/**
 * Becom Design Tokens
 * ===================
 *
 * Four levels. Each level may ONLY reference the level above it.
 *
 *   L1  primitives   raw values. The ONLY place a literal may appear.
 *   L2  brand        assigns primitives to brand meaning (+ composite effects).
 *   L3  mapped       bg / content / border roles. What components consume.
 *   L4  component    per-component tokens, added only where L3 is ambiguous.
 *
 * Cross-use of an L3 role is forbidden: a `content-*` token may never paint a
 * background, a `bg-*` token may never colour text, a `border-*` token may
 * never do either. See DESIGN-RULES.md §1 for the accepted idioms.
 *
 * Values ported faithfully from becom.digital (Lovable/shadcn build, 2026-09).
 * Colour space is oklch throughout, matching the source.
 */

:root {
  /* ══════════════════════════════════════════════════════════════════
     LEVEL 1 — PRIMITIVES
     Literals live here and nowhere else.
     ══════════════════════════════════════════════════════════════════ */

  /* >>> RAMPS L1 (generated) */
  /* Ramps are generated by scripts/build-ramps.mjs — do not hand-edit.
     Even lightness steps in OKLCH, one curve for every family, each
     anchored on a colour measured off becom.digital. Authored in oklch
     so wide-gamut displays get the real value; the hex in each comment
     is the sRGB rendering, for comparing against a comp. */

  /* ── Slate — anchored at 700: the site's body-copy grey — purple-cast, not true neutral ── */
  --bc-color-slate-0:        oklch(100.0% 0 282.5);         /* #ffffff */
  --bc-color-slate-50:       oklch(98.8% 0.0056 282.5);     /* #fafbff */
  --bc-color-slate-100:      oklch(97.6% 0.0085 282.5);     /* #f6f6fd */
  --bc-color-slate-200:      oklch(95.6% 0.0127 282.5);     /* #eff0f9 */
  --bc-color-slate-300:      oklch(91.6% 0.0155 282.5);     /* #e1e2ee */
  --bc-color-slate-400:      oklch(84.5% 0.0197 282.5);     /* #cacbd9 */
  --bc-color-slate-500:      oklch(77.4% 0.0226 282.5);     /* #b3b4c4 */
  --bc-color-slate-600:      oklch(54.9% 0.0254 282.5);     /* #6f7080 */
  --bc-color-slate-700:      oklch(41.9% 0.0282 282.5);     /* #4a4b5c */
  --bc-color-slate-800:      oklch(32.9% 0.0282 282.5);     /* #333343 */
  --bc-color-slate-900:      oklch(24.9% 0.0268 282.5);     /* #1f202e */
  --bc-color-slate-950:      oklch(18.0% 0.0254 282.5);     /* #10101c */

  /* ── Purple — anchored at 700: the brand book's Purple ── */
  --bc-color-purple-0:       oklch(100.0% 0 288.3);         /* #ffffff */
  --bc-color-purple-50:      oklch(98.6% 0.0151 288.3);     /* #faf9ff */
  --bc-color-purple-100:     oklch(97.1% 0.0252 288.3);     /* #f4f3ff */
  --bc-color-purple-200:     oklch(95.0% 0.0454 288.3);     /* #eceaff */
  --bc-color-purple-300:     oklch(92.3% 0.0706 288.3);     /* #e3dfff */
  --bc-color-purple-400:     oklch(85.4% 0.1562 288.3);     /* #cbbdff */
  --bc-color-purple-500:     oklch(72.7% 0.252 288.3);      /* #a67fff */
  --bc-color-purple-600:     oklch(59.0% 0.2419 288.3);     /* #7f53ff */
  --bc-color-purple-700:     oklch(47.1% 0.2167 288.3);     /* #5e32ca */
  --bc-color-purple-750:     oklch(44.3% 0.2249 292.1);     /* #5e1dc1 — off-curve, see below */
  --bc-color-purple-800:     oklch(37.8% 0.1915 288.3);     /* #451a9e */
  --bc-color-purple-900:     oklch(30.9% 0.1663 288.3);     /* #33097c */
  --bc-color-purple-950:     oklch(20.4% 0.131 288.3);      /* #1b004d */
  /* Step 750 is kept from becom.digital, off the generated
     curve on purpose: the brand book supersedes it for the role tokens, but
     the measured website value stays addressable. */

  /* ── Green — anchored at 500: the brand book's Green ── */
  --bc-color-green-0:        oklch(100.0% 0 157);           /* #ffffff */
  --bc-color-green-50:       oklch(98.8% 0.0118 157);       /* #f5fef8 */
  --bc-color-green-100:      oklch(97.5% 0.0197 157);       /* #ecfbf1 */
  --bc-color-green-200:      oklch(95.6% 0.0354 157);       /* #def8e7 */
  --bc-color-green-300:      oklch(93.2% 0.055 157);        /* #ccf4da */
  --bc-color-green-400:      oklch(88.0% 0.1218 157);       /* #8ff0b7 */
  --bc-color-green-500:      oklch(82.5% 0.1965 157);       /* #00ea90 */
  --bc-color-green-550:      oklch(77.9% 0.2001 149.9);     /* #31d96d — off-curve, see below */
  --bc-color-green-600:      oklch(73.9% 0.1886 157);       /* #00cc78 */
  --bc-color-green-700:      oklch(57.9% 0.169 161);        /* #009757 */
  --bc-color-green-800:      oklch(39.8% 0.1493 164);       /* #005d30 */
  --bc-color-green-900:      oklch(31.2% 0.1297 165);       /* #00431f */
  --bc-color-green-950:      oklch(22.7% 0.1022 165);       /* #00290f */
  /* Step 550 is kept from becom.digital, off the generated
     curve on purpose: the brand book supersedes it for the role tokens, but
     the measured website value stays addressable. */

  /* ── Red — anchored at 600: the source's --destructive ── */
  --bc-color-red-0:          oklch(100.0% 0 27);            /* #ffffff */
  --bc-color-red-50:         oklch(98.5% 0.0138 27);        /* #fff7f5 */
  --bc-color-red-100:        oklch(96.8% 0.0229 27);        /* #ffefec */
  --bc-color-red-200:        oklch(94.5% 0.0413 27);        /* #ffe3de */
  --bc-color-red-300:        oklch(91.5% 0.0642 27);        /* #ffd3cc */
  --bc-color-red-400:        oklch(83.0% 0.1421 27);        /* #ffa195 */
  --bc-color-red-500:        oklch(74.0% 0.2292 27);        /* #ff5e55 */
  --bc-color-red-600:        oklch(60.0% 0.22 27);          /* #e62c2c */
  --bc-color-red-700:        oklch(48.0% 0.1971 27);        /* #b20010 */
  --bc-color-red-800:        oklch(38.0% 0.1742 27);        /* #880000 */
  --bc-color-red-900:        oklch(28.0% 0.1513 27);        /* #5f0000 */
  --bc-color-red-950:        oklch(19.0% 0.1192 27);        /* #390000 */
  /* <<< RAMPS L1 */

  /* ── Spacing — 4pt grid ── */
  --bc-space-0:     0;
  --bc-space-px:    1px;
  --bc-space-0-5:   0.125rem;  /*  2px */
  --bc-space-1:     0.25rem;   /*  4px */
  --bc-space-1-5:   0.375rem;  /*  6px */
  --bc-space-2:     0.5rem;    /*  8px */
  --bc-space-2-5:   0.625rem;  /* 10px — off-grid, kept for nav-link inline padding */
  --bc-space-3:     0.75rem;   /* 12px */
  --bc-space-4:     1rem;      /* 16px */
  --bc-space-5:     1.25rem;   /* 20px */
  --bc-space-6:     1.5rem;    /* 24px */
  --bc-space-7:     1.75rem;   /* 28px */
  --bc-space-8:     2rem;      /* 32px */
  --bc-space-9:     2.25rem;   /* 36px — the avatar */
  --bc-space-10:    2.5rem;    /* 40px */
  --bc-space-11:    2.75rem;   /* 44px — the button box, squared */
  --bc-space-12:    3rem;      /* 48px */
  --bc-space-14:    3.5rem;    /* 56px — the solid icon tile */
  --bc-space-16:    4rem;      /* 64px */
  --bc-space-20:    5rem;      /* 80px */
  --bc-space-24:    6rem;      /* 96px */
  --bc-space-28:    7rem;      /* 112px */
  --bc-space-32:    8rem;      /* 128px */
  --bc-space-40:    10rem;     /* 160px */

  /* ── Radius ──
     Five steps, each with a job. The source also uses 8, 12 and 24px, but no
     component here needs 8 or 12, and an unused scale step is a decision waiting
     to be made inconsistently. Add one back through the recipe when a section
     actually needs it, not in advance. ── */
  --bc-radius-sm:   0.5rem;    /*  8px — tags                     */
  --bc-radius-md:   0.625rem;  /* 10px — nav links, inputs        */
  --bc-radius-xl:   1rem;      /* 16px — rows, tiles, inner cards */
  --bc-radius-2xl:  1.25rem;   /* 20px — cards, the default       */
  --bc-radius-3xl:  1.5rem;    /* 24px — full-width banner panels */
  --bc-radius-full: 9999px;    /*      — buttons, pills, avatars  */

  /* ── Font families ── */
  --bc-font-family-sans: "Open Sans", "Open Sans Fallback", system-ui, sans-serif;
  --bc-font-family-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ── Font sizes ── */
  --bc-font-size-2xs: 0.6875rem; /* 11px */
  --bc-font-size-xs:  0.75rem;   /* 12px */
  --bc-font-size-sm:  0.875rem;  /* 14px */
  --bc-font-size-md:  1rem;      /* 16px */
  --bc-font-size-lg:  1.125rem;  /* 18px */
  --bc-font-size-xl:  1.5rem;    /* 24px */
  --bc-font-size-2xl: 1.875rem;  /* 30px */
  --bc-font-size-3xl: 2.25rem;   /* 36px */
  --bc-font-size-4xl: 3rem;      /* 48px */
  --bc-font-size-5xl: 4.5rem;    /* 72px — md hero */
  --bc-font-size-6xl: 6rem;      /* 96px — lg hero */

  /* Display sizes interpolate where the source stepped at breakpoints, because
     theme.json element styles cannot carry a media query. Tuned to hit the
     source's md (768) and lg (1280) values exactly; mobile runs a few px large. */
  --bc-font-size-display-lg: clamp(3rem, 4.7vw + 2.25rem, 6rem);      /* 48 → 96 */
  --bc-font-size-display-md: clamp(2.25rem, 2.34vw + 1.125rem, 3rem); /* 36 → 48 */

  /* ── Font weights — the source uses four. ── */
  --bc-font-weight-regular:  400;
  --bc-font-weight-medium:   500;
  --bc-font-weight-semibold: 600;
  --bc-font-weight-bold:     700;

  /* ── Line heights ── */
  --bc-leading-none:    1;
  --bc-leading-tight:   0.95;
  --bc-leading-snug:    1.25;
  --bc-leading-normal:  1.5;
  --bc-leading-relaxed: 1.625;
  --bc-leading-control:  1.4286;  /* 14px text -> 20px box, giving a 44px control */

  /* ── Letter spacing ── */
  --bc-tracking-tight:   -0.02em;
  --bc-tracking-normal:  0;
  --bc-tracking-wide:    0.1em;
  --bc-tracking-wider:   0.15em;
  --bc-tracking-widest:  0.18em;

  /* ── Layout ── */
  --bc-size-container:  80rem;   /* 1280px — max-w-7xl */
  --bc-size-content:    45rem;   /* 720px */
  --bc-size-content-wide: 64rem; /* 1024px — hero / centred copy column */
  /* 896px — max-w-4xl. The source holds a standalone panel narrower than the
     page: the contact band's container. Its 24px of inline padding sits INSIDE
     that width, so the panel itself measures 848 — see --bc-person-band-max. */
  --bc-size-band:       56rem;
  --bc-size-media:      22rem;   /* 352px — the media card, measured */
  /* 384px — max-w-sm. A short standalone paragraph, held to a measure of its
     own: the footer's mission sentence. Not one of the four CONTAINER widths
     above — it is the paragraph measure --bc-lead-measure is, one step down. */
  --bc-size-copy:       24rem;
  --bc-size-border:     1px;
  /* The blog card's image, measured off /nieuws — aspect-[3/2]. A ratio rather
     than a height, so the image keeps its shape at every column width. */
  --bc-ratio-media:     3 / 2;

  /* ── Motion ── */
  --bc-duration-fast:   150ms;
  --bc-duration-normal: 250ms;
  --bc-duration-slow:   400ms;
  --bc-ease-standard:   cubic-bezier(0.4, 0, 0.2, 1);
  /* The source's CTA easing — a hard decelerate, used for lift and shine. */
  --bc-ease-emphasis:   cubic-bezier(0.22, 1, 0.36, 1);
  --bc-duration-lift:   220ms;
  --bc-duration-glow:   280ms;
  --bc-duration-shine:  700ms;
  --bc-duration-wipe:   340ms;
  --bc-duration-card:   320ms;   /* the source's .card-interactive */
  --bc-lift-card:       -4px;
  --bc-blur-glass:      12px;
  --bc-duration-image:  700ms;
  --bc-scale-image:     1.05;
  /* The icon tile's own motion: it lifts and cants a little rather than
     simply growing, which is what stops it reading as a scaled picture. */
  --bc-duration-tile:   500ms;
  --bc-scale-tile:      1.05;
  --bc-rotate-tile:     -4deg;

  /* ── Interaction geometry ── */
  --bc-lift-hover:      -2px;
  --bc-scale-hover:     1.02;
  --bc-scale-active:    0.99;
  --bc-saturate-hover:  1.05;
  /* Full desaturation, for a portrait that names someone rather than pictures
     them — the board grid. A bare amount, like the two above it, so the filter
     function is composed at level 4 where the decision is. */
  --bc-grayscale-muted: 1;
  --bc-ring-width:      2px;
  --bc-ring-offset:     4px;
  --bc-ease-out:        cubic-bezier(0, 0, 0.2, 1);


  /* ══════════════════════════════════════════════════════════════════
     LEVEL 2 — BRAND
     Primitives given brand meaning. Composite effects assembled here.
     ══════════════════════════════════════════════════════════════════ */

  /* >>> RAMPS L2 (generated) */
  /* Level 1 names the COLOUR (purple, green, red); level 2 names the ROLE
     it plays (neutral, accent, danger). Same twelve steps, one-to-one. */

  /* ── brand-neutral — slate below 800, purple from 800 up ── */
  --bc-brand-neutral-0:      var(--bc-color-slate-0);
  --bc-brand-neutral-50:     var(--bc-color-slate-50);
  --bc-brand-neutral-100:    var(--bc-color-slate-100);
  --bc-brand-neutral-200:    var(--bc-color-slate-200);
  --bc-brand-neutral-300:    var(--bc-color-slate-300);
  --bc-brand-neutral-400:    var(--bc-color-slate-400);
  --bc-brand-neutral-500:    var(--bc-color-slate-500);
  --bc-brand-neutral-600:    var(--bc-color-slate-600);
  --bc-brand-neutral-700:    var(--bc-color-slate-700);
  --bc-brand-neutral-800:    var(--bc-color-purple-800);  /* the turn */
  --bc-brand-neutral-900:    var(--bc-color-purple-900);
  --bc-brand-neutral-950:    var(--bc-color-purple-950);

  /* ── brand-accent — CTAs, live indicators, eyebrows ── */
  --bc-brand-accent-0:       var(--bc-color-green-0);
  --bc-brand-accent-50:      var(--bc-color-green-50);
  --bc-brand-accent-100:     var(--bc-color-green-100);
  --bc-brand-accent-200:     var(--bc-color-green-200);
  --bc-brand-accent-300:     var(--bc-color-green-300);
  --bc-brand-accent-400:     var(--bc-color-green-400);
  --bc-brand-accent-500:     var(--bc-color-green-500);
  --bc-brand-accent-600:     var(--bc-color-green-600);
  --bc-brand-accent-700:     var(--bc-color-green-700);
  --bc-brand-accent-800:     var(--bc-color-green-800);
  --bc-brand-accent-900:     var(--bc-color-green-900);
  --bc-brand-accent-950:     var(--bc-color-green-950);

  /* ── brand-danger — destructive and error states ── */
  --bc-brand-danger-0:       var(--bc-color-red-0);
  --bc-brand-danger-50:      var(--bc-color-red-50);
  --bc-brand-danger-100:     var(--bc-color-red-100);
  --bc-brand-danger-200:     var(--bc-color-red-200);
  --bc-brand-danger-300:     var(--bc-color-red-300);
  --bc-brand-danger-400:     var(--bc-color-red-400);
  --bc-brand-danger-500:     var(--bc-color-red-500);
  --bc-brand-danger-600:     var(--bc-color-red-600);
  --bc-brand-danger-700:     var(--bc-color-red-700);
  --bc-brand-danger-800:     var(--bc-color-red-800);
  --bc-brand-danger-900:     var(--bc-color-red-900);
  --bc-brand-danger-950:     var(--bc-color-red-950);
  /* <<< RAMPS L2 */

  /* ── Gradients — brand expression, composed from primitives ── */
  --bc-gradient-inverse: radial-gradient(
    ellipse at top,
    var(--bc-brand-neutral-900) 0%,
    var(--bc-brand-neutral-950) 55%,
    var(--bc-brand-neutral-950) 100%
  );
  --bc-gradient-accent: linear-gradient(
    135deg,
    var(--bc-brand-accent-500) 0%,
    var(--bc-brand-accent-600) 100%
  );
  --bc-gradient-brand: linear-gradient(
    135deg,
    var(--bc-brand-neutral-900) 0%,
    color-mix(in oklab, var(--bc-brand-neutral-900) 70%, transparent) 100%
  );
  /* The scrim that makes text legible over a photograph. Three stops rather
     than the source two stacked gradients, which is the same effect with one
     paint. */
  --bc-gradient-scrim: linear-gradient(
    to top,
    color-mix(in oklab, var(--bc-brand-neutral-950) 95%, transparent) 0%,
    color-mix(in oklab, var(--bc-brand-neutral-950) 70%, transparent) 45%,
    color-mix(in oklab, var(--bc-brand-neutral-950) 20%, transparent) 100%
  );
  --bc-gradient-inverse-mesh:
    
    radial-gradient(at 20% 30%, color-mix(in oklab, var(--bc-color-purple-600) 35%, transparent) 0px, transparent 50%),
    radial-gradient(at 80% 20%, color-mix(in oklab, var(--bc-color-purple-500) 30%, transparent) 0px, transparent 50%),
    radial-gradient(at 50% 90%, color-mix(in oklab, var(--bc-color-purple-700) 35%, transparent) 0px, transparent 50%);

  /* ── Shadows — composed from primitives ── */
  --bc-shadow-xs: 0 1px 3px 0 color-mix(in oklab, var(--bc-brand-neutral-950) 10%, transparent),
                  0 1px 2px -1px color-mix(in oklab, var(--bc-brand-neutral-950) 10%, transparent);
  --bc-shadow-card: 0 8px 30px -10px color-mix(in oklab, var(--bc-brand-neutral-900) 12%, transparent);
  --bc-shadow-lifted: 0 20px 25px -5px color-mix(in oklab, var(--bc-brand-neutral-900) 10%, transparent),
                      0 8px 10px -6px color-mix(in oklab, var(--bc-brand-neutral-900) 10%, transparent);
  --bc-shadow-glow: 0 20px 60px -20px color-mix(in oklab, var(--bc-color-purple-600) 50%, transparent);
  --bc-shadow-accent: 0 12px 40px -12px color-mix(in oklab, var(--bc-brand-accent-500) 55%, transparent);
  /* The icon tile's drop. Not one of the card shadows: it is thrown by a 48px
     square onto whatever is directly behind it, so it is tight and dark rather
     than wide and soft. The source carries it on every solid tile. */
  --bc-shadow-tile: 0 8px 24px -8px color-mix(in oklab, var(--bc-brand-neutral-900) 55%, transparent);
  /* Text over a photograph. The scrim guarantees the average; these cover the
     bright patch that lands under one word. Two weights, measured off the
     source — the heading carries the heavier one. */
  --bc-shadow-text-strong: 0 2px 8px color-mix(in oklab, var(--bc-brand-neutral-950) 55%, transparent);
  --bc-shadow-text:        0 1px 4px color-mix(in oklab, var(--bc-brand-neutral-950) 55%, transparent);


  /* ══════════════════════════════════════════════════════════════════
     LEVEL 3 — MAPPED  ·  BACKGROUND
     Surfaces and fills only. Never text, never strokes.
     ══════════════════════════════════════════════════════════════════ */

  /* The neutral surface ladder. `sunken` sits closer to white than
     `sunken-deep`; both are recessed relative to `base`, and `elevated`
     (a card) rises above it. */
  --bc-bg-elevated:        var(--bc-brand-neutral-0);
  --bc-bg-base:            var(--bc-brand-neutral-50);
  --bc-bg-sunken:          var(--bc-brand-neutral-100);
  --bc-bg-sunken-deep:     var(--bc-brand-neutral-200);

  --bc-bg-accent:          var(--bc-brand-accent-500);
  /* The quiet accent surface. The solid one is a call to action and reads as
     one wherever it is put; a tag names a category and must not compete with
     the button beneath it. Text on it is --bc-content-on-accent, the same
     purple the solid accent carries: on a green surface the word is purple. */
  --bc-bg-accent-soft:     var(--bc-brand-accent-300);
  /* One rung paler than `soft`, and it exists for a state rather than a
     surface: the Filter's hover, which has to read as a *preview* of the
     selected fill without being mistaken for it. Two steps of separation is
     what keeps "about to pick this" and "picked" apart at a glance. */
  --bc-bg-accent-subtle:   var(--bc-brand-accent-100);
  --bc-bg-accent-gradient: var(--bc-gradient-accent);
  --bc-bg-danger:          var(--bc-brand-danger-600);
  /* A scrim laid over content — modal and drawer backdrops. */
  --bc-bg-overlay:          color-mix(in oklab, var(--bc-brand-neutral-950) 60%, transparent);

  /* The dark half of the surface ladder. Same words as the light half, same
     order: elevated rises, base is the ground, sunken recedes. On a dark
     ground elevation reads as LIGHTER, so the raised step is a white wash
     rather than a darker step. */
  --bc-bg-inverse-elevated: color-mix(in oklab, var(--bc-brand-neutral-0) 6%, transparent);
  /* The same wash, strong enough to read over a photograph. `elevated` is
     measured against a flat dark ground and is nearly invisible over an image,
     which is the same problem the scrim solves for text: an uncontrolled
     photograph carries no contrast guarantee. Used by the media card's action.

     `-lit` is the pointed-at step. The three make one ladder and a hover moves
     one rung up it: an outline button on a flat dark ground goes
     `elevated` → `glass`, and the media card's, which starts at `glass`, goes
     `glass` → `glass-lit`. The source doubles its own wash on hover (5→10,
     10→20, 20→30); collapsing that to a ladder is the same normalisation the
     white text alphas get, and it is why there is no fourth alpha here. */
  --bc-bg-inverse-glass:     color-mix(in oklab, var(--bc-brand-neutral-0) 20%, transparent);
  --bc-bg-inverse-glass-lit: color-mix(in oklab, var(--bc-brand-neutral-0) 30%, transparent);
  --bc-bg-inverse-base:     var(--bc-brand-neutral-900);
  --bc-bg-inverse-sunken:   var(--bc-brand-neutral-950);

  /* A gradient surface for the inverse side, exactly parallel to
     --bc-bg-accent-gradient. Used by the hero, the CTA panel and anything else
     that wants the dark brand wash — it is not hero-specific. */
  --bc-bg-inverse-gradient: var(--bc-gradient-inverse);
  --bc-bg-inverse-mesh:     var(--bc-gradient-inverse-mesh);


  /* ══════════════════════════════════════════════════════════════════
     LEVEL 3 — MAPPED  ·  CONTENT
     Text and icons only. Never a surface, never a stroke.
     ══════════════════════════════════════════════════════════════════ */

  /* Purple leads. Every section h2/h3 on becom.digital is #38007d, so this
     is the primary content colour — not a brand accent applied on top of a
     neutral one. */
  --bc-content-primary:    var(--bc-brand-neutral-900);
  --bc-content-secondary:  var(--bc-brand-neutral-700);
  --bc-content-tertiary:   var(--bc-brand-neutral-600);
  --bc-content-accent:     var(--bc-brand-accent-800);
  --bc-content-danger:     var(--bc-brand-danger-700);
  /* The lit state — a link under the pointer, and nothing else so far.
     brand-neutral is slate at 600, so like the focus ring this reaches the
     purple ramp directly; see §1 of DESIGN-RULES. One step darker than the
     focus ring: this is text, and 700 reads at 8.67:1 on white where 600 is
     5.10:1. It is still three times the luminance of content-primary, so it
     lights up. */
  --bc-content-primary-hover: var(--bc-color-purple-700);

  /* Text placed on a filled brand / accent / danger surface. */
  --bc-content-on-accent:  var(--bc-content-primary);
  /* The accent green as text, on a dark surface — the hero's full stop. */
  --bc-content-accent-on-inverse: var(--bc-brand-accent-500);
  --bc-content-on-danger:  var(--bc-brand-neutral-0);

  /* Text placed on an inverse (dark) surface. */
  --bc-content-inverse:           var(--bc-brand-neutral-0);
  --bc-content-inverse-secondary: color-mix(in oklab, var(--bc-brand-neutral-0) 85%, transparent);
  --bc-content-inverse-tertiary:  color-mix(in oklab, var(--bc-brand-neutral-0) 75%, transparent);


  /* ══════════════════════════════════════════════════════════════════
     LEVEL 3 — MAPPED  ·  BORDER
     Strokes, dividers, focus rings. Never a surface, never text.
     ══════════════════════════════════════════════════════════════════ */

  --bc-border-default:  var(--bc-brand-neutral-300);
  --bc-border-weak:     var(--bc-brand-neutral-200);
  --bc-border-strong:   var(--bc-brand-neutral-500);
  --bc-border-accent:   var(--bc-brand-accent-500);
  /* The accent hairline that pairs with the *soft* accent surface. `accent` is
     the brand green at full chroma, which is right around a vivid fill and
     shouts around a quiet one — a 300 ground under a 500 edge reads as two
     different greens rather than as one component. This is the edge for
     anything wearing `bg-accent-soft` or `bg-accent-subtle`. */
  --bc-border-accent-soft: var(--bc-brand-accent-400);
  --bc-border-danger:   var(--bc-brand-danger-600);
  /* The vivid purple, not the flat brand one. brand-neutral is slate at 600,
     so these three reach the purple ramp directly — the only level-3 tokens
     that do, and the wiring view lists them as such. */
  --bc-border-focus:    var(--bc-color-purple-600);

  /* Strokes on an inverse background. */
  --bc-border-inverse-weak:   color-mix(in oklab, var(--bc-brand-neutral-0) 10%, transparent);
  --bc-border-inverse:        color-mix(in oklab, var(--bc-brand-neutral-0) 15%, transparent);
  --bc-border-inverse-strong: color-mix(in oklab, var(--bc-brand-neutral-0) 30%, transparent);


  /* ══════════════════════════════════════════════════════════════════
     LEVEL 4 — COMPONENT
     Added ONLY where an L3 token cannot express the decision on its own.
     Every value below is a var() onto L2/L3 — never a literal.
     ══════════════════════════════════════════════════════════════════ */

  /* ── Button ── */
  --bc-button-radius:            var(--bc-radius-full);
  --bc-button-padding-block:     var(--bc-space-3);
  --bc-button-padding-inline:    var(--bc-space-6);
  --bc-button-font-size:         var(--bc-font-size-sm);
  --bc-button-font-weight:       var(--bc-font-weight-semibold);
  --bc-button-line-height:       var(--bc-leading-control);

  /* Interaction, ported from the source's .cta-shine: a lift with a shine
     sweeping across, not a link underline. */
  --bc-button-transition:        transform var(--bc-duration-lift) var(--bc-ease-emphasis),
                                 box-shadow var(--bc-duration-glow),
                                 filter var(--bc-duration-lift);
  --bc-button-hover-transform:   translateY(var(--bc-lift-hover)) scale(var(--bc-scale-hover));
  --bc-button-hover-filter:      saturate(var(--bc-saturate-hover));
  --bc-button-active-transform:  scale(var(--bc-scale-active));
  /* The sweep comes in two colours, and a button's own ground picks one. A
     highlight is light on a dark ground and dark on a light one; one colour for
     both means half the buttons carry a sweep they cannot show — the same
     failure as one that was never applied, and harder to notice.

     A quarter, not a half. The first guess was that a dark wash reads about
     twice as strongly as the same alpha of white and so should be halved; put
     side by side against the primary's sweep, 14% was still a visible lavender
     band where the white one is a pass of light. 7% is where the two weigh the
     same. Rendered and compared rather than reasoned about — the rule of thumb
     was wrong by a factor of two, and only the picture said so.

     Both are rebound onto --bc-button-shine, never painted directly — a button
     has one sweep, and its ground says which. */
  --bc-button-shine-light:       linear-gradient(120deg,
                                   transparent 30%,
                                   color-mix(in oklab, var(--bc-brand-neutral-0) 28%, transparent) 50%,
                                   transparent 70%);
  --bc-button-shine-dark:        linear-gradient(120deg,
                                   transparent 30%,
                                   color-mix(in oklab, var(--bc-brand-neutral-900) 7%, transparent) 50%,
                                   transparent 70%);
  /* The default, for the two variants with a dark fill of their own — primary's
     accent gradient and secondary's solid purple. Both are picked from the
     block's Colour panel and so have no class to hang a rebinding on, which is
     why theirs is the default rather than a third named token. */
  --bc-button-shine:             var(--bc-button-shine-light);
  --bc-button-shine-transition:  transform var(--bc-duration-shine) var(--bc-ease-emphasis);
  --bc-button-focus-shadow:      0 0 0 var(--bc-ring-width) var(--bc-bg-base),
                                 0 0 0 var(--bc-ring-offset)
                                   color-mix(in oklab, var(--bc-border-focus) 60%, transparent);

  --bc-button-primary-bg:        var(--bc-bg-accent-gradient);
  --bc-button-primary-content:   var(--bc-content-on-accent);
  --bc-button-primary-border:    transparent;
  --bc-button-primary-shadow:    var(--bc-shadow-glow);

  /* Secondary — the solid purple button. Not an accent CTA and not an outline:
     it is the workhorse action, "Alle actualiteit" / "Bekijk volledige kalender". */
  --bc-button-secondary-bg:      var(--bc-bg-inverse-base);
  --bc-button-secondary-content: var(--bc-content-inverse);
  --bc-button-secondary-border:  transparent;
  --bc-button-secondary-shadow:  var(--bc-shadow-card);

  /* Secondary on a dark surface inverts to the light one: an elevated white
     fill carrying the purple. */
  --bc-button-secondary-inverse-bg:      var(--bc-bg-elevated);
  --bc-button-secondary-inverse-content: var(--bc-content-primary);
  --bc-button-secondary-inverse-border:  transparent;
  --bc-button-secondary-inverse-shadow:  var(--bc-shadow-card);

  /* Outline, on a light surface — a hole in the page, and what the button
     actually reads on either half: a dark section rebinds these two to the
     inverse pair below, the same move the card and the link make. */
  --bc-button-outline-bg:        transparent;
  --bc-button-outline-bg-hover:  var(--bc-bg-sunken);
  --bc-button-outline-blur:      0px;
  /* Dark, because an outline button has no fill of its own: its ground is the
     section's, and on this half that is light. A white sweep here is white on
     the page's own white, which is what this button had — invisibly. */
  --bc-button-outline-shine:     var(--bc-button-shine-dark);
  --bc-button-outline-content:   var(--bc-content-primary);
  --bc-button-outline-border:    var(--bc-border-default);

  /* Outline, on a dark surface — the hero's second CTA. Same axes as the card:
     the variant changes colour only, and geometry is shared above.

     On the dark half the outline button is glass, not a hole. Every one of the
     source's four — the hero's second CTA, the wiki panel's, the CTA band's and
     the media card's — carries a translucent white wash behind its hairline and
     a backdrop blur; the port dropped all four and left `transparent`, which is
     a different component. The source's washes are 5/10/20%: the first two are
     the same decision made twice and collapse to `bg-inverse-elevated`, exactly
     as the four white text alphas collapse to three. The 20% is not — it sits
     over a photograph, and the media card rebinds it. */
  --bc-button-outline-inverse-bg:       var(--bc-bg-inverse-elevated);
  --bc-button-outline-inverse-bg-hover: var(--bc-bg-inverse-glass);
  --bc-button-outline-inverse-blur:     var(--bc-blur-glass);
  /* Light, for the same reason the other is dark: the ground is the dark
     section it sits on. Swapped in by the dark-context list in chrome.css,
     beside the -bg / -bg-hover / -blur it already swaps. */
  --bc-button-outline-inverse-shine:    var(--bc-button-shine-light);
  --bc-button-outline-inverse-content: var(--bc-content-inverse);
  --bc-button-outline-inverse-border:  var(--bc-border-inverse-strong);

  /* ── Link ──
     One component, one hover, and a single boolean.

     Colour at rest comes from the surface, never from a choice: purple on the
     light half, white on the dark half. The only thing a variant decides is
     whether the underline is already there when nobody is pointing at it — and
     that boolean is also what tells a forward link from a back link.

     Hover is identical for every one of them: the accent underline is drawn
     left to right, and the text lights up. Underneath there is one mechanism —
     two background layers on the link itself:

       rest layer    the underline at rest, held at full width
       accent layer  the accent underline, wiped in from the left on hover

     A variant is two values: what colour the rest layer is, and whether the
     accent layer starts at full width. Everything else is shared.

         variant      rest layer     accent layer at rest
         inline       currentColor   0    (green wipes over the purple)
         standalone   —              100% (green already drawn; replays)
         back         —              0    (arrives on hover)
         quiet        —              0    (arrives on hover)  */

  --bc-link-content:               var(--bc-content-primary);
  --bc-link-content-hover:         var(--bc-content-primary-hover);
  --bc-link-inverse-content:       var(--bc-content-inverse);
  /* Green as a word only ever happens on the dark half. On white it is 1.86:1
     — fine for a line under the text, nowhere near enough for the text. */
  --bc-link-inverse-content-hover: var(--bc-content-accent-on-inverse);

  /* The underline. One geometry for all four variants. */
  --bc-link-underline-width:      var(--bc-space-0-5);
  --bc-link-underline-offset:     var(--bc-space-0-5);
  --bc-link-underline-accent:     var(--bc-border-accent);
  /* The boolean itself, and the two switches a variant sets. The defaults are
     "underline off"; each variant states both, because a variant inside a <p>
     also matches the prose rule and would otherwise inherit its rest layer. */
  --bc-link-underline-on:          100%;
  --bc-link-underline-off:         0;
  --bc-link-rest-underline:        transparent;
  --bc-link-accent-underline-size: var(--bc-link-underline-off);
  /* The wipe is an animation, not a transition, so that it replays on the one
     variant whose underline is already accent green at rest and would
     otherwise have nothing to change. 340ms is the source's own figure. */
  --bc-link-wipe-duration:        var(--bc-duration-wipe);
  --bc-link-wipe-ease:            var(--bc-ease-emphasis);
  --bc-link-transition:           color var(--bc-duration-fast) var(--bc-ease-standard);
  --bc-link-focus-outline-width:  var(--bc-ring-width);
  --bc-link-focus-outline-color:  var(--bc-border-focus);
  --bc-link-focus-outline-offset: var(--bc-space-0-5);

  /* Standalone and back — its own line, an arrow, 14px semibold. The gap grows
     on hover alongside the wipe, so the arrow travels with it. */
  --bc-link-standalone-font-size:   var(--bc-font-size-sm);
  --bc-link-standalone-font-weight: var(--bc-font-weight-semibold);
  --bc-link-standalone-gap:         var(--bc-space-2);
  --bc-link-standalone-gap-hover:   var(--bc-space-3);
  --bc-link-standalone-arrow-size:  var(--bc-space-4);
  --bc-link-standalone-transition:  gap var(--bc-duration-fast) var(--bc-ease-standard);
  /* The arrow glyphs. A mask, so the paint is currentColor and one token serves
     both surfaces and both states; the black inside the data URI is the mask's
     alpha channel, never a painted colour. Lucide arrow-right / arrow-left,
     which is what the source draws. */
  --bc-link-standalone-arrow:      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
  --bc-link-back-arrow:            url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5'/%3E%3Cpath d='m12 19-7-7 7-7'/%3E%3C/svg%3E");

  /* Quiet — footer lists and meta rows. The only variant that does not start
     at the link colour: it sits in the running-text colour until pointed at,
     then lights up like every other link. */
  --bc-link-quiet-content:         var(--bc-content-secondary);
  --bc-link-quiet-inverse-content: var(--bc-content-inverse-secondary);

  /* Compact button — the size the event cards use, 12 instances on the source.
     Smaller, tighter, and square-ish rather than a pill: it sits inside a card
     next to another action, where a full pill reads as the page CTA.

     The source also sets these uppercase. We do not, because the brand book
     asks for no capitalised words and the eyebrow is the exception we agreed —
     see DESIGN-RULES. Flagged rather than decided. */
  --bc-button-compact-radius:         var(--bc-button-radius);
  --bc-button-compact-padding-block:  var(--bc-space-2-5);
  --bc-button-compact-padding-inline: var(--bc-space-4);
  --bc-button-compact-font-size:      var(--bc-font-size-xs);
  --bc-button-compact-font-weight:    var(--bc-font-weight-bold);
  --bc-button-compact-tracking:       var(--bc-tracking-wide);
  /* Two buttons side by side are one decision, so they sit close. */
  --bc-button-group-gap:              var(--bc-space-2);   /* 8px */
  /* Label to arrow, where a button carries one. The same 8px as the gap between
     two buttons, and for the same reason: they are one thing, not two. It grows
     on hover so the arrow travels — the same 8 → 12 the standalone link makes,
     and the source's `group-hover:translate-x-1` on every affordance arrow. */
  --bc-button-icon-gap:               var(--bc-space-2);   /*  8px */
  --bc-button-icon-gap-hover:         var(--bc-space-3);   /* 12px */
  /* Beside a label. 16px is what the media card's arrow already was — it read
     the standalone link's arrow size, which made a button's icon depend on a
     link's token. Same value, named for the thing that holds it. */
  --bc-button-icon-size:              var(--bc-space-4);   /* 16px */
  /* Icon only: the same button squared. 44px is the button's own height —
     12 + 20 + 12 — so an icon-only button sits on the row's baseline beside a
     labelled one instead of being a size of its own. The icon inside is a step
     up from the inline one, because here it is the whole of what the button
     says rather than a mark travelling beside a word. */
  --bc-button-icon-only-box:          var(--bc-space-11);  /* 44px */
  --bc-button-icon-only-icon-size:    var(--bc-icon-size); /* 20px */
  /* size = compact, and this is the one place compact means anything to an
     icon-only button. The rule used to read "never write an icon-only button
     as a compact one", because the box was a single size and the compact
     padding ladder would have fought it. It does not fight it now: compact
     REBINDS the box rather than padding inside it, which is the same move the
     dark-context list makes on a surface.

     32px, measured off the team card's social row. It is for a button sitting
     INSIDE a card, where three 44px circles in a 24px-padded box read as the
     loudest thing on it. Everywhere else — the footer row, the Social links
     pattern — keeps 44, which is also the touch-target size worth defaulting
     to. The source's footer is 40; the 4px is a deliberate divergence rather
     than a third step nobody could tell from the second. */
  --bc-button-icon-only-box-sm:       var(--bc-space-8);      /* 32px */
  --bc-button-icon-only-icon-size-sm: var(--bc-icon-size-sm); /* 16px */

  /* ── Card ── */
  /* Two independent axes, like the button above: geometry is shared, and each
     surface supplies only colour. The source proves they are independent — its
     dark hero carries both a large card and compact ones. */

  /* Geometry — size, not surface. Three tiers, counted off becom.digital:
     compact rows (16/12, 18 uses), the default card (20/32, 34 uses), and the
     full-width banner panel (24/64, 4 uses). */
  --bc-card-compact-radius:  var(--bc-radius-xl);   /* 16px — rows, list items */
  --bc-card-compact-padding: var(--bc-space-4);     /* 16px */
  --bc-card-radius:          var(--bc-radius-2xl);  /* 20px — the default card */
  --bc-card-padding:         var(--bc-space-6);     /* 24px — measured, /nieuws */
  --bc-card-banner-radius:   var(--bc-radius-3xl);  /* 24px — full-width panel */
  --bc-card-banner-padding:  var(--bc-space-16);    /* 64px */

  /* The rhythm inside a card, measured off the source's news card rather than
     chosen: an 11px meta, twelve pixels, a 16px heading, eight pixels, 14px
     body. Small type and tight leading — a card is a summary, and a heading set
     at the page's h3 size makes three of them shout at each other. */
  --bc-card-heading-font-size:   var(--bc-font-size-md);
  --bc-card-heading-font-weight: var(--bc-font-weight-semibold);
  --bc-card-heading-line-height: var(--bc-leading-snug);
  --bc-card-meta-font-size:      var(--bc-font-size-2xs);
  --bc-card-body-font-size:      var(--bc-font-size-sm);
  --bc-card-body-line-height:    var(--bc-leading-normal);
  --bc-card-gap:                 var(--bc-space-2);   /*  8px — the default step */
  --bc-card-gap-heading:         var(--bc-space-3);   /* 12px — above a heading */
  --bc-card-gap-action:          var(--bc-space-8);   /* 32px — the text block ends here */

  /* A card that opens with an icon tile is a feature card, and the tile is what
     says so — keyed off the content, the way clickability is keyed off where the
     link is. The source types it differently from the news card the ladder above
     was measured on: a 20px bold heading rather than 16px semibold, and 24px of
     air under the tile rather than the 12 that sits above an ordinary heading.
     20px is not on this scale — it kept Tailwind's 18px `lg` and dropped its
     20px step when the names shifted down — so `lg` is the nearest step, the
     same call the media card's heading makes. */
  --bc-card-feature-gap-tile:          var(--bc-space-6);       /* 24px — mt-6 */
  --bc-card-feature-heading-font-size: var(--bc-font-size-lg);
  --bc-card-feature-heading-font-weight: var(--bc-font-weight-bold);

  /* Surface — colour, not size. */
  --bc-card-bg:            var(--bc-bg-elevated);
  --bc-card-border:        var(--bc-border-default);
  /* A card's DEFAULT ink, which is body copy — not the heading colour.
     Everything louder already names itself: a heading reads --bc-heading-content
     through theme.json, an eyebrow, a link, a person's name and a date band each
     paint their own. So what is left inheriting from the card is prose, and prose
     is --bc-content-secondary on this half (§6).

     It was content-primary, and every card pattern therefore had to pin
     content-secondary onto its own paragraph to get grey body copy back. Those
     pins are what lint:surfaces exists to forbid — a pinned colour cannot follow
     a card onto a dark ground — so the token they were working around had to
     move first. */
  --bc-card-content:       var(--bc-content-secondary);
  --bc-card-shadow:        var(--bc-shadow-card);

  /* The same card on a dark surface. Colour only — it takes whichever
     geometry above it needs, exactly as the light one does. */
  --bc-card-inverse-bg:      var(--bc-bg-inverse-elevated);
  --bc-card-inverse-border:  var(--bc-border-inverse);
  /* The same decision on the dark half: prose, not the heading's white.
     content-inverse is 100% and makes a card's body copy compete with the
     heading above it — the same mistake §6 records for the hero's lead. */
  --bc-card-inverse-content: var(--bc-content-inverse-secondary);

  /* ── Review card ──
     A member quote. The parts that are the card's own rather than the Card's:
     the accent quote mark that opens it, and the attribution row that closes it
     under a rule. */
  --bc-review-quote-content:   var(--bc-content-accent-on-inverse);
  --bc-review-quote-size:      var(--bc-icon-size-lg);       /* 24px — h-6 */
  --bc-review-divider:         var(--bc-border-inverse);
  --bc-review-divider-gap:     var(--bc-space-4);            /* 16px — pt-4 */
  --bc-review-author-gap:      var(--bc-space-3);            /* 12px — gap-3 */
  --bc-review-name-font-size:  var(--bc-font-size-md);
  --bc-review-name-font-weight: var(--bc-font-weight-bold);
  --bc-review-name-line-height: var(--bc-leading-snug);
  --bc-review-role-font-size:  var(--bc-font-size-sm);
  --bc-review-role-line-height: var(--bc-leading-snug);
  --bc-review-role-content:    var(--bc-content-inverse-tertiary);
  --bc-review-role-gap:        var(--bc-space-0-5);          /*  2px — mt-0.5 */

  /* ── Nav link ── */
  --bc-nav-link-content:         var(--bc-content-inverse-secondary);
  --bc-nav-link-content-hover:   var(--bc-content-inverse);
  --bc-nav-link-radius:          var(--bc-radius-md);
  --bc-nav-link-padding-block:   var(--bc-space-2);
  --bc-nav-link-padding-inline:  var(--bc-space-2-5);
  --bc-nav-link-font-size:       var(--bc-font-size-sm);

  /* ── Input ── */
  --bc-input-bg:        var(--bc-bg-elevated);
  --bc-input-border:    var(--bc-border-default);
  --bc-input-content:   var(--bc-content-primary);
  --bc-input-radius:    var(--bc-radius-md);
  --bc-input-padding-block:  var(--bc-space-2);
  --bc-input-padding-inline: var(--bc-space-3);

  /* ── Eyebrow (the all-caps meta label above section headings) ── */
  /* Quiet eyebrow — meta labels above a heading. */
  --bc-eyebrow-font-size:   var(--bc-font-size-xs);
  --bc-eyebrow-font-weight: var(--bc-font-weight-semibold);
  --bc-eyebrow-tracking:    var(--bc-tracking-widest);
  --bc-eyebrow-content:     var(--bc-content-tertiary);

  /* Accent eyebrow — the green one that opens a section, with a leading rule.
     Larger and less tracked than the quiet one; both are measured. */
  --bc-eyebrow-accent-font-size:   var(--bc-font-size-sm);
  --bc-eyebrow-accent-tracking:    var(--bc-tracking-wider);
  --bc-eyebrow-accent-content:     var(--bc-content-accent);
  --bc-eyebrow-accent-gap:         var(--bc-space-2);
  --bc-eyebrow-accent-rule-width:  var(--bc-space-7);
  --bc-eyebrow-accent-rule-height: var(--bc-space-0-5);

  /* ── Card, interactive ──
     The whole card is a link, which is most of the cards on becom.digital. On
     hover it lifts and a purple-to-green gradient outline fades in — an inset
     mask rather than a background, so it reads as a 1px border and not a fill.
     Ported from the source's .card-interactive, easing included. */
  --bc-card-interactive-transition: transform var(--bc-duration-card) var(--bc-ease-emphasis),
                                    box-shadow var(--bc-duration-card) var(--bc-ease-emphasis),
                                    border-color var(--bc-duration-card);
  --bc-card-interactive-hover-transform: translateY(var(--bc-lift-card));
  --bc-card-interactive-hover-shadow:    var(--bc-shadow-glow);
  --bc-card-interactive-ring: linear-gradient(135deg,
                                color-mix(in oklab, var(--bc-border-focus) 55%, transparent),
                                color-mix(in oklab, var(--bc-bg-accent) 45%, transparent));
  --bc-card-interactive-ring-width: var(--bc-size-border);
  /* The heading lights up with the card, the way a link lights up on hover —
     it is the link, it just happens to fill the card. */
  --bc-card-interactive-heading-hover: var(--bc-content-primary-hover);
  --bc-card-interactive-image-transition: transform var(--bc-duration-image) var(--bc-ease-emphasis);
  --bc-card-interactive-image-hover:      scale(var(--bc-scale-image));
  --bc-card-interactive-focus-shadow: 0 0 0 var(--bc-ring-width) var(--bc-bg-base),
                                      0 0 0 var(--bc-ring-offset)
                                        color-mix(in oklab, var(--bc-border-focus) 50%, transparent);

  /* A card on a dark section is a pane of frosted glass on the source. */
  --bc-card-inverse-blur: var(--bc-blur-glass);
  /* What the card actually reads, mirroring the outline button: flat at rest,
     rebound to the inverse blur by the dark-context list. --bc-card-inverse-blur
     had no consumer at all until this — a token with a value and no reader,
     which is the failure this system keeps naming. */
  --bc-card-blur:         0px;

  /* ── Card, media ──
     A photograph with the content sitting on it. The scrim is what makes the
     text legible, so it is not optional decoration — it is the component. */
  /* ── Tag ──
     A label that names what an item is — a format, a category, a state that
     does not change. Not a Pill: a pill is fully round, and roundness is the
     whole of what a pill looks like. A tag sits inside a card, so it takes the
     smallest radius in the scale rather than the largest, and reads as part of
     the card rather than as a second action next to the real one. */
  --bc-tag-bg:             var(--bc-bg-accent-soft);
  --bc-tag-content:        var(--bc-content-on-accent);
  --bc-tag-radius:         var(--bc-radius-sm);
  --bc-tag-padding-block:  var(--bc-space-1);
  --bc-tag-padding-inline: var(--bc-space-2);
  --bc-tag-font-size:      var(--bc-font-size-2xs);
  --bc-tag-font-weight:    var(--bc-font-weight-semibold);
  --bc-tag-tracking:       var(--bc-tracking-wide);
  /* surface = glass. A wash behind a hairline, carrying the brand purple as its
     word — the pill's material, at the tag's shape.

     These are the LIGHT-half values, and a dark surface rebinds all three the
     way it rebinds the card's. Glass has to be rebound rather than made
     surface-proof, because a translucent fill has no colour of its own: it
     takes whatever it is over. A single wash cannot work on both halves, which
     is what the first version got wrong — it was white-on-white on the light
     half and had to be labelled "do not".

     The word is the brand purple rather than the accent, because the accent is
     never a word on a light surface: green on white is 1.59:1. */
  --bc-tag-glass-bg:       color-mix(in oklab, var(--bc-content-primary) 8%, transparent);
  --bc-tag-glass-border:   var(--bc-border-default);
  --bc-tag-glass-content:  var(--bc-content-primary);

  /* dot = on. The live marker the hero opener carries. Accent green on the
     glass surface, where it reads on either half; the soft surface rebinds it
     to the purple, because a green dot on a green fill is not a dot. */
  --bc-tag-dot:            var(--bc-bg-accent);
  --bc-tag-dot-soft:       var(--bc-content-on-accent);
  --bc-tag-dot-size:       var(--bc-space-2);
  --bc-tag-gap:            var(--bc-space-2);

  --bc-card-media-min-height:  var(--bc-size-media);
  /* A media header sits flush against the card's edge, above the padded body.
     The blog card holds a ratio; the event card holds a fixed band, because it
     carries a date rather than a photograph and must not grow with the column. */
  --bc-card-image-aspect:      var(--bc-ratio-media);
  --bc-card-band-height:       var(--bc-space-28);   /* 112px — h-28 on the source */
  /* The date itself. Measured off the source's card: the day is text-4xl in
     its Tailwind config, which resolves to 2.25rem — our 3xl. tabular numerals
     because a column of dates that shifts width as the digits change reads as
     a mistake. The month sits on a dark chip so it holds against a photograph
     showing through the band. */
  --bc-card-band-day-font-size:      var(--bc-font-size-3xl);
  --bc-card-band-day-font-weight:    var(--bc-font-weight-bold);
  --bc-card-band-day-line-height:    var(--bc-leading-none);
  --bc-card-band-day-content:        var(--bc-content-inverse);
  --bc-card-band-month-font-size:    var(--bc-font-size-2xs);
  --bc-card-band-month-font-weight:  var(--bc-font-weight-bold);
  --bc-card-band-month-tracking:     var(--bc-tracking-widest);
  --bc-card-band-month-content:      var(--bc-content-inverse);
  --bc-card-band-month-bg:           var(--bc-bg-overlay);
  --bc-card-band-month-radius:       var(--bc-radius-md);
  --bc-card-band-month-padding-block:  var(--bc-space-0-5);
  --bc-card-band-month-padding-inline: var(--bc-space-1-5);
  --bc-card-band-date-gap:           var(--bc-space-1);
  --bc-card-media-radius:      var(--bc-card-radius);
  --bc-card-media-padding:     var(--bc-card-padding);
  --bc-card-media-scrim:       var(--bc-gradient-scrim);
  --bc-card-media-content:     var(--bc-content-inverse);
  --bc-card-media-image-transition: transform var(--bc-duration-image) var(--bc-ease-emphasis);
  --bc-card-media-image-hover:      scale(var(--bc-scale-image));
  --bc-card-media-border:      var(--bc-border-inverse-weak);

  /* The tile floats at the card's top-left corner, over the photograph rather
     than in the padded body — so it is a step down from the tile's own default
     and sits on its own inset instead of on the card's padding. */
  --bc-card-media-icon-size:  var(--bc-space-12);   /* 48px — h-12 on the source */
  --bc-card-media-icon-inset: var(--bc-space-4);    /* 16px — top-4 left-4 */

  /* The rhythm on the photograph, measured off the source. It is not the card's
     own ladder: there is no meta, the heading is the accent green rather than
     the surface colour, and the action sits 16px under the body instead of 32 —
     a media card is a poster, and its text block is three lines, not a summary
     with an afterthought under it.

     The source sets the heading at 20px, which this scale does not carry: it
     kept Tailwind's 18px `lg` and dropped its 20px step when the names shifted
     down. `lg` is the nearest step and the one used here. */
  --bc-card-media-heading-font-size:   var(--bc-font-size-lg);
  --bc-card-media-heading-font-weight: var(--bc-font-weight-bold);
  --bc-card-media-heading-line-height: var(--bc-leading-snug);
  --bc-card-media-heading-tracking:    var(--bc-tracking-tight);
  /* Green as a word, which is legal here and nowhere on the light half: on the
     scrim it reads at ~9:1, on white at 1.59. */
  --bc-card-media-heading-content:     var(--bc-content-accent-on-inverse);
  --bc-card-media-heading-shadow:      var(--bc-shadow-text-strong);
  --bc-card-media-body-font-size:      var(--bc-font-size-sm);
  --bc-card-media-body-line-height:    var(--bc-leading-relaxed);
  --bc-card-media-body-content:        var(--bc-content-inverse-secondary);
  --bc-card-media-body-shadow:         var(--bc-shadow-text);
  --bc-card-media-gap:                 var(--bc-space-2);   /*  8px — heading to body */
  --bc-card-media-gap-action:          var(--bc-space-4);   /* 16px — body to action */
  /* The action starts a rung up the glass ladder because it sits on a
     photograph, so its hover starts a rung up too. */
  --bc-card-media-action-bg:           var(--bc-bg-inverse-glass);
  --bc-card-media-action-bg-hover:     var(--bc-bg-inverse-glass-lit);

  /* ── Avatar ──
     Initials on an accent disc, where a member has no portrait. The dark text
     is --bc-content-on-accent for the same reason a primary button's is: white
     on this green is 1.9:1 and unreadable. */
  --bc-avatar-size:        var(--bc-space-9);          /* 36px — h-9 */
  --bc-avatar-radius:      var(--bc-radius-full);
  --bc-avatar-bg:          var(--bc-bg-accent-gradient);
  --bc-avatar-content:     var(--bc-content-on-accent);
  --bc-avatar-font-size:   var(--bc-font-size-xs);
  --bc-avatar-font-weight: var(--bc-font-weight-bold);
  --bc-avatar-shadow:      var(--bc-shadow-accent);

  /* ── Logo plate ──
     The white pane a member's logo sits on. A logo arrives as artwork drawn for
     a light ground and cannot be recoloured, so on the dark half it needs its
     own surface rather than the section's — which is the whole reason this is a
     component and not just an image. Fixed size so a row of them lines up
     whatever shape the artwork is; the image is contained inside it. */
  --bc-logo-plate-bg:      var(--bc-bg-elevated);
  --bc-logo-plate-radius:  var(--bc-radius-xl);
  --bc-logo-plate-padding: var(--bc-space-2);          /*  8px — p-2 */
  --bc-logo-plate-height:  var(--bc-space-14);         /* 56px — h-14 */
  --bc-logo-plate-width:   var(--bc-space-28);         /* 112px — w-28 */

  /* ── Icon ──
     Painted as a mask so it inherits the surface, like the link arrows.

     The mask itself is not a value this file holds: each becom-icon--* class in
     the generated icons.css sets --bc-icon-mask to its own data URI, and both
     the .becom-icon element and a button's ::before read it from whatever
     carries that class. Declared here so the read resolves — an icon class that
     is missing leaves `none`, which paints the box unmasked rather than
     dropping the declaration and taking the size with it. */
  --bc-icon-mask:    none;
  --bc-icon-size:    var(--bc-space-5);
  --bc-icon-size-sm: var(--bc-space-4);
  --bc-icon-size-lg: var(--bc-space-6);

  /* ── Icon tile ──
     The square that holds an icon. Two fills, counted off the source: a solid
     brand gradient carrying a white icon, and a tint with a ring carrying the
     colour itself. */
  --bc-icon-tile-size:        var(--bc-space-14);
  --bc-icon-tile-size-sm:     var(--bc-space-10);
  --bc-icon-tile-radius:      var(--bc-radius-2xl);
  --bc-icon-tile-radius-sm:   var(--bc-radius-xl);
  --bc-icon-tile-solid-bg:      var(--bc-gradient-brand);
  --bc-icon-tile-solid-content: var(--bc-content-inverse);
  /* The solid tile carries a ring and a drop on the source — on the info card's
     56px one and the media card's 48px one alike, which is what says the two are
     one tile at two sizes. Both were dropped in the port, and a tile without
     them reads as pasted onto the surface rather than sitting on it. */
  --bc-icon-tile-solid-ring:   color-mix(in oklab, var(--bc-brand-neutral-900) 30%, transparent);
  --bc-icon-tile-solid-shadow: var(--bc-shadow-tile);
  --bc-icon-tile-transition:      transform var(--bc-duration-tile) var(--bc-ease-emphasis);
  --bc-icon-tile-hover-transform: scale(var(--bc-scale-tile)) rotate(var(--bc-rotate-tile));
  --bc-icon-tile-tint-bg:      color-mix(in oklab, var(--bc-bg-accent) 15%, transparent);
  --bc-icon-tile-tint-ring:    color-mix(in oklab, var(--bc-bg-accent) 30%, transparent);
  --bc-icon-tile-tint-content: var(--bc-content-accent);
  /* The icon inside each tile. Named rather than inherited, because the
     alternative is a rule that sets --bc-icon-size from itself. */
  --bc-icon-tile-icon-size:      var(--bc-icon-size-lg);
  --bc-icon-tile-tint-icon-size: var(--bc-icon-size);

  /* ── Heading and body ──
     theme.json points at these rather than at content-primary and
     content-secondary directly, so a dark context can rebind them the way it
     rebinds a link. Until it could, every heading on every dark surface came
     out purple on purple unless its author set the colour by hand — and the
     patterns that did were the only reason nobody had noticed. */
  --bc-heading-content: var(--bc-content-primary);
  --bc-body-content:    var(--bc-content-secondary);

  /* ── Lead ──
     The opening paragraph of a section: one step up from body, quieter than a
     heading, and held to a readable measure. */
  --bc-lead-font-size:  var(--bc-font-size-lg);
  --bc-lead-line-height: var(--bc-leading-relaxed);
  --bc-lead-content:    var(--bc-content-secondary);
  --bc-lead-measure:    var(--bc-size-content);

  /* ── Stat ──
     A number worth reading from across the room, and the thing it counts. */
  --bc-stat-value-font-size:   var(--bc-font-size-display-md);
  --bc-stat-value-font-weight: var(--bc-font-weight-bold);
  --bc-stat-value-line-height: var(--bc-leading-tight);
  --bc-stat-value-tracking:    var(--bc-tracking-tight);
  --bc-stat-value-content:     var(--bc-content-primary);
  --bc-stat-label-font-size:   var(--bc-font-size-xs);
  --bc-stat-label-font-weight: var(--bc-font-weight-semibold);
  --bc-stat-label-tracking:    var(--bc-tracking-widest);
  --bc-stat-label-content:     var(--bc-content-tertiary);
  --bc-stat-gap:               var(--bc-space-2);

  /* ── Documentation — a specimen entry ──
     Name, description, properties, then the rendered component. The ladder is
     the card's own rhythm one step wider: a tight pair at the top, a step to
     the properties, a step to the thing itself, and a rule before the next
     entry. It is written once here because five of these stacked with
     hand-picked margins is exactly how a documentation page stops looking
     designed. */
  --bc-docs-entry-gap:          var(--bc-space-16);  /* 64px — the rule to the next name */
  --bc-docs-entry-name-gap:     var(--bc-space-2);   /*  8px — name → description */
  --bc-docs-entry-desc-gap:     var(--bc-space-4);   /* 16px — description → properties */
  --bc-docs-entry-render-gap:   var(--bc-space-10);  /* 40px — properties → the render */
  --bc-docs-entry-border:       var(--bc-border-weak);
  --bc-docs-props-gap:          var(--bc-space-4);
  --bc-docs-props-font-size:    var(--bc-font-size-xs);
  /* The property combination is the point of the line; the slug beside it is a
     reference. Both were tertiary, which made them one grey run of monospace. */
  --bc-docs-props-content:      var(--bc-content-secondary);
  --bc-docs-slug-content:       var(--bc-content-tertiary);
  --bc-docs-name-font-size:     var(--bc-font-size-lg);
  --bc-docs-name-font-weight:   var(--bc-font-weight-bold);
  --bc-docs-name-content:       var(--bc-content-primary);

  /* The two sticky rows, as one number each. Declared here with a sensible
     default and OVERWRITTEN AT RUNTIME by docs.js, which measures them —
     neither is a constant, because the bar wraps to two rows below sm and the
     rail wraps whenever its labels do. Declaring them is what makes the reads
     resolve when the script has not run, the same reason --bc-icon-mask is
     declared as none: a var() that resolves to nothing takes its whole
     declaration with it, and a rail that silently stops sticking is not a
     failure anybody reads as one. */
  --bc-docs-bar-height:         var(--bc-sitebar-height);
  --bc-docs-chrome-height:      calc(var(--bc-sitebar-height) + var(--bc-space-16));

  /* ── Tabs ──
     Within-page navigation. The bar is a sticky rail; each tab is a pill that
     fills on hover and stays filled while its section is in view. */
  --bc-tabbar-bg:             var(--bc-bg-elevated);
  --bc-tabbar-border:         var(--bc-border-default);
  --bc-tabbar-padding-block:  var(--bc-space-3);
  --bc-tab-gap:               var(--bc-space-1);
  --bc-tab-radius:            var(--bc-radius-md);
  --bc-tab-padding-block:     var(--bc-space-2);
  --bc-tab-padding-inline:    var(--bc-space-3);
  --bc-tab-font-size:         var(--bc-font-size-sm);
  --bc-tab-font-weight:       var(--bc-font-weight-semibold);
  --bc-tab-content:           var(--bc-content-secondary);
  --bc-tab-content-hover:     var(--bc-content-primary);
  --bc-tab-bg-hover:          var(--bc-bg-sunken);
  --bc-tab-content-current:   var(--bc-content-primary);
  --bc-tab-bg-current:        var(--bc-bg-sunken-deep);

  /* ── Filter ──
     A control whose own state is the payload. That is a fourth thing, and it
     is why it gets a name: a Tag says what an item *is* and can never change,
     a Tab points at a section elsewhere on the page, a Button goes and does
     something. A filter does none of those — clicking it changes nothing but
     itself, and the list below reads the answer.

     The radius is what says so. `md` is the corner this system already gives
     interactive chrome that is not a call to action — the nav link, the input,
     the tab — so a filter lands in that family at a glance. A pill is the one
     shape it may never take: fully round, filled solid purple, is `button-
     secondary` token for token, which is exactly why a chip drawn that way
     reads as a button and not as a filter.

     It is also deliberately shorter than a button: 42px against 44. Small
     enough to read as a control, large enough to press. */
  --bc-filter-radius:          var(--bc-radius-md);
  --bc-filter-padding-block:   var(--bc-space-2-5);
  --bc-filter-padding-inline:  var(--bc-space-4);
  --bc-filter-gap:             var(--bc-space-2);
  --bc-filter-font-size:       var(--bc-font-size-sm);
  --bc-filter-line-height:     var(--bc-leading-control);
  --bc-filter-transition:      background-color var(--bc-duration-lift) var(--bc-ease-emphasis),
                               border-color var(--bc-duration-lift) var(--bc-ease-emphasis),
                               color var(--bc-duration-lift) var(--bc-ease-emphasis);

  /* At rest: a hairline on nothing. 500 is the UI-label weight, and it is the
     weight in *both* states — see below. One step under the button's 600, and
     under the tab's, which is right: a tab has to hold a sticky rail on its
     own, a filter is one of eight in a strip that is already legible as a
     group. */
  --bc-filter-bg:              transparent;
  --bc-filter-border:          var(--bc-border-default);
  --bc-filter-content:         var(--bc-content-secondary);
  --bc-filter-font-weight:     var(--bc-font-weight-medium);

  /* Hover is a PREVIEW of the selected state, not a generic surface response.
     It used to be `bg-sunken` — the tab's and the outline button's hover, one
     neutral rung down the ladder — which is right for a control that is about
     to do something elsewhere and wrong for one that is about to change
     itself. A blue-grey wash says "you are pointing at this"; a green one says
     "this is what picking it looks like", and that is the question a filter is
     asking.

     Two ramp steps under the selected fill, so the preview cannot be mistaken
     for the answer. The border goes green at full strength here, though: the
     ground barely tints, so the edge is what carries the message. */
  --bc-filter-bg-hover:        var(--bc-bg-accent-subtle);
  --bc-filter-border-hover:    var(--bc-border-accent-soft);
  --bc-filter-content-hover:   var(--bc-content-primary);

  /* On a dark ground the light half's answer inverts: accent-100 is very nearly
     white, so the pale fill that reads as a whisper on white would be the
     loudest thing in an inverse section. A translucent accent wash is the same
     gesture at the same strength on the other half. */
  --bc-filter-inverse-bg-hover:     color-mix(in oklab, var(--bc-bg-accent) 16%, transparent);
  --bc-filter-inverse-border-hover: color-mix(in oklab, var(--bc-bg-accent) 45%, transparent);

  /* selected = on. The Tag's pair: the opaque accent at step 300 with the
     near-black purple as ink. Chosen over a solid purple fill because that is
     the secondary button, and over the tab's `sunken-deep` because a recess
     is too quiet to pick out of eight chips at a glance.

     Green already means *on* everywhere else here — the status dot, the live
     tag — and no button in the system is ever a flat soft green: the primary
     is the accent *gradient*, with a shadow and a lift. So the two do not
     collide even when a filter bar sits above a row of Inschrijven buttons.

     The weight does NOT go up with it, which was the first instinct and is
     wrong twice over. A bolder label is a wider label, so the chip grows on
     click and re-flows the row underneath the pointer. And the theme loads no
     webfont, so 600 is synthesised, with metrics nobody chose. The fill is a
     whole ground appearing; it does not need help.

     The border carries the state too, rather than going transparent. That was
     the deal when the ring came out: with no marker, a filter's whole answer
     is its ground, and a ground is the one thing that reads badly at a glance
     across eight chips on a near-white page. An edge that changes hue with the
     fill is a second signal that costs nothing — the border is already there
     at rest, already 1px, so nothing moves and nothing resizes.

     `border-accent-soft`, not `border-accent`. The full-chroma green against a
     step-300 ground reads as two different greens; one step down reads as one
     component with an edge. */
  --bc-filter-selected-bg:      var(--bc-bg-accent-soft);
  --bc-filter-selected-border:  var(--bc-border-accent-soft);
  --bc-filter-selected-content: var(--bc-content-on-accent);

  /* A filter carrying its own icon leads with it. There is no marker to
     compete with any more — the ring came out, and the fill and the edge say
     what it used to say — so this is now only about the leading slot. */
  --bc-filter-icon-size:           var(--bc-space-4);

  /* Focus is the button's ring, at the filter's corner. The input itself is
     hidden, so the ring has to be drawn on the label. */
  --bc-filter-focus-shadow:    0 0 0 var(--bc-ring-width) var(--bc-bg-base),
                               0 0 0 var(--bc-ring-offset) var(--bc-border-focus);

  /* The group. `set-gap` separates a label from its chips and one set from the
     next; `gap` is between chips, matching the two-buttons-are-one-decision
     spacing the card already uses. */
  --bc-filter-bar-gap:         var(--bc-space-8);
  --bc-filter-set-gap:         var(--bc-space-4);
  --bc-filter-group-gap:       var(--bc-space-2);

  /* ── Person ──
     Someone on a card: a photograph, a name, what they do, and — for the team
     rather than the board — how to reach them. Classes rather than block
     styles, like the review card's attribution and the event card's date band:
     they are this composition's internals and nothing else would pick them.

     The name and role are the same two type decisions the review card's
     attribution makes, at the same two sizes. They stay separate families
     because the role's COLOUR is what differs and it differs per callsite —
     the accent here, inverse-tertiary there — which is precisely what a
     level-4 token is for. Worth unifying if a third caller ever appears. */
  --bc-person-gap:               var(--bc-space-4);   /* photo → text, 16px */
  --bc-person-photo-size:        var(--bc-space-14);  /* 56px */
  --bc-person-photo-radius:      var(--bc-radius-full);
  /* photo = muted. The board is greyscaled on the source and the team is not:
     a board member is named rather than pictured. */
  --bc-person-photo-filter:      grayscale(var(--bc-grayscale-muted));

  --bc-person-name-font-size:    var(--bc-font-size-md);
  --bc-person-name-font-weight:  var(--bc-font-weight-semibold);
  --bc-person-name-line-height:  var(--bc-leading-snug);
  /* Declared against the mapped token directly, NOT via --bc-heading-content.
     A var() inside a custom-property declaration is substituted where the
     declaration lives — here, :root — so a chain through another token freezes
     the light value and descendants inherit the frozen one. Reading
     --bc-heading-content looked like it would follow a dark section and did
     not: the band's name came out purple on purple. That is why the
     dark-context list is a long explicit list rather than three chains. */
  --bc-person-name-content:      var(--bc-content-primary);

  /* The role is the accent, and this is one of the two places green is legal
     as a word on the light half: it is content-accent, step 800 of the ramp at
     8.4:1 on white, not the accent-500 that §1b keeps off light surfaces. */
  --bc-person-role-font-size:    var(--bc-font-size-sm);
  --bc-person-role-line-height:  var(--bc-leading-normal);
  --bc-person-role-content:      var(--bc-content-accent);

  /* The third line, under the role. It is the member's COMPANY on the board
     and a second title on the team — one line doing one job, which is to carry
     whatever qualifies the role, so it is named for the slot rather than for
     either instance. Present on 11 of the source's 22 cards, so the pattern
     ships with it and an author deletes it rather than hunting for it.

     content-SECONDARY, not tertiary. It is small, and tertiary at this size on
     a card would be the one piece of text on the component that has to be
     worked at. The source agrees: it is muted-foreground here, the same ink as
     the phone number below it.

     The source steps it 4px off the role on the board and not at all on the
     team — one decision made twice, 4px apart, so it is normalised to the
     step. Without one, the neutral line and the accent role above it run
     together as a single block. */
  --bc-person-detail-gap:        var(--bc-space-1);   /* 4px */
  --bc-person-detail-font-size:  var(--bc-font-size-xs);
  --bc-person-detail-line-height: var(--bc-leading-normal);
  --bc-person-detail-content:    var(--bc-content-secondary);

  /* contact = on. Its own rhythm, because the card's default step is 8px and
     these three blocks are measured at 16 and 12. */
  --bc-person-contact-gap:       var(--bc-space-4);   /* 16px above the block */
  --bc-person-contact-row-gap:   var(--bc-space-1);   /* 4px between its lines */
  --bc-person-contact-font-size: var(--bc-font-size-sm);
  --bc-person-contact-content:   var(--bc-content-secondary);
  --bc-person-social-gap:        var(--bc-space-3);   /* 12px above the row */

  /* ── Person, as a band ──
     The same person laid across a panel instead of stacked in a grid: the
     closing "here is who to ask" section. It reuses the photo, name and role
     above and changes four things — the photo is larger, the two sit in a row,
     an eyebrow opens it, and the contact block becomes two Buttons.

     The panel itself is just a Card on a dark section, so it needs no tokens
     at all: the dark-context list already swaps the card's surface, and its
     radius is the default tier. The source draws that corner one step larger,
     and taking the tier instead is the trade §4 asks for — a pattern reaching
     past the component token is how the tiers drift apart.

     One size for the portrait rather than the source's two. It steps 80 → 96
     at the medium breakpoint, and this stylesheet carries no width queries;
     96 is the value the band is mostly seen at. */
  --bc-person-photo-size-lg:        var(--bc-space-24);  /* 96px */
  --bc-person-band-gap:             var(--bc-space-6);   /* 24px, photo → text */
  --bc-person-band-name-font-size:  var(--bc-font-size-lg);
  --bc-person-band-name-font-weight: var(--bc-font-weight-bold);
  /* A hairline around the portrait, which the light card does not draw. On the
     dark panel a photograph ends against a translucent surface with nothing to
     say where it stops; the source rings it for that reason. */
  --bc-person-band-photo-ring:      var(--bc-border-inverse);
  /* The panel is narrower than the page it closes, and that is the whole of
     why it reads as an aside rather than as another section. The source states
     an OUTER width with its padding inside; ours states the panel itself,
     because WordPress puts the section's padding outside. Same 848px, arrived
     at from the other side — the mirror of --bc-container-outer.
     It is a rule in chrome.css rather than a layout attribute on the block:
     safecss_filter_attr strips var() out of contentSize, silently. */
  --bc-person-band-max:             calc(var(--bc-size-band) - var(--bc-container-padding-inline) * 2);
  --bc-person-band-eyebrow-gap:     var(--bc-space-1);   /* 4px, eyebrow → name */
  --bc-person-band-actions-gap:     var(--bc-space-4);   /* 16px above them */

  /* ── Accordion ──
     A stack of disclosures inside one card. Native <details>/<summary>: the
     keyboard, the open state and the screen-reader announcement all come from
     the element, and there is no state code anywhere.

     It takes its surface from the CARD tokens rather than declaring one of its
     own — same background, border, radius and shadow, so the dark-context list
     that rebinds a card rebinds this too and the accordion comes out right on
     either half without knowing which one it is on. Only its padding differs
     from a card's, and only on one axis: the rule between two items has to
     reach the card's inner edges, so the block padding comes off and each
     summary carries its own instead. */
  --bc-accordion-padding-inline:        var(--bc-space-6);
  --bc-accordion-item-border:           var(--bc-border-weak);

  /* The summary's three states are the Tab's three, minus the fill —
     see the rule in chrome.css for why the fill cannot come along. Rest is
     the near-black the source uses for its own question text, not the purple:
     six purple questions stacked read as six headings rather than as a list
     of things to open. */
  --bc-accordion-summary-padding-block: var(--bc-space-4);
  --bc-accordion-summary-gap:           var(--bc-space-4);
  --bc-accordion-summary-font-size:     var(--bc-font-size-md);
  --bc-accordion-summary-font-weight:   var(--bc-font-weight-semibold);
  --bc-accordion-summary-line-height:   var(--bc-leading-snug);
  --bc-accordion-summary-content:       var(--bc-content-secondary);
  --bc-accordion-summary-content-hover: var(--bc-content-primary-hover);
  --bc-accordion-summary-content-open:  var(--bc-content-primary);

  /* The chevron, held as a token rather than reached for through an icon
     class — the marker is the component's, not the author's, exactly as the
     standalone link's arrow is. lucide chevron-down, painted as a mask with
     currentColor so it lights up with the text it sits beside. */
  --bc-accordion-marker:                url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --bc-accordion-marker-size:           var(--bc-icon-size-sm);
  --bc-accordion-marker-rotate:         180deg;
  --bc-accordion-marker-transition:     transform var(--bc-duration-fast) var(--bc-ease-standard);
  --bc-accordion-transition:            color var(--bc-duration-fast) var(--bc-ease-standard);

  /* An outline rather than the chip components' ring: a summary is a
     full-width row, and a 4px offset ring around one draws a box the width of
     the card that reads as a second border. */
  --bc-accordion-focus-outline-width:   var(--bc-ring-width);
  --bc-accordion-focus-outline-color:   var(--bc-border-focus);
  --bc-accordion-focus-outline-offset:  var(--bc-space-1);

  --bc-accordion-panel-font-size:       var(--bc-font-size-sm);
  --bc-accordion-panel-line-height:     var(--bc-leading-relaxed);
  --bc-accordion-panel-content:         var(--bc-content-secondary);
  --bc-accordion-panel-padding-bottom:  var(--bc-space-4);

  /* ── Site bar and page hero ──
     The bar is absolutely positioned over the hero so one gradient covers both;
     two stacked backgrounds restart the gradient and leave a visible seam. The
     hero therefore has to carry the bar's height in its own top padding. */
  --bc-sitebar-height:          var(--bc-space-20);
  --bc-sitebar-padding-block:   var(--bc-space-5);
  --bc-sitebar-gap:             var(--bc-space-4);
  --bc-sitebar-actions-gap:     var(--bc-space-2);
  --bc-sitebar-logo-height:     var(--bc-space-9);
  /* The mark, inlined the way --bc-link-standalone-arrow is. It cannot be a
     path: the preview resolves relative URLs from the repo root and WordPress
     from the theme directory, and the live path is /app/themes on Bedrock and
     /wp-content/themes everywhere else. Two rules read it — the bar's and the
     overlay's — so it is a token rather than the same 2.7KB written twice.
     Source: assets/images/becom-logo-inverse.png, which is the shipped mark
     with its .st1 fill swapped from the brand purple to white; the green is
     untouched and every alpha preserved. The ratio is the artwork's. */
  --bc-sitebar-logo-image:      url("data:image/png;base64,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");
  --bc-sitebar-logo-ratio:      384 / 109;
  /* The documentation bar is fixed to the top of the viewport so a reader can
     cross to another page from anywhere in a long one. At rest — the top of
     the page, nothing scrolled — it has no ground of its own, because the hero
     is its ground and that is the whole reason the hero is dark. It takes one
     as soon as the page moves under it: from there the bar is over content
     rather than over the top of a section, and by the time the hero has passed
     its white text would otherwise be on white page. Near-opaque over a blur
     rather than solid, which is the material the overlay panel already uses.

     It is the SUNKEN dark, not the base one. The hero is a radial gradient
     running base → sunken from its top, so a bar painted with the base sits
     over the sunken half of it as a lighter band. The deepest neutral surface
     is also the right default for chrome that has to carry white text over
     anything the page puts under it.

     Opaque. It was 92% over a blur — the overlay panel's material — and a bar
     you can read the page through is a bar with the page's contrast in it:
     whatever scrolls under it shows through as a moving smear behind the nav.
     There is no blur token here either, because a backdrop filter behind an
     opaque ground filters a backdrop nobody can see. */
  --bc-sitebar-stuck-bg:        var(--bc-bg-inverse-sunken);
  --bc-sitebar-stuck-border:    var(--bc-border-inverse-weak);
  /* Colour only. The border is present at rest and transparent, so the bar's
     height does not change by a pixel on the first scroll — docs.js measures
     that height into --bc-docs-bar-height, and a bar that resizes when it
     fills moves the rail and every anchor with it. */
  --bc-sitebar-stuck-transition: background-color var(--bc-duration-fast) var(--bc-ease-standard),
                                 border-color var(--bc-duration-fast) var(--bc-ease-standard);

  --bc-pagehero-padding-top:    calc(var(--bc-sitebar-height) + var(--bc-space-16));
  --bc-pagehero-padding-bottom: var(--bc-space-20);

  /* The bar's actions are smaller than the page's. Measured off the source:
     its header buttons are 8/16 at 14px semibold — 36px tall — where the
     system's button is 12/24 at 44. That is neither the default nor `compact`
     (10/16 at 12px bold, wide-tracked), so it is not a third size tier and
     there is no new block style to pick: the BAR REBINDS the button's padding
     for anything inside it, exactly as a clickable card rebinds
     --bc-button-hover-transform and a dark section rebinds the link tokens.
     A 44px button here also breaks the row — see the note on the nav gap. */
  --bc-sitebar-button-padding-block:  var(--bc-space-2);
  --bc-sitebar-button-padding-inline: var(--bc-space-4);

  /* ── The nav, and the two controls that open and close it ──
     The menu toggle and the overlay's close button are one control at two
     labels: same box, same corner, same glass hover. The source draws them
     identically and swaps only the glyph, so they share these tokens. */
  --bc-nav-link-gap:            var(--bc-space-0-5);
  /* A nav link is a control, not a paragraph. Without this it inherits the
     body's relaxed leading — 22.75px on 14px type — and every link in the bar
     comes out 39px tall against the source's 36. */
  --bc-nav-link-line-height:    var(--bc-leading-control);
  --bc-nav-link-bg-hover:       var(--bc-bg-inverse-elevated);
  --bc-navtoggle-box:           var(--bc-space-10);
  --bc-navtoggle-radius:        var(--bc-radius-md);
  --bc-navtoggle-icon-size:     var(--bc-icon-size);
  --bc-navtoggle-content:       var(--bc-content-inverse);
  --bc-navtoggle-bg-hover:      var(--bc-bg-inverse-elevated);

  /* ── The overlay menu ──
     A full-screen modal dialog, not a disclosure — measured off the source,
     which sets role="dialog" aria-modal="true" and locks the body's scroll.
     Its ground is the dark recess at the alpha the source uses, over a blur,
     so the hero stays faintly visible behind it. */
  --bc-navmenu-bg:              color-mix(in oklab, var(--bc-bg-inverse-sunken) 98%, transparent);
  --bc-navmenu-blur:            var(--bc-blur-glass);
  --bc-navmenu-padding-inline:  var(--bc-container-padding-inline);
  --bc-navmenu-padding-bottom:  var(--bc-space-10);
  --bc-navmenu-gap:             var(--bc-space-1);
  --bc-navmenu-actions-gap:     var(--bc-space-6);
  --bc-navmenu-link-radius:         var(--bc-radius-md);
  --bc-navmenu-link-padding-block:  var(--bc-space-3);
  --bc-navmenu-link-padding-inline: var(--bc-space-3);
  --bc-navmenu-link-font-size:      var(--bc-font-size-md);
  --bc-navmenu-link-line-height:    var(--bc-leading-normal);
  --bc-navmenu-link-content:        var(--bc-content-inverse-secondary);
  --bc-navmenu-link-content-hover:  var(--bc-content-inverse);
  --bc-navmenu-link-bg-hover:       var(--bc-bg-inverse-elevated);

  /* ── The language switcher ──
     A pill on the dark bar that opens a LIGHT popover. The menu brings its own
     surface, so it carries its own ink — the same licence the review card has
     to choose the inverse gradient, and the reason it needs no rebinding when
     the bar around it is a dark context.

     The trigger is the outline pair at the tag's type: 12px semibold in a
     fully round border, which is what tells it from the buttons beside it. Its
     globe is 16px where the source's is 14 — 14 is off the 4pt grid and the
     pill does not change height either way, the 12px line box being the taller
     of the two. */
  --bc-lang-gap:                var(--bc-space-1-5);
  --bc-lang-padding-block:      var(--bc-space-2);
  --bc-lang-padding-inline:     var(--bc-space-3);
  --bc-lang-radius:             var(--bc-radius-full);
  --bc-lang-font-size:          var(--bc-font-size-xs);
  --bc-lang-font-weight:        var(--bc-font-weight-semibold);
  /* The 16px globe sets the pill's line box, so the label must not set a
     taller one — at the control leading it did, and the pill came out 35px
     against the source's 34. */
  --bc-lang-line-height:        var(--bc-leading-snug);
  --bc-lang-icon-size:          var(--bc-icon-size-sm);
  --bc-lang-content:            var(--bc-content-inverse);
  --bc-lang-border:             var(--bc-border-inverse-strong);
  --bc-lang-bg-hover:           var(--bc-bg-inverse-elevated);

  --bc-lang-menu-bg:            var(--bc-bg-elevated);
  --bc-lang-menu-border:        var(--bc-border-weak);
  --bc-lang-menu-radius:        var(--bc-radius-md);
  --bc-lang-menu-padding:       var(--bc-space-1);
  --bc-lang-menu-shadow:        var(--bc-shadow-card);
  --bc-lang-menu-min:           var(--bc-space-40);
  --bc-lang-menu-offset:        var(--bc-space-2);

  --bc-lang-item-gap:           var(--bc-space-3);
  --bc-lang-item-padding-block: var(--bc-space-1-5);
  --bc-lang-item-padding-inline: var(--bc-space-2);
  --bc-lang-item-radius:        var(--bc-radius-sm);
  --bc-lang-item-font-size:     var(--bc-font-size-sm);
  --bc-lang-item-content:       var(--bc-content-secondary);
  --bc-lang-item-bg-hover:      var(--bc-bg-accent);
  --bc-lang-item-content-hover: var(--bc-content-on-accent);
  --bc-lang-check:              var(--bc-content-primary);
  --bc-lang-check-size:         var(--bc-icon-size-sm);

  /* The same languages as a flat list, for the mobile panel. It sits on the
     dark ground the panel already paints, so it takes the inverse ink directly
     rather than bringing a surface of its own — which is what tells it from the
     bar's popover, and why it needs no light-half pair.

     The current language is bolder as well as brighter. That is safe here where
     it would not be on a Filter: these are stacked rows, so a wider label
     re-flows nothing, and it marks a state the pointer cannot change. */
  --bc-langlist-gap:                var(--bc-space-1);
  --bc-langlist-margin-top:         var(--bc-space-6);
  --bc-langlist-padding-inline:     var(--bc-space-3);
  --bc-langlist-item-gap:           var(--bc-space-2);
  --bc-langlist-item-padding-block: var(--bc-space-2);
  --bc-langlist-item-padding-inline: var(--bc-space-3);
  --bc-langlist-item-radius:        var(--bc-radius-md);
  --bc-langlist-item-font-size:     var(--bc-font-size-sm);
  --bc-langlist-item-weight:        var(--bc-font-weight-semibold);
  --bc-langlist-item-content:       var(--bc-content-inverse-tertiary);
  --bc-langlist-item-bg-hover:      var(--bc-bg-inverse-elevated);
  --bc-langlist-item-content-hover: var(--bc-content-inverse);
  --bc-langlist-current-weight:     var(--bc-font-weight-bold);
  --bc-langlist-current-content:    var(--bc-content-inverse);
  --bc-langlist-current-bg:         var(--bc-bg-inverse-elevated);
  --bc-langlist-icon-size:          var(--bc-icon-size-sm);

  /* ── Site footer ──
     The other half of the site chrome. Unlike the bar it paints its own ground
     — bg-sunken, the ladder's rung for the footer — so nothing inside it is
     rebound and nothing inside it pins an ink.

     The block is symmetric, which is the one place on the site that is legal:
     the asymmetric section rhythm in --bc-section-padding-* pulls a section up
     toward the one above it and pushes the next away, and the footer has no
     next. The source states it as py-16 with py-20 from lg. */
  --bc-sitefoot-padding-block:       var(--bc-space-16);
  --bc-sitefoot-padding-block-wide:  var(--bc-space-20);
  /* One hairline, drawn twice: above the footer and above its bottom bar. */
  --bc-sitefoot-border:              var(--bc-border-default);
  --bc-sitefoot-gap:                 var(--bc-space-12);
  --bc-sitefoot-columns-gap:         var(--bc-space-10);

  /* The mark, in the POSITIVE artwork this time — the bar's is the inverse one,
     which would be white on white here. Inlined for the reason that one is: a
     template part cannot run get_theme_file_uri(), and a literal path is
     /app/themes on Bedrock and /wp-content/themes everywhere else.
     Source: assets/images/becom-logo.png. */
  --bc-sitefoot-logo-height:         var(--bc-space-11);
  --bc-sitefoot-logo-image:          url("data:image/png;base64,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");
  /* The same artwork as the bar's, so it is the same number rather than the
     same literal written twice. */
  --bc-sitefoot-logo-ratio:          var(--bc-sitebar-logo-ratio);

  --bc-sitefoot-mission-measure:     var(--bc-size-copy);
  --bc-sitefoot-mission-font-size:   var(--bc-font-size-sm);
  --bc-sitefoot-mission-line-height: var(--bc-leading-relaxed);

  /* An outline button's hover fill is bg-sunken — which is the footer's own
     ground, so the network row's hover was a fill in the colour it already
     sat on. Rebound a rung further down the ladder rather than restyled, the
     way the media card moves its action up the glass end: the buttons stay the
     same outline buttons, on a surface that answers. */
  --bc-sitefoot-action-bg-hover:     var(--bc-bg-sunken-deep);

  --bc-sitefoot-list-margin-top:     var(--bc-space-5);
  --bc-sitefoot-list-gap:            var(--bc-space-3);
  --bc-sitefoot-list-font-size:      var(--bc-font-size-sm);

  --bc-sitefoot-bottom-gap:          var(--bc-space-16);
  --bc-sitefoot-bottom-padding-top:  var(--bc-space-8);
  --bc-sitefoot-bottom-font-size:    var(--bc-font-size-xs);
  --bc-sitefoot-bottom-row-gap:      var(--bc-space-6);
  --bc-sitefoot-legal-gap-inline:    var(--bc-space-6);
  --bc-sitefoot-legal-gap-block:     var(--bc-space-2);

  /* ── Code ──
     A command someone copies into a terminal, and a name inside a sentence.
     The block sits on the deepest dark surface on either half of the ladder:
     it is opaque, so it carries its own contrast and needs no rebinding, and a
     terminal reads as a terminal. The inline one is a quiet recess in the
     heading purple, so a command name reads as a thing to type rather than as
     a link. */
  --bc-code-bg:                  var(--bc-bg-inverse-sunken);
  --bc-code-content:             var(--bc-content-inverse);
  --bc-code-radius:              var(--bc-card-compact-radius);
  --bc-code-padding:             var(--bc-space-5);
  --bc-code-font-family:         var(--bc-font-family-mono);
  --bc-code-font-size:           var(--bc-font-size-sm);
  --bc-code-line-height:         var(--bc-leading-relaxed);
  --bc-code-inline-bg:           var(--bc-bg-sunken);
  --bc-code-inline-content:      var(--bc-content-primary);
  --bc-code-inline-radius:       var(--bc-radius-sm);
  --bc-code-inline-padding-inline: var(--bc-space-1-5);
  --bc-code-inline-font-size:    var(--bc-font-size-sm);

  /* ── Section rhythm ── */
  --bc-section-padding-top-tight:      var(--bc-space-4);
  --bc-section-padding-top:            var(--bc-space-6);
  --bc-section-padding-top-loose:      var(--bc-space-12);
  --bc-section-padding-bottom-tight:   var(--bc-space-16);
  --bc-section-padding-bottom:         var(--bc-space-20);
  --bc-section-padding-bottom-loose:   var(--bc-space-24);
  --bc-section-padding-bottom-looser:  var(--bc-space-28);
  --bc-section-padding-block-hero:     var(--bc-space-40);
  --bc-container-max:               var(--bc-size-container);
  --bc-container-padding-inline:    var(--bc-space-6);
  /* The outer width a hand-written container needs so its CONTENT lands on
     --bc-container-max. WordPress puts the padding outside the 1280 and a naive
     max-width:1280 puts it inside, which is a 24px disagreement wherever the two
     meet — and they meet on every page that documents a pattern. */
  --bc-container-outer:  calc(var(--bc-container-max) + var(--bc-container-padding-inline) * 2);
}
