/* =========================================================================
   BRANDIP PROJECT SCREEN — INTRO-1 (index.html) ONLY.
   INTRO-1's LAST project row, in the slot the seven-eleven-wave duplicate held.

   ISOLATED COPY, same contract as css/pellmell-intro-ef.css and
   css/pellmell-intro-7e.css: the portfolio's index-portfolio-archived.html keeps its own Brandip
   rules in css/styles.css and is NOT touched by this file; v2/v3 never load it;
   nothing is added to css/pellmell-intro.css (the base v2/v3 share). Portfolio
   ships do not move INTRO-1 and INTRO-1 ships do not move the portfolio. If the
   portfolio Brandip styles change, SYNC BY HAND.

   DESIGN GUIDE, NOT A SOURCE: Figma LrUdy5WZmi3n2gkRz9SEC2 node 1906:1708
   "Brandip-1093x600" (panel 1906:1710, tracks 1906:1837) and
   PORTFOLIO/Brandip/Brandip-1093x600.svg. Neither ships and neither is traced or
   placed as an image — every string, type spec and colour below is read off the
   node and rebuilt live, as the portfolio row is built.

   FULL COMPOSITION, NO DEVIATION. Both columns are here: the left panel (the two
   tags, the player, the four Influences boxes) and the video-tracks column. The
   PANEL IS A PORT of the portfolio's coded .bw-panel-left and children, not a
   rebuild — one value moves (see .bw-panel-left) and one string comes off the
   node (see .bw-inf-title). No row META panel: INTRO-1 project screens are
   visual-only, the same as the EF and 7-Eleven screens.
   ========================================================================= */

/* BOTH FACES ARE SELF-HOSTED, NOT LINKED FROM A FONT CDN — INTRO-1's stated
   convention (see the Roboto note in pellmell-intro-7e.css). The portfolio gets its
   Lexend from the Google Fonts <link> in the portfolio index-portfolio-archived.html; that link does not exist on this
   page. Both are VARIABLE, so one file each serves every weight and none is
   synthesised.

   BRICOLAGE GROTESQUE IS PRIMARY, LEXEND IS THE FALLBACK. The node moved all of this
   screen's text onto Bricolage (Light for body, ExtraBold for the logo); Lexend stays
   second in the stack, and its @font-face and subset file are kept, so a Bricolage
   failure degrades to the face this screen was built in rather than to a system
   grotesque. */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 200 800;              /* variable weight axis */
  font-stretch: 75% 100%;            /* variable wdth axis */
  font-display: swap;
  src: url('../assets/fonts/bricolage-grotesque-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Lexend';
  font-style: normal;
  font-weight: 100 900;              /* variable weight axis */
  font-display: swap;
  src: url('../assets/fonts/lexend-latin.woff2') format('woff2');
}

/* =========================================================================
   SECTION SHELL — identical treatment to .ef-project-screen / .se-project-screen.
   Sits last in normal flow with a z-index above the fixed .hero (100), so it
   scrolls UP OVER the pinned Matey screen. The shared .hero base is untouched.
   ========================================================================= */
.bw-project-screen {
  position: relative;
  z-index: 200;
  min-height: 100vh;
  background: #ffffff;        /* opaque: occludes the pinned hero scrolling under */
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
/* Fallback (reduced-motion / no-JS): #scrollTrack collapses to 0, so push this
   screen below the first viewport to preserve Matey-first ordering — the same
   offset EF and 7-Eleven use. */
html:not(.js-loading) .bw-project-screen {
  margin-top: 100vh;
}

/* =========================================================================
   FOOTPRINT — the EF / 7-Eleven painted box, on the node's own frame.

   The reference frame is 1093 x 600 (aspect 1.82167); the painted box is
   1205.48 x 660 (aspect 1.826485). They are 0.26% apart, so the height is the
   node's 600 and ONE transform does the rest:

     internal   1095.8909 x 600
     scale      660 / 600 = 1.1
     painted    1205.48 x 660 — EXACT, the same box .ef-stack and .se-screen paint
     left       (1276 - 1205.48) / 2 = 35.26, the same centring both of them use

   WIDTH ABSORPTION — 2.8909px, and it goes to the TRACKS COLUMN.
   1095.8909 - 1093 = 2.8909. The panel is a fixed-content column (a 216-wide
   player, chips that wrap to their own text) so it cannot absorb anything; the
   tracks column is the free one — its wave TILES, its ruler REPEATS and its
   filmstrip OVERFLOWS, so all three simply run 2.89px further. Column goes
   829 -> 831.8909 (+0.35%). Nothing is stretched and no authored number moves.
   ========================================================================= */
.project-row--live[data-theme="brandip"] {
  width: 1276px;
  height: 660px;
  border-radius: 0;
  overflow: visible;
  display: flex;
  align-items: stretch;
}
.project-row[data-theme="brandip"] .visual-panel {
  width: 1276px;
  height: 660px;
  background: transparent;
  position: relative;
  overflow: hidden;
}
.project-row[data-theme="brandip"] .bw-screen {
  position: absolute;
  left: 35.26px;
  bottom: 0;
  transform: scale(1.1);       /* 660 / 600 — height-fit, no clip */
  transform-origin: bottom left;
}

/* =========================================================================
   THE SCREEN — internal 1095.8909 x 600.
   ========================================================================= */
.bw-screen {
  position: relative;
  width: 1095.8909px;
  height: 600px;
  flex-shrink: 0;
  background: #221016;                 /* node 1906:1708 ground */
  /* The node authors 16 on its 1093 frame. 48 x 1.1 = 52.80 rendered used to match the
     EF hero, .se-screen and #heroCard.
     48 -> 9.0909 (user, 2026-08-24): the project containers now match the FOOTER's 10px
     corner. AUTHORED 9.0909 because this box renders at 1.1x — 9.0909 x 1.1 = 10.0000
     PAINTED. Writing 10 here would paint 11. If the scale above changes, this must too. */
  border-radius: 9.0909px;
  overflow: hidden;
  font-family: 'Bricolage Grotesque', 'Lexend', sans-serif;
  /* The node pins Bricolage's optical-size and width axes on every text node
     ("opsz" 14, "wdth" 100); set once here so nothing has to restate it. Only these
     two axes are listed, so font-weight still drives wght normally. */
  font-variation-settings: "opsz" 14, "wdth" 100;
  /* glassy inset edge shared by the framed sub-panels (the node's inset shadow pair) */
  --bw-glass-shadow:
    inset 1px 1px 2px 0 rgba(255, 255, 255, 0.3),
    inset -1px -2px 2px 0 rgba(255, 255, 255, 0.1);
  /* Shared left gutter — the Figma handle box (Icon-handle 1906:2133) is x0 w30.
     The soundwaves, the video timeline and the handle-dot centring all derive from
     this ONE value, so every track shares one left edge. */
  --bw-gutter: 30px;
  /* THE SCREEN'S ACTIVE TREATMENT — one raised fill, used by the Athletes panel's
     selected pair. WHITE at 20%, as the node paints it. An earlier build substituted
     the screen's cream at the same level, reasoning that no pure white appears
     anywhere else here; that was overruled — the guide is right on this one. */
  --bw-active-fill: rgba(255, 255, 255, 0.2);
}
.bw-defs { position: absolute; }

/* Body 1906:1709 — x16, so 16 + 232 + 16 + 831.8909 = 1095.8909 exactly. */
.bw-body {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 16px;
  padding-left: 16px;
}

/* =========================================================================
   LEFT PANEL — 1906:1710. PORTED from the portfolio's .bw-panel-left; the only
   value that moves is the width.

   THE STACK IS 886.89 TALL IN A 600 FRAME AND THAT IS AUTHORED, NOT A DEFECT.
   24 (pad) + 24 (titlerow) + 16 + 261.92 (player) + 16 + 30 (projtitle) + 16
   + 498.97 (influences) = 886.89 — measured, not projected.
   The node renders it inside a 600 frame, so the lower Influences boxes clip at the
   bottom edge — .bw-screen's overflow:hidden reproduces that exactly. Do not
   "fix" it by shrinking the stack or growing the frame. Three passes have grown it:
   the Athletes panel (646.16 -> 765.36), the project title moving out of the filters
   row (+46 = a 30-tall .bw-projtitle on the panel's 16 gap), and the athlete names
   going from .bw-name pills to the wider .bw-chip (+75.53 — a chip carries 5.592 of
   side padding against the pill's 4.66, which wraps several Athletes rows). Each step
   puts more of the stack below the fold; none of it is a regression.
   ========================================================================= */
.bw-panel-left {
  /* 232 — the node's own panel width (1906:1710), which is ALSO the portfolio's, so
     the port no longer carries a moved value. Everything below is byte-identical to
     css/styles.css unless annotated. */
  width: 232px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-top: 24px;
}

/* TITLE ROW — 1906:1711. The two tags that used to live here ("Nyjah Huston" /
   "Skateboarder") are GONE; they moved into the Athletes panel below. In their place:
   the player's MENU button, then the Brandip logo. */
.bw-titlerow {
  display: flex;
  align-items: center;
  align-self: flex-start;   /* the node's Title frame hugs (99.73); don't stretch to 232 */
  gap: 8px;
  height: 24px;
  padding-left: 3.728px;
}
/* 2061:1610 — the same glyph that used to sit in the player's transport row; the node
   moved it up here, to the LEFT of the logo. assets/brandip/icon-player-menu.svg is
   that button whole (a 22.3696 rounded rect #403E3C at 40% plus the two #F6EBE4 bars
   at 40%, short over long), so it is one <img>, not a rebuild. Rendered at the node's
   24 box: the asset's rect is 22.3696 in a 23 viewBox, so the painted rect lands
   0.66 internal px short of the node's 24 — sub-pixel at this scale, and closing it
   would mean oversizing the box and shifting the logo. */
.bw-menu { display: block; width: 24px; height: 24px; flex-shrink: 0; }
/* 2062:1685 — Bricolage Grotesque ExtraBold, the one place on this screen that is not
   Light. 800 is the top of the variable weight axis. */
.bw-logo {
  font-size: 16px;
  font-weight: 800;
  color: #f6ebe4;
  opacity: 0.8;
  white-space: nowrap;
}
/* THE TITTLE OVER THE "i" IS RED (#F63A65); the rest of the wordmark is unchanged.
   CSS cannot colour part of a glyph, so the "i" is set as U+0131 DOTLESS I and the dot
   is drawn back on. Bricolage gives "i" and "ı" the SAME advance, so nothing reflows.

   THE DOT IS THE TYPEFACE'S OWN TITTLE, NOT A SHAPE STANDING IN FOR IT. A second copy
   of the REAL "i" is laid over the dotless one in red and clipped to the band above the
   stem, so the only red ink on screen is the glyph's own tittle — its exact outline,
   whatever that outline is. This matters because Bricolage's tittle is NOT a circle:
   measured off the font it fills 80.5% of its bounding box, against 78.5% for a true
   ellipse and 100% for a rectangle, i.e. a superellipse. An ellipse (`border-radius:50%`)
   was the first build and is wrong in form even at the right size and position.

   Nothing here is a placed literal. The red copy inherits the same font, size, variation
   settings and box as the dotless glyph beside it, so it registers by construction and
   stays registered if the face's metrics change. The single number is the clip line —
   see .bw-logo-dot. */
.bw-logo-i { position: relative; }
.bw-logo-dot {
  position: absolute;
  left: 0;
  top: 0;
  color: #F63A65;
  pointer-events: none;
  /* Clip to the band above the "i" stem. MEASURED off the SHIPPED render at 8x device
     scale, not off a canvas (canvas cannot carry font-variation-settings, and the first
     pass measured there was wrong because of it): the tittle occupies y 2.750..5.875
     from the logo box top and the stem top starts at 6.250, so the line goes between
     them. 6.06 is the midpoint of that 0.375 window. */
  clip-path: inset(0 0 calc(100% - 6.06px) 0);
}

/* player — 1906:1719. Stacked flush: window 21 + hero 207.385 + controls 33.554
   = 261.939, which is the node's own height. */
.bw-player {
  position: relative;
  width: 232px;
  box-sizing: border-box;
  padding: 0 8px;
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.01);
  box-shadow: var(--bw-glass-shadow);
  /* The Figma Player is overflow-clip: the corner handle's ellipse is clipped to the
     player's rounded rect, so it reads as a corner tab, not a ball poking out. */
  overflow: hidden;
}
/* Player corner handle = background circle + dot-grid on top (Figma Ellipse 70,
   node 1906:1754), seated with its top-left at the player's (-6.07, -5.13). The
   inner shadow is a white highlight on the top and left edges — the same glass
   language as the rest of the screen. */
.bw-player-handle {
  position: absolute;
  top: -5.13px;
  left: -6.07px;
  width: 24.692px;
  height: 24.692px;
  border-radius: 50%;
  background: rgba(64, 62, 60, 0.4);
  box-shadow: inset 1px 2px 2px 0 rgba(255, 255, 255, 0.3);
}
/* Dots sit lower-right of the ellipse centre, which lands centred in the visible
   (clipped) corner tab. Ported from the portfolio's derivation. */
.bw-hdots {
  position: absolute;
  left: 12.03px;
  top: 11.42px;
  width: 9px;
  height: 8px;
  overflow: visible;
}
/* WINDOW ICONS — right-aligned on the HERO'S INK, not on its box.

   The three icon boxes were already flush: .bw-window is the player's 216 content
   width, justify-content:flex-end, and the close box's right edge measured 224 —
   exactly .bw-hero's. It still read as short by ~5px, and box alignment is why.

   All three assets are 21-unit viewBoxes drawn around cx 10.32 with r 5.59, so the
   ink runs x4.730 -> x15.915 and each file carries 5.085 of transparent padding on
   its right. Aligning the BOXES therefore parks the visible disc 5.085 inside the
   photo edge. The node has the same inset (Close 1906:1729 is a 21.0003 frame whose
   Vector sits at x5.0002) — it is a property of the drawing, so the frame cannot show
   the fix and this is ours to make.

   So the row is widened by exactly that inset and still hugs right: the box edge goes
   to 229.085 and the INK lands on 224. It spends 5.085 of the player's 8px right
   padding and cannot clip — .bw-player's border box is 232.

   ONE CORRECTION FOR THREE ICONS, DELIBERATELY. min and max render their 21-unit
   viewBox at 20.5, so their own ink inset is 4.964, not 5.085 — 0.12px apart. They
   shift with the close icon rather than each being corrected alone, because what has
   to look flush is the ROW's right edge, and 0.12px is below the threshold of
   anything. */
.bw-window {
  --bw-winicon-ink: 5.085px;   /* 21 - 15.915, measured off assets/brandip/icon-close.svg */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.864px;
  width: calc(216px + var(--bw-winicon-ink));
  height: 21px;
}
.bw-win-icon { display: block; height: 20.5px; width: 20.5px; }
.bw-win-icon:last-child { height: 21px; width: 21px; }

.bw-hero {
  position: relative;
  width: 216px;
  height: 207.385px;
  border-radius: 8px;
  overflow: hidden;
}
.bw-hero-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
}
.bw-hero-tint {
  position: absolute;
  inset: 0;
  mix-blend-mode: overlay;
  background: linear-gradient(-90deg,
    rgba(96, 66, 37, 0) 0%,
    rgba(96, 66, 37, 0.85) 52%,
    rgb(21, 30, 18) 100%);
}

/* controls — 1906:1736. TWO INDEPENDENT BLOCKS, NOT ONE ROW. This is the whole point
   of the rule below, so it is worth stating as a contract rather than as a layout:

     · the TRANSPORT is centred on the player, and stays centred however long the
       timestamp copy gets;
     · the TIMESTAMP is pinned to the player's left edge, and stays there however wide
       the transport gets.

   Neither derives from the other. They were one left-packed flex row until this ship
   (transport, then an 11.185 gap, then the timestamp, the pair hugging at 151.42),
   which made both positions a function of the other block's width — change the copy
   from "0:01 / 02:05" to something longer and the buttons walked left.

   THE MECHANISM IS position:absolute ON THE TIMESTAMP, and that is what buys the
   independence: taking it out of flow leaves .bw-controls-group with exactly one
   in-flow child to centre, so justify-content:center resolves against the full 216
   and cannot see the timestamp at all. The node reaches the same conclusion the same
   way (1906:1746 is `absolute left-0 top-0` inside 1906:1737).

   .bw-controls stretches to 216 now instead of hugging — it is a flex column child of
   .bw-player, so deleting its align-self:flex-start is the whole change; the width is
   the player's content box and is not restated here. Its 40 gap stays declared and
   inert, as it was before: one child, nothing to space. */
.bw-controls {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 40px;
  height: 33.554px;
}
/* Controls 1906:1737 — the timestamp's containing block, hence position:relative.
   Its own 11.185 gap is now inert too (the transport is its only in-flow child); it
   stays for the same reason .bw-controls' 40 does. */
.bw-controls-group {
  position: relative;
  flex: 1 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11.185px;
}
.bw-transport {
  display: flex;
  align-items: center;
  gap: 11.185px;
}
.bw-btn { display: block; }
/* THE PAUSE DISC USES ITS OWN ASSET, AND ONLY BECAUSE OF ISOLATION.
   In the node all three transport glyphs carry the same treatment — #F6EBE4 under the
   same three-inner-shadow filter (0.3 / 0.1 / 0.3) — but rewind and FF put
   `fill-opacity="0.4"` on their path and the pause does not, so the pause disc renders
   at full cream beside two at 40%. Verified on both the node's fresh exports and the
   in-tree files: structurally identical, that one attribute apart.
   The obvious fix — adding the attribute to assets/brandip/button-pause.svg — is not
   available: the portfolio index-portfolio-archived.html references that file, so editing it would move the portfolio
   row. assets/brandip/button-pause-dim.svg is that file with the one attribute added
   and NOTHING else changed (a one-line diff), and only this screen points at it. */
/* Ported sizes, and they are the ones that match the ASSETS: button-rewind.svg and
   button-ff.svg are 15-unit frames, button-pause.svg is 23, icon-player-menu.svg is
   23 — so 14.913 / 22.649 / 22.37 render those frames at their drawn size. The
   node's own 16 / 24 are its frame numbers, not these files'. */
.bw-btn--rewind, .bw-btn--ff { width: 14.913px; height: 14.913px; }
.bw-btn--play { width: 22.649px; height: 22.649px; }
/* Timestamp 1906:1746 — OUT OF FLOW, pinned to the player's left content edge. left:0
   is .bw-controls-group's left, which is .bw-player's content box, which is the same
   8px the hero and the window row start from — so the timestamp, the photo and
   "Dream Crazy" in .bw-projtitle below all share one left edge, by derivation rather
   than by three agreeing numbers. Centred vertically in the 33.554 row instead of
   sitting on a baseline, so the copy can grow a line without moving the transport. */
.bw-timestamp {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 8px;
  font-weight: 300;
  color: rgba(246, 235, 228, 0.4);
  opacity: 0.8;
  white-space: nowrap;
}

/* PROJECT TITLE — the 1908:3636 string, relocated out of the filters row (see
   .bw-filters) and set directly under the player. A SIBLING of .bw-influences, not a
   sixth box inside it, so it takes the panel's own 16px gap above and below rather
   than the 4px box gap — that separation is what keeps it reading as the player's
   caption instead of another listing.

   NO PILL RULES OF ITS OWN. The three children reuse the panel's existing vocabulary
   verbatim: .bw-inf-title for "Dream Crazy" (the Athletes title pill, 2062:1681) and
   .bw-chip for "Nike" / "2018" (the "American football" chip). Its SURFACE is likewise
   shared — see the container rule below, which it takes with the five boxes.

   BOTH SPACING VALUES ARE THE NODE'S, READ OFF 2061:1616 — p-8 all round on the
   container, and a 4px gap on its pill row (2062:1681). The 4 is NOT .bw-chip-row's
   3.728 even though two of the three children are chips: the node spaces this row the
   way it spaces .bw-inf-titles, the other row whose first child is a title pill. It is
   a 0.272px difference and it is still the node's; do not "unify" it with 3.728. */
.bw-projtitle {
  box-sizing: border-box;
  width: 100%;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  padding: 8px;
}

/* =========================================================================
   THE PANEL'S CONTAINER SURFACE — the TRACK container treatment, on all six
   left-panel containers, so both columns of the screen are built out of ONE object.

   EVERY VALUE HERE IS READ OFF NODE 2061:1616, the title container, which is the
   node's own worked example of this treatment on a panel box. It is the text track's
   surface exactly (.bw-track--text .bw-text-row: #221016 under --bw-glass-shadow),
   which is why "matching the track containers" is a description and not an analogy.

   WAS: three different edges down one column — a 1px #403e3c border on the two solid
   boxes, a 0.5px #cfc8c2 hairline on the ghosts, a 0.5px #ada6a1 on ghost2 — and
   nothing at all on the title. NOW: no border on any of them; the ground colour, and
   the glass inset pair as the only edge.

   RADIUS IS 8, NOT THE TRACKS' 16. Read, not derived, and not carried over from the
   tracks: 2061:1616 authors rounded-8, and the boxes' own 11.185 is superseded. An
   earlier pass of this change shipped 16 all round, reasoning from the tracks' corner
   and from screens 3/4; the node overrules it.

   THE FILL IS THE SCREEN'S OWN GROUND, so the boxes read as cut-outs lit at the edge
   rather than as washes floating on it. Against #221016 this is all but identical to
   the tracks' rgba(255,255,255,0.01) — the node's literal is shipped because it is
   the node's, not because the two composite differently.

   SCREENS 2, 3 AND 4 DO NOT MOVE. Each already restates border, padding,
   border-radius, background AND box-shadow for .bw-inf-box + both ghosts at
   two-class specificity, so none of this reaches them; and .bw-projtitle exists only
   on this screen. Checked in all three sheets, not assumed. */
.bw-projtitle,
.bw-inf-box {
  background: #221016;
  box-shadow: var(--bw-glass-shadow);
}
/* THE CORNER IS 8 ON THE TITLE AND 16 ON THE FIVE LISTINGS. v=20 shipped a flat 8
   across all six, generalised from the one box (2061:1616) read that pass. Wrong:
   1906:1811 and 1906:1824 are both rounded-16, and the split matches what screens 3
   and 4 already do (--r8 on box 1, 16 on the rest).

   READ THIS BEFORE "FINISHING THE JOB" AGAINST THE FRAME. As of this ship the node is
   MID-EDIT and its six boxes are in three states: 1 is the new surface at r8, 5 and 6
   are the new surface at r16, and 3 (1906:1770) is still the OLD 1px #403e3c border at
   r11.185 with no fill. Box 4 was not read; box 2 is new. The six are unified here by
   instruction — "apply the track container style to the left panel content containers",
   all six named — so the node's remaining unconverted boxes are a stale frame, not a
   spec, and must not be copied back. */
.bw-projtitle { border-radius: 8px; }

/* ATTRIBUTION DISCLAIMER — node 2456:1707, the second row of the project-title card.
   Copy is a legal/authorship note, not product vocabulary: the Nike film is a PUBLIC
   EXAMPLE used to demonstrate Brandip, and this line says so on the screen itself. It
   pairs with .bw-screen's aria-label, which was changed the same day to say "a brand
   video" rather than naming the ad — the label must not imply the work is the author's.

   INK IS .bw-chip's, NOT A NEW TREATMENT. The node gives rgba(246,235,228,0.6) at
   opacity .8 in Bricolage Light — which is exactly what .bw-chip above already carries,
   and what the styleguide records as "resting chip ink, Light .8". Restated here rather
   than shared because the two differ on everything else (size, fill, wrapping).

   WHAT DIFFERS FROM A CHIP, all from the node:
     7px not 8px       — the note sits a step under the pills it explains
     no fill, no pill  — the node's 4px radius is on a transparent box, so nothing paints
     wraps            — a chip is `white-space: nowrap`; this is a sentence
     5.592px inset     — the SAME horizontal padding a chip uses, so the sentence's first
                         character aligns with the chip text above it rather than with the
                         chip's outer pill edge. That alignment is the reason for the value.
   `width: 100%` is the row break — see the markup note. This screen paints at scale 1.1,
   so 7px authored renders 7.7px, the same relationship every value on it carries. */
.bw-projtitle-note {
  width: 100%;
  padding: 0 5.592px;
  font-size: 7px;
  font-weight: 300;
  line-height: normal;
  color: rgba(246, 235, 228, 0.6);
  opacity: 0.8;
}
.bw-inf-box   { border-radius: 16px; }

/* influences / sponsors — 1906:1769. Five boxes now: the Athletes panel is the new
   first child (2061:1616), which is why the stack grew 304.22 -> 423.42. */
.bw-influences {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 232px;
}
.bw-inf-box {
  box-sizing: border-box;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 7.457px;
  padding: 8px 5.592px 8px 8px;
}
/* The two ghosts now differ from the base box, and from each other, by PADDING ALONE —
   their cream and grey hairlines went out with the borders, and those hairlines were
   the only thing that distinguished them. Both names are KEPT rather than collapsed:
   screens 2 and 4 still key their own overrides off --ghost and --ghost2 separately.
   Side padding 11.185 -> 8 to follow 1906:1811 / 1906:1824, the two boxes the node has
   actually converted (both `px-[8px]` now). The base box keeps 8/5.592 because 1906:1770
   still carries it and has not been converted — see the corner note above. */
.bw-inf-box--ghost,
.bw-inf-box--ghost2 { padding: 7.457px 8px; }
/* THE GLASS PILL, used by every box title AND by the athlete NAME pills — the node
   gives them identical treatment (rounded 8, the 0.01 white fill, the triple inset
   shadow, 4.66 padding), so it is one rule read twice rather than two kept in
   agreement. Only the box titles take the align-self.

   .bw-name IS NO LONGER USED ON THE DARK SCREEN. Its athlete names now carry .bw-chip
   so that each name+sport pair is one treatment; the selector stays because screens 2,
   3 and 4 still use it, and it must not move. See the styleguide.

   The first box's title string is the node's "Influences" (1906:1774), not the
   portfolio's "Cross Industry & Broader Influences" — strings come off the node. */
.bw-inf-title,
.bw-name {
  display: inline-flex;
  align-items: center;
  padding: 2.5px 4.66px;
  border-radius: 8px;
  font-size: 8px;
  font-weight: 300;
  color: #f6ebe4;
  opacity: 0.8;
  white-space: nowrap;
}
/* THE GLASS EDGE IS NOW .bw-name's ALONE. The primary chips are TEXT ONLY on this
   screen — no container. The node agrees and is consistent about it: 2168:2308
   (Dream Crazy), 1906:1773 (Influences), 1906:1816 (Personal Brand Ventures) and
   1906:1829 (Cultural) have all dropped the inset triple, in boxes the designer has
   otherwise left in four different states. Four out of four is a decision, not drift.

   .bw-name KEEPS IT because .bw-name is no longer used on this screen at all — the
   athlete names are .bw-chip here (see the Athletes box). It survives only for
   screens 2, 3 and 4, all of which override it anyway; leaving the declaration on it
   rather than deleting it keeps those three provably unmoved by this edit.

   The padding and radius STAY on .bw-inf-title even though nothing paints them. They
   are the node's (p-4.66, r8, plus an rgba(255,255,255,0.01) fill that is invisible
   over #221016 and is not reproduced), and they are what holds every title's text on
   the x the surrounding boxes are measured from. Strip them and all six titles shift
   left 4.66. */
.bw-name {
  box-shadow:
    inset 0 0 10px 0 rgba(255, 255, 255, 0.3),
    inset -1px -2px 2px 0 rgba(255, 255, 255, 0.1),
    inset 1px 1px 2px 0 rgba(255, 255, 255, 0.3);
}
.bw-inf-title { align-self: flex-start; }
/* The Athletes box carries TWO title pills, "Athletes" and "Brands" (2062:1681),
   identically treated on a 4px gap. */
.bw-inf-titles { display: flex; align-items: center; gap: 4px; align-self: flex-start; }
.bw-inf-titles .bw-inf-title { align-self: auto; }
.bw-inf-rows { display: flex; flex-direction: column; gap: 7.457px; width: 100%; }
.bw-chip-row { display: flex; flex-wrap: wrap; gap: 3.728px; }
.bw-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2.796px 5.592px;
  border-radius: 11.185px;
  background: rgba(64, 62, 60, 0.4);
  font-size: 8px;
  font-weight: 300;
  line-height: 1;
  color: rgba(246, 235, 228, 0.6);
  opacity: 0.8;
  white-space: nowrap;
}
.bw-inf-rows > .bw-chip { align-self: flex-start; }
/* SELECTED / ACTIVE — THE MARK IS ON THE NAME. The wrapper still holds both members,
   because the pair is what gets selected and the sport has to be reachable from the
   name to be stepped back out; but as of 2026-08-11 THE SPORT CARRIES NO PART OF THE
   MARK. It is fill-for-fill and ink-for-ink a resting chip, and only "Nyjah Huston"
   lifts. See the rule below for the values and where they were read.

   THIS REPLACES THE 2026-08-06 READING, in which both members took --bw-active-fill and
   both went to full #F6EBE4 so the pair read as one lifted object. That was argued from
   the node and it is no longer what the node says: the re-read shows the sport ordinary
   throughout, which is also what screens 2, 3 and 4 do. The wrapper is NOT vestigial —
   `.bw-pair--active .bw-chip` still fills the name through it, and the sport rule below
   is written as a subtraction from that fill, so deleting either leaves the row wrong.

   THE WEIGHT STEP IS DARK-SCREEN-DEAD. It lives on `.bw-pair--active .bw-name`, and the
   dark screen's names are .bw-chip now — so on that screen active is fill + ink only.
   The rule still fires on screens 2, 3 and 4, whose names are still .bw-name; do not
   move it.

   This is the screen's SECOND user of one active vocabulary; .bw-track-label--active
   (Voiceover) is the first, and the move is deliberately the same — the opacity
   knock-down removed, colour to full cream. What diverged is the SCOPE of the mark, not
   its vocabulary: one element lifts, not two.

   THE CREAM REPLACES THE NODE'S #FF3567, AND THAT IS A CLOSED DECISION (user, 2026-08-11).
   Recorded with its reasons because a node re-read will surface the difference every time
   and the 2026-08-06 lock rightly asks what a deviation BUYS. Two checkable things:

     1. THE ACCENT IS ALREADY SPENT TWICE HERE. #F63A65 carries the wordmark's tittle and
        the video playhead on this screen. Putting the same pink on a chip in the Athletes
        panel gives it a third, unrelated job — "selected athlete" alongside "brand mark"
        and "playhead". Grep the accent's users before arguing this back.
     2. IT KEEPS THE SCREEN AT ONE ACTIVE VOCABULARY. Cream-to-full is what
        .bw-track-label--active already does, so the Athletes selection is a second user of
        one move rather than a per-panel treatment — which is what the 2026-08-06 lock asks
        for in as many words.

   Screens 2, 3 and 4 DO take the accent on their selected name, and that is not an
   inconsistency to fix: their ground is pale, nothing else on them is spending #FF3567,
   and cream would not read at all. The treatments differ because the grounds do. */
/* Rows 4 and 5 of the Athletes panel pack TWO name+sport pairs side by side
   (2168:2196 / 2168:2215, gap 7 — measured x0 -> x108.098 across a 101.098 child). */
.bw-chip-pair { display: flex; align-items: flex-start; gap: 7px; }

.bw-pair {
  display: inline-flex;
  align-items: flex-start;
  gap: 3.728px;              /* the row's own gap, so the wrapper is spacing-neutral */
}
.bw-pair--active .bw-name {
  background: var(--bw-active-fill);
  color: #f6ebe4;
  font-weight: 600;          /* Bricolage Grotesque SemiBold */
}
.bw-pair--active .bw-chip {
  background: var(--bw-active-fill);
  color: #f6ebe4;
}
/* THE SPORT IS A RESTING CHIP — ITS OWN VALUES, NOT REFERENCES TO ONE. Both read off the
   node 2026-08-11, and both are the resting "American football" chip's (2168:2180 /
   2168:2181) to the digit:

     "Skateboarding" fill 2168:2194  rgba(64,62,60,0.4)     ← resting chip fill
     "Skateboarding" ink  2168:2195  rgba(246,235,228,0.6)  ← resting chip ink, Light .8

   THEY ARE LITERALS ON PURPOSE. Not an inherit, not a removed override, not a var. Per
   the 2026-08-07 lock a selected state landing on its own default is a COINCIDENCE until
   the node says it is a rule, and this one has already moved twice. RE-READ THE NODE
   before touching either value; do not "tidy" this into tracking .bw-chip, and do not
   assume moving .bw-chip's fill or colour should drag these with it.

   IT IS A SUBTRACTION, NOT A DEFAULT. `.bw-pair--active .bw-chip` above still applies
   --bw-active-fill and cream to BOTH members; this rule takes the second one back out.
   That order is deliberate — it keeps the name's lift and the sport's opt-out as two
   readable decisions instead of one selector that has to name the right chip.

   The 2026-08-06 ids for these rows (2062:1696 / 2062:1716) are DEAD, and 2061:1616 has
   been RECYCLED onto the project-title row. The Athletes box is 2168:2167 now. Walk down
   from there, never from an id quoted in an older comment or a commit message.

   REACHES THE DARK SCREEN ONLY, by construction rather than by scope. This is the one
   screen where BOTH pair members are .bw-chip; screens 2, 3 and 4 pair a .bw-name with a
   .bw-chip, so chip-adjacent-chip has nothing to match inside their .bw-pair--active.
   Verified against all four markup blocks — no screen-modifier qualifier needed, and the
   light variant's own rules are untouched by this file's edit.

   THE NAME DEPARTS FROM THE NODE AND THAT IS SETTLED — DO NOT RE-RAISE IT. The node paints
   the name #FF3567 SemiBold on the ordinary chip fill; this screen paints raised fill +
   cream #F6EBE4, and the user confirmed on 2026-08-11 that the cream is intended and
   REPLACES the node's accent. A re-read will keep surfacing the difference; it is a closed
   decision, not a drift. See .bw-pair--active below for what it buys. */
.bw-pair--active .bw-chip + .bw-chip {
  background: rgba(64, 62, 60, 0.4);
  color: rgba(246, 235, 228, 0.6);
}

/* =========================================================================
   VIDEO TRACKS (right) — 1906:1837, widened 829 -> 831.8909 by the width
   absorption above. Children sit at y0 / y64 / y207, i.e. a 16px column gap.
   ========================================================================= */
.bw-tracks {
  width: 831.8909px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* filters toolbar — 1906:1838. A 48-tall box with pt-24, so the 24-tall content row
   occupies y24..48 and its child centres on y36. The node's second child, the project
   title (1908:3636), has moved into the left panel — see .bw-projtitle. The 24px gap
   below is the node's and is kept though it now spaces nothing: it is the row's
   authored value, and the row is otherwise the node's verbatim. */
.bw-filters {
  box-sizing: border-box;
  height: 48px;
  display: flex;
  align-items: center;
  gap: 24px;
  padding-top: 24px;
}
.bw-filter-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 24px;
  padding: 2.796px 5.592px 2.796px 8px;
  border-radius: 11.185px;
  background: rgba(64, 62, 60, 0.4);
}
.bw-filter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22.37px;
  height: 22.37px;
  box-sizing: border-box;
}
/* The source icon SVGs are exported at the frame bounds with the glyph already
   centred inside its own padding, so they fill the 22.37 frame with no extra
   padding — node 1906:1840 frame 22.37 / glyph 13.98. Adding CSS padding here is
   the v=244 double-count the portfolio build already unwound. */
.bw-filter img { display: block; width: 100%; height: 100%; }

/* =========================================================================
   track-selected: filmstrip + timeline ruler — 1906:1851
   ========================================================================= */
.bw-track-selected {
  position: relative;
  width: 831.8909px;
  height: 127px;
  box-sizing: border-box;
  border-radius: 16px 0 0 16px;
  background: rgba(255, 255, 255, 0.01);
  box-shadow: var(--bw-glass-shadow);
  overflow: hidden;
  /* Strip metrics. The thumbnails AND the playhead both derive from these two, so the
     red bar cannot drift off the clips it marks.
     Figma: Frame 48098170 y10.96 -> Thumbnails mt24.36 = 35.32; strip h76.
     THAT 35.32 IS NOW SCREENS 2/3/4's VALUE, NOT THIS SCREEN'S — the node re-authored
     the video track and the dark screen follows it down to 42.611. See the
     #bwProjectScreen override below; the declaration stays here because the other three
     read it from this block and none of them overrides .bw-thumbs. */
  --bw-thumb-top: 35.32px;
  /* 2:1 with every other thumbnail. The width is the authoritative half and the height is
     derived, so --bw-strip-h stays available to the playhead's own calc below without
     being a second place the ratio could drift. 139 / 2 = 69.5, where this was 76. */
  --bw-thumb-w: 139px;
  --bw-strip-h: calc(var(--bw-thumb-w) / 2);
  /* Progress-bar/verticle 1906:1912. THIS SCREEN NO LONGER READS IT — see .bw-playhead,
     which is the strip box plus a rise now. It is still live for screens 2 and 4, which
     state it on their own .bw-playhead rules, so it is declared here rather than
     duplicated twice. Do not "clean up" as unused: `grep -l bw-playhead-h css/`. */
  --bw-playhead-h: 84.581px;
  /* HOW FAR THE PLAYHEAD STANDS ABOVE THE CLIPS. Its top and height both derive from
     this, so the two are one edge moving and the bottom stays pinned to the clips.
     Declared here, VALUED on the dark screen's override below — screens 2, 3 and 4 state
     their own top and height and never read it, so it is inherited-but-unread on theirs. */
  --bw-playhead-rise: 0px;
}
/* THE DARK SCREEN'S VIDEO STRIP, RE-READ 2026-08-11. Two passes of raising the bar inside
   the old layout were both judged too short on screen, and the reason was not the bar: the
   port's strip sits 7.29 HIGHER IN THE CARD than the node's does, so there was never room
   above it to stand in. The node did not solve this by moving the ruler up — its ruler is
   within ~1.5 of where this build already puts it — it solved it by putting the CLIPS
   lower. So does this.

   Node chain, all live ids, card-relative (Track-video 1906:1851 is the card, 127 tall;
   Handle+clips 1906:1852 sits at y8.38861 inside it and Video 1906:1867 at y0 of that):

     clips     2168:2449  y34.22278 +8.38861 = 42.611 .. 118.611  (h76, unchanged)
     playhead  2168:2447  y29.70399 +8.38861 = 38.093 .. 118.611  (h80.5188)
     => rise    42.611 - 38.093 = 4.5188        => bottom inset 127 - 118.611 = 8.389,
                                                   which is 1906:1852's own top inset.

   THE PLAYHEAD IS A CHILD OF THE CLIPS FRAME IN THE NODE NOW (2168:2447 inside Clips
   1906:1870, both 80.5188 tall, with the thumbnails inset 4.5188 from its top). That is
   the whole mechanism: the bar is the full clips frame and the pictures are inset inside
   it. Read as a guide here rather than restructured — same result, one fewer box.

   VERIFIED BY EYE against a render of 1906:1851 beside a render of this screen, per the
   brief, not from these numbers alone.

   SCOPED BY ID, and that is deliberate. --bw-thumb-top is declared on .bw-track-selected
   above and screens 2, 3 and 4 read it — none of them overrides .bw-thumbs, so moving the
   base declaration would drag THEIR thumbnails down while their playheads, which do state
   their own top, stayed put. There is no modifier class on the dark screen to qualify
   with; the id is the only handle that reaches this screen and nothing else. */
#bwProjectScreen .bw-track-selected {
  --bw-thumb-top: 42.611px;
  --bw-playhead-rise: 4.5188px;
}
/* The timeline starts at the SHARED gutter, flush-left with the soundwaves —
   Figma Video 1906:1867 is at x30. Width is the same 798.4729 box the waves get. */
.bw-ruler {
  position: absolute;
  top: 10.96px;
  left: var(--bw-gutter);
  width: calc(100% - var(--bw-gutter));
  height: 22px;
}
/* 1906:3592 — labels and 77.389 dot runs alternating on a 23px gap, out to (20s).
   The run is ~823.5 wide against the 798.47 box, so the trailing dot run clips at
   the panel edge — which is what the node does with its own 795.58 box. */
.bw-ruler-row {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: 23px;
}
/* The label boxes carry the node's OWN widths (set inline: 15 / 17.594 / 17.594 /
   19 / 19 / 19, frames 1906:1908-1911 + 3593 + 3599) rather than sizing to the
   browser's Lexend metrics. The run's rhythm is then the node's and cannot drift:
   each box's measured glyph differs from Figma's by a fraction of a px, and with
   auto width those fractions accumulate across six labels and walk every dot run
   off its interval. Overflow is symmetric (text-align:center), so the glyphs still
   read centred in their slot. */
.bw-time {
  flex-shrink: 0;
  font-size: 8px;
  font-weight: 400;
  color: rgba(246, 235, 228, 0.89);
  opacity: 0.8;
  white-space: nowrap;
  text-align: center;
}
/* THE NODE'S RUN IS FOUR DOTS, NOT A FINE TILE — asset dots-1 (1906:3573) is
   77.3886 x 2.09715 holding four circles of r=1.04857 at cx 1.04857 / 26.1457 /
   51.2429 / 76.34, fill #F6EBE4 at full opacity. So: pitch 25.09713, diameter
   2.09715, and the ink spans the box edge to edge.

   THIS REPLACES THE PORTFOLIO'S TILE, which is what shipped at v=2 and was wrong in
   four ways at once because all four are properties of that one tile:
     radius        0.5    -> 1.04857   (the dots rendered at 48% of the node's size)
     pitch         4px    -> 25.09713  (6.27x too dense)
     opacity       0.45   -> 1.0       (fill is #F6EBE4 flat)
     phase/extent  inset  -> flush     (77.389 / 4 = 19.35 tiles, so the run painted
                                        from x2 and died ~3px short of its own right
                                        edge — which is why it read as sitting LEFT
                                        inside each interval)
   Those numbers were authored for the portfolio's ruler, where the run is an
   absolutely-positioned box with `left:8; right:4` insets tuned to that ruler's
   length. The insets were dropped in the port but the tile was kept, so the tile's
   own phase took over the alignment.

   Four tiles of 25.09713 land dot centres at 1.0486 / 26.1457 / 51.2428 / 76.3400
   against the node's 1.04857 / 26.1457 / 51.2429 / 76.34 — the fourth tile is
   clipped by the box but its dot is not, so all four render whole. */
.bw-ruler-dots {
  flex-shrink: 0;
  width: 77.3886px;
  height: 2.09715px;
  background-image: radial-gradient(circle at 1.04857px 1.04857px,
                                    #f6ebe4 1.04857px, transparent 1.14857px);
  background-size: 25.09713px 2.09715px;
  background-repeat: repeat-x;
}
.bw-ruler-line {
  position: absolute;
  top: 17.54px;
  left: 0.98px;
  width: calc(100% - 0.98px);
  height: 0.974px;
  background: #f6ebe4;
}
/* The node's four ticks (1906:1883-1886), positions inline on the elements. */
.bw-marker {
  position: absolute;
  top: 16.15px;
  width: 0.428px;
  height: 3.73px;
  background: #f6ebe4;
}
/* SIX clips (1906:1869) at the node's authored widths. The strip is 851.12 wide
   against the 798.47 panel, so the sixth clip is cut off at the right edge — the
   node clips its own the same way, and it is why there is no bare ground to fill.
   (The widened-clip variant this file carried at v=1 existed only because the
   panel was absent and the column was 1041.53; with the panel back the authored
   widths overflow again and the variant is retired.) */
.bw-thumbs {
  position: absolute;
  top: var(--bw-thumb-top);
  left: var(--bw-gutter);
  display: flex;
  gap: 3.262px;
}
.bw-thumb {
  width: var(--bw-thumb-w);
  aspect-ratio: 2 / 1;
  flex-shrink: 0;
  overflow: hidden;
}
.bw-thumb:first-child { width: 139.81px; }
.bw-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ── PART III — WHAT THE CLOSING PANEL REVEALS (2187:1766) ─────────────────────
   The first four clips of the timeline are the four stills that were selected in the
   panel, washed pink and carrying NO checkmark — the marks belong to the editor, not to
   the finished edit. Clips 5 and 6 are untouched.

   Each is stacked over the original rather than swapping a src, so the change can be
   crossed rather than popped, and so the original is still there if the sequence is ever
   run again. --swapped is a modifier because the base .bw-thumb is shared with screens
   2, 3 and 4 and must not gain a positioning context. */
.bw-thumb--swapped { position: relative; }
.bw-thumb .bw-thumb-after { position: absolute; inset: 0; z-index: 1; opacity: 0; }
.bw-thumb .bw-thumb-tint {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: rgba(255, 53, 103, 0.3);
  opacity: 0;
}
.bw-hero-after {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
  opacity: 0;
}
/* PLAYHEAD — BOTTOM ON THE CLIPS, TOP STANDING PROUD OF THEM. It grows UPWARD ONLY:
   bottom stays pinned to the strip's, and --bw-playhead-rise is spent entirely on the top.
   That is why top and height both derive from the one token — they are two readings of a
   single edge moving, and stating either as its own literal lets the bar slide off the
   clips it marks. On the dark screen: clips 42.611..118.611, bar 38.093..118.611.

   THE CEILING IS THE RULER'S INK, NOT ITS BOX. `.bw-ruler` is a bare positioning box,
   y10.96..32.96, that paints nothing, so its lower edge is not a constraint on anything.
   What is actually overhead, in the 1.864px-wide column the bar occupies at x30..31.864:

     the ruler LINE      full width, bottom y29.47   <- the ink the eye reads
     the FIRST MARKER    x30.96..31.39, bottom y30.84 <- a 0.428-wide hairline, but it IS
                                                        over the bar, so it is the ceiling

   The other three markers (left 141.54 / 284.75 / 427.53) are nowhere near this column.

     rise 4.5188  ->  top 38.093   gap to the marker 7.25   gap to the line 8.62

   THE GAP GREW; IT WAS NOT SPENT. Two earlier passes tried to buy overhang out of the 4.48
   of headroom the OLD strip position left, and both were judged too timid on screen — at
   rise 3 the tip was 1.48 off the marker with nowhere further to go. The room was never
   above the bar to begin with: the port had the strip 7.29 higher in the card than the
   node does. Moving the clips down to the node's 42.611 bought that outright, so the bar
   is now both taller AND further from the ruler than at any earlier value. The old 4.48
   hard stop is void; there is now 7.25 of slack over the tip.

   FOR THE RECORD, the superseded reading: 1906:1912 was 84.581 CENTRED on the 76 strip,
   4.29 of overhang each end, top at y31.03 — 0.19 clear of the marker, i.e. no gap at all,
   and bottom-aligning it put the top 6.2 inside the ruler. That frame is not what the node
   paints any more; see 2168:2447 on the strip override above. Judge any new value on
   screen against a render of 1906:1851, not on arithmetic, and re-measure if the ruler
   ever moves.

   THIS RULE IS THE DARK SCREEN'S ONLY. --bw-playhead-h stays declared on .bw-track-selected
   because screens 2 and 4 were INHERITING this height while overriding only `top` —
   dropping it here silently shortened both of their bars by 8.58 before it was caught.
   They now state `height: var(--bw-playhead-h)` themselves, as screen 3 already did, so
   all three are immune to the top/height change here. Verified on the render, not assumed. */
.bw-playhead {
  position: absolute;
  top: calc(var(--bw-thumb-top) - var(--bw-playhead-rise));
  left: var(--bw-gutter);
  width: 1.864px;
  height: calc(var(--bw-strip-h) + var(--bw-playhead-rise));
  border-radius: 8px;
  background: #f63a65;
}

/* =========================================================================
   track-secondary — 1906:1913. Three waveform tracks + the text track on an 8px
   column gap (node rows at y 0 / 106 / 212 / 318 against 98-tall tracks).
   ========================================================================= */
.bw-track-secondary {
  width: 831.8909px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.bw-track { position: relative; width: 831.8909px; }
/* 4 + 10 + 4 = the node's 18-tall Label. Cream at 60%, Lexend Light — NOT the
   portfolio build's #403e3c. */
.bw-track-label {
  display: block;
  padding: 4px 0 4px 24px;
  font-size: 8px;
  font-weight: 300;
  line-height: normal;
  color: rgba(246, 235, 228, 0.6);
  opacity: 0.8;
}
/* VOICEOVER — the active track. Node 1906:1917 is `#f6ebe4` at Lexend REGULAR, with
   no opacity knocked off it, against the other three at Light 300 / 60% / .8. So the
   active state is carried by all three properties, not just the colour. Its strip
   handle takes the same #F6EBE4 (symbol #bw-handle-active in the markup). Neither is
   pink any more — that was this node's earlier state. */
.bw-track-label--active {
  font-weight: 400;
  color: #f6ebe4;
  opacity: 1;
}
.bw-wave-row {
  /* Flush on BOTH sides, so the row's coordinate space == the track column and the
     gutter (x0->30) lives wholly inside the frame. Figma Soundwave-* 1906:1918 is
     x0 w825.58; the wave itself is its 1906:1934 child at x30, y0, h76. */
  position: relative;
  height: 80px;
  margin: 0;
  border-radius: 16px 0 0 16px;
  box-shadow: var(--bw-glass-shadow);
}
.bw-handle {
  /* Dots centred in the left gutter: the 9px handle in the x0->30 gutter gives
     left 10.5 (dots x10.5-19.5, centre x15), matching Figma Handle-dots 1906:2134
     (x11 w8 -> centre x15). Vertical: top 50% of the 80px row -> y40, where the
     node's 24-tall handle box also centres. */
  position: absolute;
  left: calc((var(--bw-gutter) - 9px) / 2);
  top: 50%;
  transform: translateY(-50%);
  width: 9px;
  height: 8px;
  overflow: visible;
}
/* The live canvas each track renders on — the box is Figma Soundwave 1906:1934
   (x30, y2 within the 80 frame, h76), 798.4729 wide after the absorption.
   <canvas> is a REPLACED element, so flush-right is a calc width, NOT left+right:0
   (auto resolves to the intrinsic canvas size and leaves it short — the gotcha
   locked at portfolio v=269). Driven by js/pellmell-intro-brandip-wave.js, which
   TILES the wave rather than stretching it so the bar pitch stays byte-identical
   to the portfolio's. */
.bw-wave-gl {
  position: absolute;
  left: var(--bw-gutter);
  top: 2px;
  width: calc(100% - var(--bw-gutter));
  height: 76px;
  display: block;
  pointer-events: none;
}

/* text track — 1906:2554 */
.bw-track--text .bw-text-row {
  position: relative;
  height: 36px;
  margin: 0;
  padding-right: 8px;
  box-sizing: border-box;
  border-radius: 16px 0 0 16px;
  background: #221016;
  box-shadow: var(--bw-glass-shadow);
  overflow: hidden;
}
/* NO HANDLE OVERRIDE ON THE TEXT ROW ANY MORE. The node moved its Icon-handle
   (now 2053:1601, x0 w30 with Handle-dots 2053:1602 at x11 w8 -> centre x15) onto
   exactly the centring every soundwave row uses, so the base .bw-handle rule above
   covers all four rows and the row-specific `left: 8px` this file used to carry is
   deleted rather than restated. All four handles and all four content columns now
   derive from --bw-gutter alone. */
/* 2035:1616 — the short dot run immediately right of that handle box, which is
   8 + 8 + 8 = 24 wide. THREE dots, rx 1.04857, cx 1.05285 / 7.15856 / 13.2643,
   #F6EBE4 at fill-opacity 0.6.

   THIS CARRIED THE SAME PORTFOLIO TILE THE RULER RUN DID, and failed the same way:
   14.3171 / 4 = 3.58 tiles, so it painted three half-size dots plus a clipped
   sliver, inset from the left edge. Caught by auditing every repeating tile in this
   sheet after the ruler fix — see the RULES entry, "a repeating tile must divide
   its box". Pitch 6.10571 puts three whole dots in 14.3171 with the third landing
   exactly on the right edge. */
.bw-text-dots {
  flex-shrink: 0;
  width: 14.3171px;
  height: 2.09715px;
  background-image: radial-gradient(circle at 1.05285px 1.04857px,
                                    rgba(246, 235, 228, 0.6) 1.04857px, transparent 1.14857px);
  background-size: 6.10571px 2.09715px;
  background-repeat: repeat-x;
}

/* =========================================================================
   TEXT STRIP CONTENT — node 2053:1616 "Content", the container the dot run and
   the three caption pairs all live in. It is ONE horizontal auto-layout, not
   three absolute anchors:

     x 30 · w 598.1454 (hug) · h 28.43 · padding-left 4 · items centred

   THE LEFT EDGE IS THE SHARED GUTTER, AND THAT IS THE POINT. `left:
   var(--bw-gutter)` puts this container on x30 — the same token .bw-wave-gl uses,
   so the Text strip starts exactly where the Music soundwave above it does. The
   run previously sat at a literal `left: 24px`, chained off the width of the text
   row's own handle box (8 padding + 8 dots + 8 padding); the handle box is the one
   thing on this row that is NOT gutter-derived, so anchoring to it is what made
   this row the only one that did not share the edge. The dot run's own 4px indent
   inside the container is the node's `pl-[4px]`, not an anchor.

   THE GAPS ARE NOT UNIFORM — 89 / 27 / 27 / 27, left to right. The node authors
   them as four NESTED auto-layout groups (2054:1618 gap 89 · 2054:1636 gap 27 ·
   2054:1637 gap 27 · 2054:1619 gap 27), each wrapping the previous one plus the
   next pair. Flattened they are equivalent to one row with a per-child left
   margin, which is what this builds — four spacer divs would carry no information
   the margins do not. Each margin IS the node's gap at that junction; they are set
   inline for the same reason the pair widths are.

   THE FIRST GAP IS THE ODD ONE AND IT IS LOAD-BEARING. 89 against three 27s is
   what puts caption 1 under 0:05 rather than hard against the dot run; the run of
   27s then spaces 0:10, 0:14 and 0:16 at their own intervals. These are TIME
   spacings, not even spacings — see the caption-to-ruler measurements in
   Docs/STYLEGUIDE.md before "tidying" them into a single value.

   WIDTH HUGS, as the node's does, so the caption positions fall out of the layout:
   dots 4, pair 1 at 107.317, pair 2 at 274.145, pair 3 at 466.145, pair 4 at
   544.145, total 598.145. Vertically the container is centred on the row, which
   holds the dot run exactly where it already sat and puts the pairs on the same
   centre line.
   ========================================================================= */
.bw-text-content {
  position: absolute;
  left: var(--bw-gutter);
  top: 50%;
  transform: translateY(-50%);
  height: 28.43px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding-left: 4px;
}
/* Each pair is a two-line column. THERE IS NO GAP BETWEEN THE CAPTION AND ITS
   TIMESTAMP — the node stacks them flush and the air between them is the fixed
   LINE BOXES (caption 15.845, timestamp 12.583), not a gap property. Building it
   as `line-height: normal` gave ~10 and ~8.2, which is why the pairs read ~10px
   short and tight. */
.bw-cap-group {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* 2054:1631 "Good." is items-start, unlike the other three. */
.bw-cap-group--start { align-items: flex-start; }
/* Pairs 2, 3 and 4 carry a fixed 28.43 frame with their lines top-aligned; only
   pair 1 hugs (28.428). */
.bw-cap-group--fixed { height: 28.43px; justify-content: flex-start; }
.bw-cap {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 15.845px;
  font-size: 8px;
  font-weight: 300;
  line-height: normal;
  color: #f6ebe4;
}
/* BOTH LINES ARE 8px. The node sets text-[8px] on the pair and the timestamp
   carries no override; the three different sizes read earlier (7 / 8 / 6.524) were
   an older state of this frame and are superseded by 2053:1616. */
.bw-cap-time {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 12.583px;
  font-size: 8px;
  font-weight: 300;
  line-height: normal;
  color: rgba(246, 235, 228, 0.4);
  opacity: 0.8;
  white-space: nowrap;
}
/* ONE per-pair line-box exception is left: pair 3's timestamp is auto-height where
   the other three are a fixed 12.583 box. Pairs 2 and 4 both carry fixed 15.85
   caption boxes now (each was auto-height nowrap in an earlier state of this
   frame), so no caption override survives. */
.bw-cap-group--start .bw-cap-time { height: auto; }

/* =========================================================================
   CLIP/EDIT/SWAP SEQUENCE — PART I. Storyboard 2206:11566 states 1-4:
   default -> hover -> select/edit clip -> edit mode (default). Guides for the
   states themselves are 2178:3439 (hover) and 2178:6646 (edit window).

   EVERY STATE BELOW IS PLAYED, NOT HOVERED. There is deliberately not one
   :hover rule in this section. The timeline sets classes and tweens these
   properties; real pointer hover does exactly one thing, in the JS, which is
   pause the auto-play and resume it on leave. A :hover rule added here would
   fire a second, competing copy of the state and desync the sequence.

   THE REST STATE IS THE PRE-SEQUENCE SCREEN. Tint, action row and checkmark
   are all opacity 0 and the window is parked off-stage, so with JS disabled
   this screen renders exactly as it did before Part I existed.

   DARK SCREEN ONLY, BY CONSTRUCTION. Every class here exists only inside
   #bwProjectScreen's markup — screens 2, 3 and 4 have no .bw-thumb--seq and no
   .bw-editwin, so none of these selectors can reach them. That is why no
   screen-modifier qualifier appears, and it is checkable: grep the markup.
   ========================================================================= */

/* ---- clip 1's hover state (2178:3439) ---------------------------------- */
/* .bw-thumb--seq is the ONLY thumb that becomes a positioning context. The base
   .bw-thumb is shared with screens 2/3/4 and must not gain one.

   PAINT ORDER IS DECLARED HERE, NOT INFERRED — 2178:3439: image, then the pink wash on
   it, then the controls in front of both. All three used to sit at `z-index: auto`,
   which meant the order was DOM order and nothing else: correct by accident, and
   silently at the mercy of anything that promotes one of them into its own stacking
   context. That is not a property this sequence can leave implicit — each of them takes
   a transform or an opacity from the timeline, and the controls are the one thing the
   state exists to show.

   THREE LAYERS, NOT FOUR: a checkmark used to land here on the controls' own centre and
   held z-index 4. State 3 goes press, white, clear, open now, and it has been removed
   rather than left hidden — the panel's own checkmarks (.bw-ew-f-check, one per marked
   frame) are different elements on a different box, and two things called "the
   checkmark" is how that gets confused.

   `isolation: isolate` is what makes the ladder safe to state. Without it these indices
   would resolve against .bw-track-selected's stacking context and sort themselves among
   the playhead and the other thumbs; with it they are contained to this thumb, and the
   thumb itself keeps `z-index: auto`, so its own position among its siblings is exactly
   what it was. */
.bw-thumb--seq { position: relative; isolation: isolate; }
.bw-thumb-img { position: relative; z-index: 1; }
/* The 30% #FF3567 wash the node puts over the frame (2178:3749). BEHIND THE CONTROLS:
   it washes the image, not the buttons — their discs are opaque #2E2225 and read as
   solid dark over it. */
.bw-clip-tint {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: rgba(255, 53, 103, 0.3);
  opacity: 0;
  pointer-events: none;
}
/* icons-hover-thumb 2178:5032 — 115 x 24 on an 8px gap, centred in the 139.81
   frame (12.4 each side). Like and add carry their own #2E2225 disc inside the
   asset; the Edit control does not, so its pill is drawn here. */
.bw-clip-actions {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 8px;
  opacity: 0;
  pointer-events: none;
}
/* SPECIFICITY, NOT PREFERENCE: the base sheet carries `.bw-thumb img { width:100%;
   height:100% }` for the filmstrip pictures, which would blow every icon in here up
   to the full frame. `.bw-thumb--seq .bw-clip-act` is (0,2,0) against that (0,1,1),
   so these win. Do not un-nest them. */
.bw-thumb--seq .bw-clip-act { flex-shrink: 0; }
.bw-thumb--seq .bw-clip-act--like,
.bw-thumb--seq .bw-clip-act--add { display: block; width: 24px; height: 24px; }
/* THE MIDDLE CONTROL IS A LABELLED PILL, NOT A THIRD ICON — 2178:5035 is 51 x 24,
   #2E2225 at radius 32, holding a 12.4 glyph and the word "Edit" on a 4px gap.
   Raised in the report: the brief calls all three "icons". */
/* position + z-index SO THE OUTER ICONS CAN TUCK UNDERNEATH. The like and add glyphs
   slide inward on the press and finish BEHIND this button (js, the 'press' / 'altclick'
   beats). Source order alone will not do it — the row paints like, button, add, so the add
   glyph would cross OVER the button on its way in. A positive z-index here puts the button
   above both siblings without touching their own stacking. */
.bw-thumb--seq .bw-clip-act--edit {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 51px;
  height: 24px;
  box-sizing: border-box;
  padding: 1.398px 2.796px;
  border-radius: 32px;
  background: #2e2225;
}
/* THE PRESS TURNS THE LABEL AND ITS GLYPH WHITE — state 3 mimics the click that opens
   the panel. The glyph is an <img>, so the only way to recolour it is a filter, and
   `brightness(0) invert(1)` is the two-step to flat white. It is declared here at its
   IDENTITY value rather than as `none` so the timeline has matching filter functions to
   interpolate between; from `none` the change would snap instead of easing.
   The rest value is the label's #776868, restated in the timeline's own rest block. */
.bw-thumb--seq .bw-clip-act--edit img {
  display: block;
  width: 12.4px;
  height: 12.4px;
  filter: brightness(1) invert(0);
}
.bw-thumb--seq .bw-clip-act--edit span {
  font-size: 12px;
  font-weight: 400;
  line-height: 1;
  color: #776868;
  white-space: nowrap;
}
/* ---- the Edit window (2178:6646 / Group 13260) -------------------------- */
/* THE TRANSFORM LIVES ON THE WRAPPER, one level above the panel, so that what slides
   is the window as an object and the panel keeps its own clip for its contents.
   Parked at translateX(100%) — one full self-width right of its rest position, which
   is fully outside .bw-screen's overflow:hidden.
   Height is the panel's 560, not the node group's 560.416: that extra 0.416 only ever
   described the prompt bar hanging past the bottom, and the bar now sits inside. */
.bw-editwin {
  position: absolute;
  top: 19.584px;
  right: 0;
  width: 997.164px;
  height: 560px;
  z-index: 20;
  transform: translateX(100%);
  pointer-events: none;
}
.bw-ew-panel {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 560px;
  box-sizing: border-box;
  /* #0F0F0F — the panel inverts with the 2346:2015 re-pull. It was #F8EFE9, and every
     rule below that reads dark-on-light had to turn with it; the ones that did NOT are
     the chips, which keep their pale fill and their dark ink. */
  background: #0f0f0f;
  border-radius: 16px 0 0 16px;
  /* NO BOX-SHADOW, DELIBERATELY (user, 2026-08-24 — "flat is better"). A --bw-glass-shadow
     inset edge was added here and REVERSED at the user's call. It is not an oversight and
     it is not a divergence from the node: Figma 2347:25469 (EDIT-panel-1) DOES paint the
     panel with that inset pair, and the user has overridden it. The panel sits flat
     against the project ground on purpose — do not "restore" it from the node. */
  overflow: hidden;
}
/* Icons-close-expand 2191:5566 at x939.082 w44.001 in the panel's OWN frame, i.e.
   997.164 - 983.083 = 14.081 from its right edge. Anchored off the panel box, not
   the padding box: .bw-ew-inner carries the 24px padding, so an absolute child of
   the panel is unaffected by it and the node's number transfers directly. */
.bw-ew-icons {
  position: absolute;
  top: 16px;
  right: 24px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 5px;
}
.bw-ew-expand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 12px;
  background: #221016;
}
.bw-ew-expand img { display: block; width: 12px; height: 12px; }
/* THE CLOSE IS A DISC AT REST NOW, AND IT IS THE SAME DISC EXPAND WEARS. 2347:2266 makes
   the row 24 + 5 + 24 = 53 wide, and 2347:2259 exports as a #221016 circle with a #FF3567
   X on it — so the close stops being a bare 12.001 glyph in the row and becomes expand's
   twin. That is why the row's own numbers moved with it: gap 8 -> 5 and right 14.081 -> 24
   are what a 53-wide group needs, not a second opinion about the old 44.001 one.
   THE CLICK'S PINK DISC STILL SITS ON TOP OF THIS ONE and is untouched — see below. */
.bw-ew-close {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 12px;
  background: #221016;
  /* THE RAISED EDGE, DECLARED AT ZERO ALPHA. The active close carries effects so it reads
     raised rather than flat (2351:37659); at rest it is flat. Stating the same two inset
     shadows here with alpha 0 gives the timeline a matching function list to interpolate
     FROM — the same reason the glyph filters are declared at their identity rather than as
     `none`, and the reason a shadow tween does not snap on its first frame. */
  box-shadow:
    inset 1px 1px 2px 0 rgba(255, 255, 255, 0),
    inset -1px -2px 2px 0 rgba(255, 255, 255, 0);
}
/* THE X, AS A MASK RATHER THAN AN IMAGE. The close beat inverts the pair — the disc goes
   #221016 -> #FF3567 and this goes #FF3567 -> #221016 — and #221016 is an arbitrary hue,
   which an <img> cannot be taken to by filter. Masking the same SVG and colouring the span
   underneath makes both ends a real `background-color`, so the timeline tweens a colour
   instead of a filter function list, and the identity `filter: brightness(1) invert(0)`
   that the old rule had to declare (purely so GSAP had something to interpolate FROM) is
   gone with it.
   THE SEPARATE PINK DISC IS GONE TOO. `.bw-ew-close-disc` existed to bloom a second circle
   over a close that had none at rest; the re-pull gives the close its own #221016 disc, so
   the beat recolours THAT one and there is nothing left to stack.
   ONE SIZE IN BOTH STATES — 9.0935, the X the re-pulled icon-close-dark.svg (24 x 24,
   #221016 disc, #FF3567 X) draws inside its own 24 disc. The 12.001 this carried was the
   glyph's size back when the close was a bare X in the row with no disc at all, kept after
   the disc arrived; against a 24 disc it is 50% where the export is 37.9%, which is 74%
   more ink and is what read as over-saturated once the active X went white.
   THE GLYPH ITSELF IS UNCHANGED AND STILL THE SUPPLIED ONE. Both exports' X paths were
   checked against this mask point for point — 33 points each, deviation 0.0000107 against
   icon-close-dark and 0 between the two exports. Same glyph at three scales; only the box
   it is drawn into moves. Nothing to extract that is not already here. */
.bw-ew-close-x {
  position: relative;
  z-index: 1;
  display: block;
  width: 9.0935px;
  height: 9.0926px;
  /* FULL-STRENGTH #FF3567, and the mask is a silhouette. The old export carried
     fill-opacity 0.85 IN THE MASK, and a mask reads ALPHA — so every colour this element
     was tweened to came out multiplied by 0.85 and the white end composited to
     (255, 225, 232), a pale pink that could not reach white however it was written. The
     re-pulled default states a flat #FF3567 X with no transparency at all, so the 0.85 is
     gone from both places rather than moved. */
  background-color: #ff3567;
  -webkit-mask: url(../assets/brandip/icon-close-edit.svg?v=3) center / contain no-repeat;
          mask: url(../assets/brandip/icon-close-edit.svg?v=3) center / contain no-repeat;
}
.bw-ew-inner {
  box-sizing: border-box;
  height: 100%;
  padding: 16px 24px 8px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.bw-ew-head { display: flex; align-items: center; gap: 8px; }
.bw-ew-title { font-size: 24px; font-weight: 400; color: #ff3567; line-height: normal; }
.bw-ew-title-ico { display: block; width: 16px; height: 16px; }
.bw-ew-content {
  display: flex;
  flex-direction: column;
  gap: 24px;
  /* six thumbnails and the five gaps between them: 6 x 150 + 5 x 4 = 920. The reel is
     exactly this wide, which is what makes a seventh tile off-stage on either side. */
  --bw-tile-w: 150px;
  --bw-tile-gap: 4px;
  --bw-reel: calc(var(--bw-tile-w) * 6 + var(--bw-tile-gap) * 5);
}
/* ROW A, RE-PULLED 2026-08-12 (Frame 48098374, 2212:5673). THREE COLUMNS, NOT FOUR,
   on a 24 gap: Col-1 0..362.99, Col-2 386.99..604.31, Col-3 628.31..850.09. What
   closes the fourth column is Video style — it has left the row and stacked under
   Col-3, and it is the third box there.

   THE ROW IS 254.80 TALL. The node draws 165.37 and the difference is Video style
   opening at rest (2026-08-15, see the markup): the box goes 30.45 -> 118.08 and the
   row goes with it. Everything under Row A moves down the same 87.63 — "More Nyjah
   Huston" from 251.17 to 338.80, still whole; "Other Street Skateboarders" from 373.67
   to 461.30, which puts its first tile row under the prompt bar and its names past the
   panel's 560. THAT IS A KNOWN COST, taken deliberately so the drop has chips to sweep
   over. The node clips in the same place for the same reason, 87.63 higher up. */
.bw-ew-rowa { display: flex; align-items: flex-start; gap: 24px; }

/* ── PART II — THE CHIP RAIL ───────────────────────────────────────────────────
   What the four boxes collapse into: one line of four EQUAL chips on Row A's bottom
   edge (2223:6420 -> 2196:7587).

   THE WIDTH IS DERIVED, NOT TAKEN FROM THE NODE. Measured off the guides, the collapsed
   row is 219 / 192 / 192 / 193 with uniform 8px gaps — the boxes keep their EXPANDED
   widths into the rail, which totals 815.43 and leaves 133.73 of the row unused on the
   right. Four equal chips and three 8px gaps across the row is the rule written here
   instead. At the shipped 949.164 it resolves to 231.291, it stays right if the panel
   width ever moves, and it clears the node's own chips at both sizes — 13.97 of headroom
   over sponsors' 217.32, 39.92 over the other three's 191.37 — so nothing clips collapsed.
   (An earlier reading of this note had the guides drawing all four at 217.32. They do not;
   only sponsors is that wide. The derived rule is unaffected, the premise was wrong.)

   BOTTOM-ALIGNED, and that is derived too. The rail is the row's last line, which is
   exactly where the already-collapsed Video style box sits — so it never travels at all,
   and the stretched sponsors box, whose bottom is that line already, collapses without
   moving. Only Personal Brand Ventures actually falls, and only as far as the measure
   says (113.46 at the shipped sizes; nothing states it).

   THE ROW'S HEIGHT IS FROZEN INLINE by the timeline before the boxes leave the flow.
   Without it Row A would collapse onto Col-1 the instant these go absolute and every
   thumbnail strip below would jump up 66px mid-animation. */
.bw-ew-rowa {
  position: relative;
  isolation: isolate;
  /* One number governs the separation. The width is what is left of the row after three
     gaps, so widening the gap narrows the chips and the four still span the row exactly
     — they cannot be made to touch from here. */
  /* the clip stack's height: 8 of ghost above the card, then the card's own 91. The
     details line and the slider are placed off it, so they cannot drift from the strip. */
  /* 8 of ghost above the card, then the card itself — derived now, so the stack, the
     details line (--bw-clip-h + 8) and the slider all follow the thumbnail's ratio.
     THE 4px REVEALS DO NOT DEPEND ON THIS. They come from the ghosts' own top offsets
     (0 / 4px) against the card's 8px, so each band stays 4 whatever the card's height
     becomes — it is the STACK's height that has to follow, and it does, here. */
  --bw-clip-h: calc(var(--bw-tile-w) / 2 + 16px);
  --bw-chip-gap: 8px;
  --bw-chip-w: calc((100% - var(--bw-chip-gap) * 3) / 4);
  --bw-chip-pitch: calc(var(--bw-chip-w) + var(--bw-chip-gap));
}
/* OPAQUE WHILE THEY TRAVEL, and it costs nothing to look at. A box that passes over
   another has to hide it completely — the glass ground is rgba(255,255,255,0.4) and
   anything underneath reads straight through it, which is what made the first build
   muddled. #FBF5F2 is that exact glass composited onto the panel's own #F8EFE9
   (0.4 x 255 + 0.6 x 248/239/233 = 250.8 / 245.4 / 241.8), so at rest the swap is
   invisible and in motion it occludes. The inset glass edge is untouched.

   Z-ORDER IS STATED for the same reason: Personal Brand Ventures passes in FRONT of
   Brand influence and Video style, and DOM order would put it behind both. Contained
   by `isolation` on the row above, so these four cannot sort themselves against
   anything else in the panel. */
/* THIS RULE RESTATES THE GROUND, AND THAT IS WHY THE RECOLOUR BROKE THE RAIL.
   The base `.bw-ew-box` went `rgba(255,255,255,0.4)` -> `#221016` with the 2346:2015 pull
   and this one did not follow, because it does not inherit — it is a higher-specificity
   restatement that has carried its own copy of the ground since the rail was built. So in
   the rail state the four boxes stayed CREAM while everything sitting on them had already
   turned for a dark ground, and the title — now `rgba(251,245,242,0.85)` — went
   light-on-cream, i.e. invisible. That is the reported "four empty cream pills": not the
   chips disappearing, but the collapsed pill losing the only thing it still paints.
   THE STYLEGUIDE'S RULE IS WHY IT IS RESTATED RATHER THAN DELETED. An override must not
   silently inherit a value that belongs to another state; if it wants the base's number it
   says the number. Deleting the declaration would fix today and hide the next divergence.
   So: grep this file for `.bw-ew-box` before changing the base's ground — there are two
   grounds, and they have to move together. */
.bw-ew-rowa--rail .bw-ew-box {
  position: absolute;
  bottom: 0;
  width: var(--bw-chip-w);
  overflow: hidden;
  background: #221016;
  /* STATED, NOT INHERITED. Without this the four boxes each keep the radius of their
     EXPANDED self — Col-2's 16 on sponsors against Col-3's 8 on the other three — and the
     rail renders one chip with a visibly rounder corner than its three neighbours. In the
     rail they are four of the same object, so the radius is one number here. 8 is what the
     storyboard's collapsed row draws (2383:5346, corner inset 6/4/2/1/1/0 from the edge)
     and what three of the four already carried. */
  border-radius: 8px;
}
.bw-ew-rowa--rail .bw-ew-box--sponsors  { left: 0;                              z-index: 1; }
.bw-ew-rowa--rail .bw-ew-box--ventures  { left: var(--bw-chip-pitch);           z-index: 3; }
.bw-ew-rowa--rail .bw-ew-box--influence { left: calc(var(--bw-chip-pitch) * 2); z-index: 2; }
.bw-ew-rowa--rail .bw-ew-box--style     { left: calc(var(--bw-chip-pitch) * 3); z-index: 1; }
/* THE ROWS MUST CLIP, NOT SQUASH — this is what makes the collapse read as chips going
   out one row at a time instead of a box deflating. .bw-ew-box is a column flex and its
   children take the default `flex-shrink: 1`, so shrinking the box compresses every row
   at once and the whole stack squeezes. Pinning them at their own height sends the
   overflow past the box's pinned bottom edge instead, where `overflow: hidden` takes it:
   the last row goes, then the one above it, up to the title. A reveal played backwards.

   THE TITLE CENTRES AS IT COLLAPSES, and that is done in the timeline rather than here.
   `align-items: center` would be a snap, and applying it on any single frame of a
   collapse is exactly the re-alignment that was rejected earlier — so the title keeps
   its left-aligned layout and is carried to the centre by a transform driven off the
   collapse's own progress. Same reason it is not a second tween: it has to resolve WITH
   the height, not alongside it. The offset is recomputed from the live box, so it stays
   centred while the chip later widens into the rail. */
.bw-ew-rowa--rail .bw-ew-boxtitle,
.bw-ew-rowa--rail .bw-ew-chiprow { flex-shrink: 0; }
/* AND THE TITLE HAS TO HUG ITS TEXT BEFORE IT CAN BE MOVED. .bw-ew-box is a column
   flex, so the title was being STRETCHED to the full box width and its text simply sat
   at the left of it — measured, there was 0.0 of slack on either side, so the centring
   transform had nothing to travel across and moved nothing. Shrink-wrapping it changes
   nothing visible (the box paints no ground of its own and the text was already left),
   and it is what gives the transform something to centre. */
.bw-ew-rowa--rail .bw-ew-boxtitle { align-self: flex-start; }
/* Col-1 2212:5674 — 362.99 x 99, and both children are placed off it absolutely: the
   stack is its own 220-wide box and the tags sit BESIDE it now, not under it. */
/* THE STRIP PAINTS OVER THE DETAILS. That is the move — the clip slides across them as
   it widens rather than anything fading — so the stack is stated above the tags, and
   Col-1 isolates so these two indices cannot sort themselves against the chip rail's. */
.bw-ew-col1 { position: relative; width: 362.99px; height: var(--bw-clip-h); flex-shrink: 0; isolation: isolate; }
/* --bw-clip-h is the stack's height AND what the details line is placed off, so the two
   cannot drift apart: 8 of ghost above the card, then the card's own 91. */
.bw-ew-stack { position: absolute; left: 0; top: 0; z-index: 2; width: 219.99px; height: var(--bw-clip-h); }

/* ── PART II — THE EXPANDED CLIP'S DETAILS LINE (2196:11294) ───────────────────
   THERE IS NO SEPARATE LINE ELEMENT. The details are not swapped for a new row — the
   block beside the card IS the line, moved and unstacked into it, so nothing fades and
   nothing is duplicated. The target positions are derived at runtime in the timeline
   from the three items' own measured boxes; the only numbers typed anywhere are the
   guide's two flex gaps, 8 between the timestamp and the name and 4 between the name
   and the caption, which together reproduce its 282.99-wide group exactly
   (63 + 8 + 77 + 4 + 131).

   The line's own y is the card's bottom plus 8, measured, which is why --bw-clip-h is
   declared once and both the stack and the slider read it.

   zoom 2196:11301 — 100 x 12 hung off the row's right edge at -0.33, and ABOVE centre:
   its top is -4.02 against a 14-tall line, which is the node's number and not a
   centring anyone would arrive at. This is the one thing that does fade in, once the
   clip and the details have both stopped. */
.bw-ew-zoom {
  position: absolute;
  right: -0.33px;
  top: calc(var(--bw-clip-h) + 8px - 4.02px);
  display: block;
  width: 100px;
  height: 12px;
  opacity: 0;
}

/* THE TWO CARDS BEHIND — 2212:5677 (far) and 2212:5686 (near). Each is a whole 91-tall
   card, and each is covered by the one in front down to a 4px band: the far one shows
   0..4, the near one 4..8, and the front card owns 8..99. Their own 4px top padding
   means no frame ever reaches those bands, so what actually paints is ground and edge.
   The frames are carried anyway, and that is deliberate — Parts II and III fan this
   stack, and a layer that is only a coloured strip would have to be rebuilt then.

   NOT PORTED: each layer's "More" badge (2212:5679 / 5688 / 5707). The node z-orders it
   BELOW its own frames — z1 under z2 on the ghosts, z2 under z7..3 on the front — so it
   never paints. It is the second checkmark node the 2026-08-12 re-pull report flagged. */
.bw-ew-ghost {
  position: absolute;
  box-sizing: border-box;
  /* HUGS THE FRAME, so it follows the ratio instead of restating a height. 4 + w/2 + 4;
     at 150 wide that is 83, where it used to be a flat 91 around an 83 frame. */
  height: calc(var(--bw-tile-w) / 2 + 8px);
  padding: 4px 8px;
  display: flex;
  align-items: flex-start;
  isolation: isolate;
  border-radius: 8px;
  /* THE CONTAINER GLASS, NOT A WHITE STROKE — re-pulled from 2347:25486 (2026-08-18).
     All three stack layers carried `inset 0 0 0 0.5px #fff`, a hairline keyline. The node
     replaces it with the same inset pair the Col-2/3 chip containers wear, so the stack
     reads as the same material as the boxes beside it rather than as an outlined object.
     --bw-glass-shadow is that pair, already declared for those containers, so this is the
     token rather than a copy of its values.
     ONE DEVIATION, 1px: the node gives the NEAR ghost `inset -1px -1px` where the far ghost
     and the card both get `-1px -2px`. Taken as the token's -2 on all three — a 1px y offset
     on the fainter of two inset highlights, against three layers that are otherwise the same
     treatment. Restate it here if the node ever means it. */
  box-shadow: var(--bw-glass-shadow);
}
/* The furthest layer's ground is 60% WHITE, not the opaque #FBF5F2 it shipped at
   (guide 2212:6187). It reads as the palest of the three because it is the only one
   letting the panel's #F8EFE9 through rather than sitting on top of it.
   Recorded, because the two disagree: the guide's design context returns this fill as
   `bg-white`, i.e. opaque, with no alpha and no node opacity beside it. The brief says
   60% and the brief wins; over #F8EFE9 the two land about 1% apart anyway, so this is a
   difference in what is declared rather than one anybody could see. */
.bw-ew-ghost--far  { left: 26.995px; top: 0;   width: 166px; background: rgba(255, 255, 255, 0.6); }
.bw-ew-ghost--near { left: 18.995px; top: 4px; width: 182px; padding-left: 16px; padding-right: 16px; background: #c3bab8; }
.bw-ew-ghost .bw-ew-f { margin-right: 0; }

/* Row_1 2212:5696 — the front card. FIVE frames now, not six: f1 has moved out to the
   near ghost. 5 x 150 - 4 x 144 = 174 against a 171.99 content box, so the last 2.01 of
   f5 sits inside the 24 right padding, exactly as the node has it.

   THE EDGE IS AN INSET SHADOW, NOT A BORDER, and that is load-bearing. Figma's 0.5
   stroke overlays the frame box; a real CSS border would come out of the padding box
   instead and walk the whole filmstrip 0.5 inward, which is the one measurement in here
   that must not move. Same reason on the two ghosts above. */
.bw-ew-card {
  position: absolute;
  left: 0;
  top: 8px;
  box-sizing: border-box;
  width: 100%;
  height: calc(var(--bw-tile-w) / 2 + 8px);
  padding: 4px 24px;
  display: flex;
  align-items: flex-start;
  isolation: isolate;
  border-radius: 8px;
  /* Same swap as .bw-ew-ghost — see the note there. The card also gains the node's own
     keyline, which the ghosts do not have: 0.25px of rgba(34,16,22,0.4), an edge INTO the
     dark ground rather than a highlight on it. box-sizing is already border-box, so the
     0.5px it costs comes out of the 24px padding and moves no frame. */
  border: 0.25px solid rgba(34, 16, 22, 0.4);
  box-shadow: var(--bw-glass-shadow);
  background: #221016;
}
.bw-ew-f {
  position: relative;
  display: block;
  flex-shrink: 0;
  /* ── THUMBNAILS ARE 2:1, AND THE RATIO IS THE SPEC ──────────────────────────────
     Every thumbnail in this project is one size at one ratio. Figma's 150x82.5 and 139x76
     were APPROXIMATIONS of it — 76 is not half of 150, and neither is 82.5 — so the pair
     is not the thing to carry. `aspect-ratio` with a width is, and the height then cannot
     drift from the ratio because nothing states it.
     WIDTH IS THE AUTHORITATIVE HALF: --bw-reel is 6 x --bw-tile-w + 5 gaps = 920 and the
     reel window is derived from it, so moving width moves the strip geometry, where moving
     height moves only the thumbnail.
     var, not a second 150 — this frame and .bw-ew-tile are the same thumbnail. */
  width: var(--bw-tile-w);
  aspect-ratio: 2 / 1;
  margin-right: -144px;
  overflow: hidden;
}
.bw-ew-f--1 {
  z-index: 8;
}
/* THE SIXTH FRAME, CARRIED AT ZERO WIDTH. It is in the card in numbering order but takes
   no space at rest, so the five-sliver layout above is untouched — f1's -144 puts f3 at 6
   whether this sits between them or not. The 'fan' tween widens every frame to the tile,
   this one from 0, and the strip that opens is the guide's six rather than five. Selected
   it is not: the four that swap are 1, 3, 4 and 6.
   z-index 7 keeps the descent 8..3 intact so the slivers still stack left-to-right. */
.bw-ew-f--2 {
  width: 0;
  margin-right: 0;
  z-index: 7;
}
.bw-ew-f--3 { z-index: 6; }
.bw-ew-f--4 { z-index: 5; }
.bw-ew-f--5 { z-index: 4; }
.bw-ew-f--6 { z-index: 3; margin-right: 0; }
.bw-ew-f img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* f0 is the SELECTED frame and carries the same 30% #FF3567 the clip does. */
/* THE MARK: WASH AND CHECKMARK, ONE ELEMENT. They are nested in a single box on the
   frame they belong to, so they cannot be animated, positioned or revealed apart —
   which is exactly what went wrong before. The checkmark used to be ONE mark centred on
   the CARD while the wash sat on f0; at 220 wide those read as the same place, but the
   expansion takes the card to 949 and the card's centre walks off f0 and lands on the
   third frame. Tint on one frame, check on another, from a rule that looked right.
   Superseding the earlier "centred on 2212:5692": the mark is centred on its FRAME now,
   which moves it 11px at rest and keeps the pair together at every width.

   FOUR FRAMES CARRY IT — 1, 3, 4 and 5, which is what the guide's expanded strip shows.
   The three late ones are held at 0 until the strip opens: their frames are 6px slivers
   until then, and a 24px checkmark clipped into a 6px band is not a checkmark. */
.bw-ew-f-mark { position: absolute; inset: 0; z-index: 2; }
.bw-ew-f-mark--late { opacity: 0; }
.bw-ew-f-tint { position: absolute; inset: 0; background: rgba(255, 53, 103, 0.3); }
/* SPECIFICITY, NOT PREFERENCE — the same trap `.bw-thumb img` sets for the clip's hover
   controls. `.bw-ew-f img { width:100%; height:100% }` is (0,1,1) and matches this
   checkmark, so a bare `.bw-ew-f-check` at (0,1,0) LOST and the glyph was stretched to
   the whole frame. Qualifying it takes it to (0,2,0). Do not un-nest. */
.bw-ew-f .bw-ew-f-check {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 24px;
  height: 24px;
  object-fit: contain;
}

/* THE TICK'S CONFIRMED STATE, STACKED. The resting checkmark is #FFFFFF at fill-opacity
   0.6 over the #2E2225 disc, which composites to a cream — so "the tick goes white" has
   somewhere to go, but not somewhere CSS can take it: this is an <img>, and any filter
   that lifts the tick lifts the disc with it. The disc must not move.
   So the confirmed tick is a second file — icon-checkmark-white.svg, the node's own export
   (2347:27325) — laid exactly over the first and faded in. Checked before wiring: same
   viewBox, and the disc and tick path data are byte-identical to the resting file, so the
   two cannot sit apart. Its root carried none of the resting export's render attributes;
   they are matched here so the only difference left between the files is the tick's fill.
   The discs coincide, so what crosses is the tick alone.
   Same idiom as .bw-ew-f-alt, which stacks the swapped still over the original. */
.bw-ew-f .bw-ew-f-check--on {
  opacity: 0;
}
/* Icon-handle-active 2212:5711 is a 24 box at right -0.5, top 34.06, with 8px padding,
   so the 8x8 dot block lands at 204.49 / 42.06 in the card (219.99 + 0.5 - 24 + 8).
   Reuses #bw-handle-active — the symbol is already defined once on this screen and must
   not be cloned. z-index 1: the node puts the handle UNDER the frames now, where it was
   8 before, which shows only where f5's overflowing 2.01 crosses the box and never over
   the dots themselves. */
.bw-ew-handle {
  position: absolute;
  left: 204.49px;
  top: 42.06px;
  z-index: 1;
  width: 9px;
  height: 8px;
  overflow: visible;
}
/* Tags 2212:5725 — out from under the card and stacked beside it. top 11 plus the
   node's own 4 top padding puts the name at 15, and the 8px gaps put the caption at 37
   and the time at 59. Three lines where there were two: the name has lost its comma. */
.bw-ew-tags {
  position: absolute;
  z-index: 1;
  left: 227.99px;
  top: 11px;
  padding-top: 4px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
/* 500 (Bricolage Medium), where the old node carried 300 — and the time joins the
   caption at #A69B98 instead of holding the full-strength #221016. */
/* #FBF5F2, and this one is NOT in the brief — it is forced. The caption was
   rgba(34,16,22,0.85), i.e. near-black on what is now a #0F0F0F panel, so leaving it would
   have deleted "Nyjah Huston, American skateboarder" from the screen. Sampled off the guide
   at #ECE6E5 core, which is this colour under its own antialiasing. */
.bw-ew-tag { font-size: 12px; font-weight: 500; color: #fbf5f2; }
/* #A69B98, not the darker pass's #776868 — the caption lightens with the boxes. */
.bw-ew-tag--dim { color: #a69b98; }
.bw-ew-time { font-size: 10px; font-weight: 500; color: #928686; }

/* THE FOUR CHIP BOXES — THE LIGHTER TREATMENT, 2204:11542 ("Panel-edit").
   2178:6646 paints these boxes dark: an rgba(119,104,104,0.85) ground at radius 8
   with cream titles and white-85% chips. That is the DARKER pass and it is not what
   ships — 2204:11542 is the same four boxes done pale, and the whole system moves
   with it, not just the ground:

                    darker (2178:6646)          lighter (2204:11542, SHIPPED)
     box ground     rgba(119,104,104,0.85)      rgba(255,255,255,0.4)
     box radius     8                           16
     box padding    4                           8
     box title      rgba(248,239,233,0.85)      rgba(34,16,22,0.85)   cream -> dark
     chip ground    rgba(255,255,255,0.85)      rgba(255,255,255,0.6)
     chip radius    24 (full)                   8
     chip ink       #776868                     #928686
     chip edge      none                        the three-part glass inset
     row gap        4                           3.728

   The title inverting is the tell that this is one decision and not a recolour:
   pale ground, dark ink. Take the whole row or none of it. */
.bw-ew-box {
  box-sizing: border-box;
  padding: 8px;
  border-radius: 16px;
  /* #221016 flat, from 2346:2072 — not the rgba(255,255,255,0.4) glass this carried. The
     radius and the glass shadow are unchanged, so the container keeps its edge and only
     its ground turns. */
  background: #221016;
  /* THE WHITE PAIR, RESTORED (2026-08-24). A dark variant was tried here and it made the
     boxes FLATTER, not lifted — the reason is arithmetic, so it is recorded rather than
     re-attempted: this ground is #221016 = (34,16,22), so even pure black at alpha 1 can
     only darken it by (34,16,22), while white is (221,239,233) away. A dark bevel on this
     box cannot produce a readable edge at any alpha. The LIGHT edge is what makes these
     containers lift, which is also what the node paints and what the main page's inner
     containers use. */
  box-shadow: var(--bw-glass-shadow);
  display: flex;
  flex-direction: column;
  gap: 7.457px;
}
/* THREE OF THE FOUR HUG THEIR CONTENT in this node, where the darker one sized all
   four explicitly. Only the two measurements it still states are kept. */
/* ONE WIDTH FOR ALL FOUR, SET BY THE WIDEST CHIP — 226px (user, 2026-08-18).
   SUPERSEDES "three equal plus one wider" from earlier the same day, and with it the
   DO-NOT-RE-EQUALISE note that rule carried. Both readings were arrived at from the
   OUTSIDE — the node's drawn widths — and both were wrong for the same reason: the width
   is a consequence of the content, and Video style's content is the widest in the panel.
   Measured, each box against its own widest chip plus the 8/8 padding:
     Collaborations & Apparel Sponsors   217.31   needs 205.98
     Personal Brand Ventures             191.00   needs 105.48
     Brand influence                     191.00   needs 126.67
     Video style                         191.00   needs 225.75   <- clipped by 34.75
   225.75 is "Visual language inspired by Wieden+Kennedy agency" at 209.75 plus the
   padding. 226 rather than 225.75 because the .25 is below anything the layout can show
   and text measurement is not bit-stable across a font swap.
   THE RAIL IS NOT THIS NUMBER and does not need to be — it derives 231.291 from the row
   (see Part II), which clears the same chip by 5.54. Pinning the rail to 226 would leave
   22.16 of the row unused for no gain. */
.bw-ew-box--sponsors,
.bw-ew-box--ventures,
.bw-ew-box--influence,
.bw-ew-box--style { width: 226px; }
/* Col-3 2212:5766 — THREE boxes, on the same 16 gap, and no height or centring of its
   own: it hugs 51.46 + 16 + 52.36 + 16 + 118.08 = 254.80 and that sum is what sets Row
   A's height. Video style is the third child and it is OPEN — see the markup for why
   it departs from the node there. The column's WIDTH comes from it too: the boxes
   stretch to the widest, so an open Video style takes Col-3 from 191 to 221.78. Both
   fit — Row A had 134 of slack on its right and the row grew into it. */
.bw-ew-boxcol { display: flex; flex-direction: column; gap: 16px; }
/* The sponsors box takes its height from the row rather than hugging its own chips,
   which is what puts its bottom edge level with the collapsed Video style box. */
.bw-ew-box--sponsors { align-self: stretch; }
/* --style now carries NO DECLARATIONS: it used to state height 120 and the box hugs its
   chip list instead. It stays in the markup as the box's identity, which is what the
   contract states will have to target. Not a rule that went missing. */
/* A TRANSITION CLASS, NOT A RESTING ONE (2026-08-15). Nothing is authored with it any
   more — Video style was the last holder and it opens at rest now. What still uses it:
   toRail() puts it on for the length of ONE measurement to read a box's collapsed
   height, and seal() puts it on for good the moment a box finishes folding, because
   clipping alone leaves ~4.9px of the first row showing under the title.
   The box hugs its title at 8 + 14.46 + 8 = 30.46 with it on.
   display:none is right for both of those and wrong for anything tweened: when the
   contract states (2196:7587 / 2196:9458) land they will need something animatable, and
   this modifier is the seam to change then, not the markup. */
.bw-ew-box--collapsed .bw-ew-chiprow { display: none; }
/* The 4.66 left pad is the same one .bw-inf-title carries — it is what holds every
   title's text on the x its box is measured from, and nothing paints it. */
.bw-ew-boxtitle {
  display: inline-flex;
  align-items: center;
  height: 14.46px;
  padding: 0 4.66px;
  font-size: 8px;
  /* 500, up from 300 — 2346:2078 is Bricolage Grotesque Medium. The chips beside it stay
     Light, so the title now carries the weight contrast that the old all-300 pair did not. */
  font-weight: 500;
  opacity: 0.8;
  color: rgba(251, 245, 242, 0.85);
  white-space: nowrap;
}
.bw-ew-chiprow { display: flex; align-items: center; gap: 3.728px; }
/* ONE CHIP TREATMENT, where the node has three. Its chips run 8px Bricolage Light,
   8.389px Bricolage Light and 8px Lexend Light across the four boxes with no
   pattern to it — the same drift the 2026-08-06 type pass found elsewhere on this
   screen, and it survives unchanged into the lighter pass. Normalised to the
   majority (8px Bricolage Light) and raised in the report rather than reproduced.

   The box-shadow is the SAME three-part inset .bw-name carries. Written out rather
   than tokenised: .bw-name predates this and is load-bearing for screens 2, 3 and 4,
   so pulling its declaration into a token to share here would edit a rule this
   change has no business touching. If a third consumer appears, tokenise then. */
/* ── ONE FACE: BRICOLAGE GROTESQUE, EVERYWHERE ────────────────────────────────────
   There is no chip-face rule here any more, and its absence is the decision.
   2349:31504 sets rows 5-6 of Collaborations in Lexend, and 2347:25563 / 2347:25576 /
   2348:31491 set all of Col-3 in it. **That is a missed font change in Figma, not the
   spec** (user, 2026-08-18): the panel is Bricolage Grotesque throughout, and the same
   applies to any other node that shows Lexend.
   IT DID EXPLAIN A REAL SYMPTOM, which is worth keeping so the evidence is not re-read as
   proof of the wrong conclusion. "Diamond Supply Co." appears twice in Collaborations at
   84.321 and 86.321 wide — same string, same size, same padding — and the 2px is the face.
   The lengths in the NODE really do differ; they differ because the node is wrong. Rendering
   both in Bricolage makes them equal, which is correct, not a flattening. */

/* ── COL-3 IS ONE COLUMN, AND ITS THREE BOXES ARE ONE TREATMENT ────────────────────
   Re-pulled 2026-08-18 from 2347:4522: 2347:25563 (Personal Brand Ventures),
   2347:25576 (Brand influence) and 2348:31491 (Video style) are all `rounded-[8px]`,
   against Col-2's 16 — so the radius is a COLUMN property here, not a panel one, and
   .bw-ew-box's 16 is Col-2's alone.

   THE TITLES ARE ALL MEDIUM, AND THE NODE IS WRONG ABOUT TWO OF THEM. 2347:25563
   (Personal Brand Ventures) is Medium and is correct; 2347:25576 (Brand influence) and
   2348:31491 (Video style) read Light, and that is a FIGMA ERROR, not the spec (user,
   2026-08-18). All chip titles in this panel are Bricolage Grotesque Medium.
   SO THERE IS NO RULE HERE FOR EITHER WEIGHT OR FACE — the three inherit .bw-ew-boxtitle's
   500 and the screen's Bricolage with Col-2's title. "All titles are Medium, all of it
   Bricolage" is expressed once, where it applies to everything, rather than three times.
   RADIUS IS THE ONLY THING THIS COLUMN OVERRIDES, and it is the only part of the node these
   three boxes are believed on.
   DO NOT RE-PULL EITHER BACK. A future read of 2347:4522 will show Light on two of the three
   and Lexend on all of them; both are the node being out, and this note is the record. */
.bw-ew-box--ventures,
.bw-ew-box--influence,
.bw-ew-box--style {
  border-radius: 8px;
}

.bw-ew-chip {
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  height: 14.457px;
  padding: 0 4.66px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.6);
  box-shadow:
    inset 0 0 10px 0 rgba(255, 255, 255, 0.3),
    inset -1px -2px 2px 0 rgba(255, 255, 255, 0.1),
    inset 1px 1px 2px 0 rgba(255, 255, 255, 0.3);
  font-size: 8px;
  font-weight: 300;
  /* rgba(34,16,22,0.75) from 2346:2083 — the chips are the one thing in this panel that did
     NOT invert. They keep their pale rgba(255,255,255,0.6) fill, so their ink stays dark. */
  opacity: 0.8;
  color: rgba(34, 16, 22, 0.75);
  white-space: nowrap;
}

/* ── THE REEL, AND ITS WINDOW ──────────────────────────────────────────────────
   Rows 2 to 4 are the same reel: six equal thumbnails on equal gaps. One set of
   tokens defines that, and the window is derived from them rather than stated, so a
   change to the tile or the gap moves the clip with it.

   THE WINDOW IS WHY: nothing between a tile and the panel clipped anything, and the
   panel's own overflow sits 24 further out — that is .bw-ew-inner's padding — so a
   tile pushed past the row's edge still painted inside the panel. Measured, the
   swapped-out first thumbnail left 20.0px of itself showing in the left margin after
   the strip shifted, and the seventh showed 49.2px on the right before it.

   IT CANNOT GO ON THE STRIP. The strip is the element the swap translates, so its box
   travels with its own children — measured mid-swap, the tile that should have gone
   was still 150 of 150 inside it. The clip has to sit on something static, which is
   the section. */
.bw-ew-sec {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: var(--bw-reel);
  overflow: hidden;
}
.bw-ew-sechead { display: flex; align-items: center; gap: 8px; }
.bw-ew-sectitle { font-size: 10px; font-weight: 400; color: #fbf5f2; }
.bw-ew-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2px 4px;
  border: 0.25px solid #928686;
  border-radius: 8px;
  font-size: 8px;
  font-weight: 300;
  color: #928686;
}
/* THE ADD CONTROL IS NOT A PILL — Icon-add 2204:11473 is a bare 9 x 9 sitting at y2.5
   in the 14-tall row, on the same 8px gap as the two text pills. It was inheriting
   .bw-ew-pill's 0.25 #776868 border and drawing a SECOND ring around the one the asset
   already carries (its own `rect rx=4.375 stroke=#776868 stroke-width=0.25`) — the
   circle-inside-a-circle. The asset's ring is the real one and is left untouched.

   THE 2px PADDING GOES WITH IT, and not as tidying: with no border and no ground the
   padding is invisible in itself, but flex measures the gap from the padded box, so it
   was pushing the circle to 10 from "women" where the node has 8. Removing only the
   border would have left that 2 behind with nothing left to explain it. */
.bw-ew-pill--add { padding: 0; border: 0; }
.bw-ew-pill--add img { display: block; width: 9px; height: 9px; }
.bw-ew-strip { display: flex; gap: var(--bw-tile-gap); }
.bw-ew-tile {
  position: relative;
  display: block;
  flex-shrink: 0;
  width: var(--bw-tile-w);
  aspect-ratio: 2 / 1;
  overflow: hidden;
}
.bw-ew-tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* THE NODE FRAMES EACH TILE WITH A NESTED BOX, NOT A CROP — an inner absolutely
   positioned image taller than its 82.5 window with a negative top. Converted to
   object-position, which is the same crop expressed once: y% = -top / (imgH - boxH).
   The "More" row's six all differ; the twelve other-skateboarders tiles all share
   the node's top-left anchor (left 0.21 / top 0.28), so they take the default. */
.bw-ew-tile--m1 img { object-position: 50% 65.1%; }
.bw-ew-tile--m2 img { object-position: 50% 38.4%; }
.bw-ew-tile--m3 img { object-position: 0 50%; }
.bw-ew-tile--m4 img { object-position: 50% 28.1%; }
.bw-ew-tile--m5 img { object-position: 50% 86.7%; }
.bw-ew-tile--m6 img { object-position: 50% 25.2%; }
/* 2192:7556 crops a 101.512-tall image into the 82.5 box at top -5.21, which is
   5.21 / (101.512 - 82.5) = 27.4% — the same conversion the other six use. */
.bw-ew-tile--m7 img { object-position: 50% 27.4%; }

/* ── PART II — THE ALTERNATE CLIP'S HOVER STATE (2192:5708) ────────────────────
   The same three-control pattern as the clip's own hover, on the first More tile:
   the 30% #FF3567 wash on the picture and the controls in front of it. Paint order is
   stated for the same reason it is stated there — these all take an opacity from the
   timeline, and an implicit order is what put the controls under the wash last time. */
.bw-ew-tile { isolation: isolate; }
.bw-alt-tint {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: rgba(255, 53, 103, 0.3);
  opacity: 0;
  pointer-events: none;
}
/* Frame 48098385 — 124 x 24 at 13.734 / 28.549 in the 150 x 82.5 tile. */
.bw-alt-actions {
  position: absolute;
  left: 13.734px;
  top: 28.549px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 8px;
  opacity: 0;
  pointer-events: none;
}
/* The strip's own `.bw-ew-tile img { width:100%; height:100% }` would blow these up to
   the full tile, exactly as .bw-thumb img does to the clip's controls. Same fix, same
   reason: two classes beat one. */
.bw-ew-tile .bw-alt-act { display: block; flex-shrink: 0; width: 24px; height: 24px; }
/* Same as .bw-clip-act--edit — see the tuck note there. */
.bw-alt-swap {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  gap: 4px;
  box-sizing: border-box;
  width: 60px;
  height: 24px;
  padding: 1.398px 2.796px;
  border-radius: 32px;
  background: #2e2225;
}
/* Brown at rest and white on the click, and the glyph gets there the way the Edit
   button's does — declared at its identity so the two filter lists interpolate. The
   exported asset is white, which is the guide's CLICKED state; it is recoloured to the
   rest brown in the file itself. */
.bw-ew-tile .bw-alt-swap img {
  display: block;
  flex-shrink: 0;
  width: 8.906px;
  height: 10px;
  filter: brightness(1) invert(0);
}
.bw-alt-swap span {
  font-size: 11px;
  font-weight: 400;
  line-height: 1;
  color: #776868;
  white-space: nowrap;
}
/* The clip that replaces the original, stacked in f0 UNDER the tint so the wash still
   sits on top of whichever picture is showing. */
.bw-ew-f-alt {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  object-fit: cover;
}
/* THE SWAPPED-IN CLIP KEEPS THE CROP IT ARRIVED WITH. Frame 1 and More tile 1 are the
   same 150 x 82.5 box showing the same photograph, so anything other than the same
   object-position shows a different part of it — measured, the tile sits at 50% 65.1%
   and this was taking the default 50% 50%, which walked the picture 15% of its own
   height the moment it swapped in. The other frames have no tile counterpart and keep
   the centred crop the card gives its own stills. */
.bw-ew-f--1 .bw-ew-f-alt { object-position: 50% 65.1%; }
.bw-ew-strip--named .bw-ew-tile img { object-position: 50% 0; }
.bw-ew-named { display: flex; flex-direction: column; flex-shrink: 0; width: var(--bw-tile-w); }
.bw-ew-name {
  display: flex;
  align-items: center;
  height: 17px;
  font-size: 8px;
  font-weight: 400;
  opacity: 0.8;
  color: #928686;
}

/* prompt 2189:3706 — CENTRED ON THE PANEL, PARKED AT ITS BOTTOM.
   The gap under it is AUTHORED, not read: neither guide states one. 2178:6646 puts
   the bar at an absolute y544, which hangs it 20px past a 560-tall panel; 2204:11542
   centres it and pins it at `bottom: 1px`, effectively flush. Ten is the middle of
   the 8-12 the brief asks for, and it is the only number in this rule that is not
   the node's — so if the guides ever state one, this is what it replaces.
   Centring is by transform rather than by a computed left, so it survives the panel
   width changing; the node's own 294.408 was (997.164 - 600) / 2 rounded, i.e. the
   same intent expressed as a constant. */
.bw-ew-prompt {
  position: absolute;
  left: 50%;
  /* 10 -> 16 (user, 2026-08-24: the field "looks flush with the bottom edge of the Edit
     panel"). MEASURED, and matched to the panel's OWN inset rather than nudged: at 10 the
     painted gap was 11.00px, while .bw-ew-icons sits 16 authored / 17.60 painted from the
     top of the same panel. 16 makes the panel's top and bottom insets agree, so the
     number is the one already in use here rather than a new one.
     AUTHORED px, NOT PAINTED: .bw-screen renders at 1.10, so this pays out as 17.60 —
     the same painted inset the icons already have. Writing 16 painted here would mean
     14.55 authored and would not match anything. */
  bottom: 16px;
  transform: translateX(-50%);
  box-sizing: border-box;
  width: 600px;
  height: 36px;
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* WHITE AND GLASS, from 2351:37609 — this bar was #FBF5F2 behind a 0.25 #FF3567 keyline,
     which was the cream panel's treatment and became the last stranded cream on a #0F0F0F
     ground. The node gives it a 1px WHITE edge over an 80% white ground, so it reads as a
     lit input sitting on the dark panel rather than as a leftover surface.
     AND IT TAKES THE CHIP'S SHADOW, NOT --bw-glass-shadow. The token is the two-part
     container edge (1px/1px and -1px/-2px); 2351:37609 carries the three-part CHIP glass,
     which adds the `inset 0 0 10px` bloom. Same three lines .bw-ew-chip states, restated
     here rather than tokenised — the two are the same treatment today and there is no node
     saying they must stay that way. */
  border: 1px solid #ffffff;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.8);
  box-shadow:
    inset 0 0 10px 0 rgba(255, 255, 255, 0.3),
    inset -1px -2px 2px 0 rgba(255, 255, 255, 0.1),
    inset 1px 1px 2px 0 rgba(255, 255, 255, 0.3);
}
.bw-ew-prompt-l { display: flex; align-items: center; gap: 8px; }
.bw-ew-prompt-l img { display: block; width: 11.336px; height: 11.336px; }
/* Bricolage with the rest of the panel. The node sets this one string in Lexend; that is
   the same missed font change as the chips' — see the note on .bw-ew-chip. Inherits the
   screen's stack rather than restating it. */
.bw-ew-prompt-l span {
  /* 10px, down from the node's 12. Dropped on the brief rather than measured off
     2204:11539 — the placeholder was reading heavier than the panel's own captions,
     which sit at 10 and 12 and are what it is seen beside. */
  font-size: 10px;
  font-weight: 300;
  opacity: 0.8;
  /* #221016 (2351:37614), up from #776868 — the ground went from cream to 80% white, so the
     placeholder had to go with it or it would sit mid-grey on near-white. The node also
     states 11px here; the 10 above is the brief's own reduction from the old node's 12 and
     is LEFT ALONE, because that was a decision rather than a measurement. */
  color: #221016;
}
.bw-ew-prompt-r { display: block; width: 13.5px; height: 13.5px; }
