/* ==========================================================================
   baddie — components
   --------------------------------------------------------------------------
   Dependency-free. Built ONLY on tokens.css — load that first:

     <link rel="stylesheet" href="brand/tokens.css">
     <link rel="stylesheet" href="brand/components.css">

   Every class is prefixed `b-`. Modifiers use `--`, parts use `__`.
   State comes from real HTML/ARIA state, not extra classes:
     :disabled / [aria-disabled="true"]   [aria-busy="true"]   [aria-invalid="true"]
     [aria-pressed="true"]  [aria-selected="true"]  [aria-checked="true"]
     [aria-current="page"]  [data-unread="true"]    [data-platform="instagram"]

   The look, in one paragraph: flat surfaces and 1px hairlines; small radii,
   pills only for buttons and chips; solid ink for the things you press and
   switch on; one brand-coloured element per view; nothing glows, nothing
   bounces. Three voices: --font-display speaks for the brand, --font-sans does
   the work, --font-mono states the facts (numbers, times, handles, code).

   Contents
     1  Base & reset            9  Avatar            17  Tooltip
     2  Type helpers           10  Platform          18  Switch, checkbox, radio
     3  Button                 11  Tabs              19  Sidebar & nav item
     4  Field, input, select   12  Segmented         20  Row (inbox / list)
     5  Chip                   13  Alert             21  Bits: spinner, kbd, divider
     6  Badge                  14  Toast             22  Stage, shade, quote
     7  Card                   15  Modal             23  Reduced motion, forced colours
     8  Skeleton               16  Empty state
   ========================================================================== */

/* 1 ─ Base & reset ─────────────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scrollbar-color: var(--border-strong) transparent;
  /* Bodoni Moda stops at the weights it really has. An older rule asking the
     display face for a weight it lacks gets the nearest real one, never a
     smeared synthetic bold. */
  font-synthesis-weight: none;
  accent-color: var(--ink);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-regular);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

/* The serif is the brand speaking: page and section titles. Smaller titles
   are work, so they are set in the sans. */
h1,
h2 {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-variation-settings: "opsz" var(--opsz-headline);
  line-height: 1.12;
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
}

h2 {
  font-variation-settings: "opsz" var(--opsz-title);
}

h3,
h4 {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-variation-settings: normal;
  line-height: var(--lh-snug);
  letter-spacing: 0;
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

/* Links are ink. The underline is the accent. */
a {
  color: var(--text);
  text-decoration-color: var(--primary);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

::selection {
  background: var(--primary-soft-hover);
  color: var(--text);
}

input,
textarea {
  caret-color: var(--primary);
}

/* One focus style everywhere: a ring in the *other* brand hue, never removed. */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

:focus:not(:focus-visible) {
  outline: none;
}

.b-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* 2 ─ Type helpers ───────────────────────────────────────────────────────
   Display type is Bodoni Moda at one weight (--fw-display), sentence case.
   Mono is for facts only: numbers, times, handles, limits, code.            */

.b-display {
  font-family: var(--font-display);
  font-variation-settings: "opsz" var(--opsz-display);
  font-size: var(--fs-display);
  font-weight: var(--fw-display);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
  text-wrap: balance;
}

.b-h1 {
  font-family: var(--font-display);
  font-variation-settings: "opsz" var(--opsz-headline);
  font-size: clamp(var(--fs-3xl), 1.3rem + 2.6vw, var(--fs-5xl));
  font-weight: var(--fw-display);
  line-height: 1.08;
  letter-spacing: var(--ls-tighter);
}

.b-h2 {
  font-family: var(--font-display);
  font-variation-settings: "opsz" var(--opsz-title);
  font-size: clamp(var(--fs-2xl), 1.2rem + 1.4vw, var(--fs-3xl));
  font-weight: var(--fw-display);
  line-height: 1.15;
  letter-spacing: var(--ls-tight);
}

.b-h3 {
  font-family: var(--font-sans);
  font-variation-settings: normal;
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
}

.b-h4 {
  font-family: var(--font-sans);
  font-variation-settings: normal;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: 0;
}

.b-lead {
  font-size: var(--fs-lg);
  line-height: var(--lh-normal);
  color: var(--text-muted);
}

.b-small {
  font-size: var(--fs-sm);
}

.b-muted {
  color: var(--text-muted);
}

.b-faint {
  color: var(--text-faint);
}

/* A fact, set in mono: a count, a time, a handle, a limit, a step.
   Lowercase or sentence case, never tracked capitals. It stands by itself or
   in a row of facts; it is never stacked over a heading as a kicker.
   .b-eyebrow is the old name for the same thing and still works. */
.b-meta,
.b-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: var(--lh-normal);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

/* The one phrase or number on a view that gets the signature colour.
   .b-gradient-text is DEPRECATED: gradient text is retired, and the class now
   means the same solid colour, so old markup keeps working. */
.b-signature,
.b-gradient-text {
  color: var(--primary-text);
}

.b-link {
  color: var(--text);
  font-weight: var(--fw-medium);
  text-decoration: underline;
  text-decoration-color: var(--primary);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  border-radius: var(--radius-xs);
  cursor: pointer;
}

.b-link:hover {
  text-decoration-thickness: 2px;
}

.b-code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  padding: 0.12em 0.4em;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  color: var(--text);
  overflow-wrap: anywhere;
}

/* 3 ─ Button ───────────────────────────────────────────────────────────────
   <button class="b-btn b-btn--primary">Save changes</button>

   Which one:
     (default) / --secondary  hairline pill. Every action that is not the main one.
     --primary   solid ink (white in dark). The main action of a form, dialog,
                 card or toolbar. At most one per region.
     --brand     solid signature colour (pink by day, purple by night). ONE per
                 view, and only for the act the view exists for: Post, Connect
                 your first account, Download. A view without such an act has none.
     --accent    solid agent colour. Approving or sending what your agent prepared.
     --danger    solid orange-red. The destructive confirm. Always plain.
     --soft      neutral tonal fill. --ghost: no fill until hovered.
   Sizes:    --sm · (default) · --lg      Shape: --icon (square) · --block (full width)
   States:   :disabled / [aria-disabled="true"] · [aria-busy="true"] (shows a spinner)  */

.b-btn {
  --_h: var(--control-md);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--_h);
  min-width: var(--_h);
  padding: 0 var(--space-5);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.1;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.b-btn:hover {
  background: var(--surface-2);
  border-color: var(--text);
}

.b-btn:active {
  background: var(--surface-3);
}

.b-btn > svg {
  flex: none;
  width: 1.2em;
  height: 1.2em;
}

/* primary — solid ink. No gradient, no gloss, no glow. */
.b-btn--primary {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--ink-contrast);
}

.b-btn--primary:hover {
  border-color: var(--ink-hover);
  background: var(--ink-hover);
}

.b-btn--primary:active {
  border-color: var(--ink-active);
  background: var(--ink-active);
}

/* brand — the signature colour. One per view. */
.b-btn--brand {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-contrast);
}

.b-btn--brand:hover {
  border-color: var(--primary-hover);
  background: var(--primary-hover);
}

.b-btn--brand:active {
  border-color: var(--primary-active);
  background: var(--primary-active);
}

.b-btn--secondary {
  /* the default look, named so intent is explicit in markup */
}

/* soft — a neutral tonal fill, quieter than the hairline */
.b-btn--soft {
  border-color: transparent;
  background: var(--surface-2);
  color: var(--text);
}

.b-btn--soft:hover {
  border-color: transparent;
  background: var(--surface-3);
}

.b-btn--soft:active {
  background: var(--surface-3);
}

/* accent — approving or sending something your agent prepared */
.b-btn--accent {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
}

.b-btn--accent:hover,
.b-btn--accent:active {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
}

.b-btn--ghost {
  border-color: transparent;
  background: transparent;
}

.b-btn--ghost:hover {
  border-color: transparent;
  background: var(--surface-2);
}

.b-btn--danger {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--danger-contrast);
}

.b-btn--danger:hover,
.b-btn--danger:active {
  border-color: var(--danger-hover);
  background: var(--danger-hover);
}

.b-btn--sm {
  --_h: var(--control-sm);
  padding: 0 var(--space-3);
  gap: var(--space-1-5);
  font-size: var(--fs-xs);
}

.b-btn--lg {
  --_h: var(--control-lg);
  padding: 0 var(--space-8);
  font-size: var(--fs-base);
}

.b-btn--icon {
  width: var(--_h);
  padding: 0;
}

.b-btn--block {
  display: flex;
  width: 100%;
}

.b-btn:disabled,
.b-btn[aria-disabled="true"] {
  border-color: transparent;
  background: var(--surface-3);
  color: var(--text-muted);
  cursor: not-allowed;
}

.b-btn[aria-busy="true"] {
  pointer-events: none;
}

.b-btn[aria-busy="true"]::before {
  content: "";
  flex: none;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: b-spin 0.7s linear infinite;
}

/* touch: grow the hit area to 44px without changing how the button looks */
@media (pointer: coarse) {
  .b-btn::after {
    content: "";
    position: absolute;
    inset: 50% 0 auto;
    height: max(100%, var(--tap-min));
    transform: translateY(-50%);
  }
}

@media (pointer: coarse) {
  .b-chip--toggle::before,
  .b-segmented__item::before {
    content: "";
    position: absolute;
    inset: 50% 0 auto;
    height: max(100%, var(--tap-min));
    transform: translateY(-50%);
  }
}

/* 4 ─ Field, input, textarea, select ───────────────────────────────────────
   <div class="b-field">
     <label class="b-label" for="h">Handle</label>
     <input class="b-input" id="h" aria-describedby="h-hint">
     <p class="b-hint" id="h-hint">…</p>     or  <p class="b-error" id="h-err">…</p>
   </div>                                                                      */

.b-field {
  display: grid;
  gap: var(--space-1-5);
  min-width: 0;
}

.b-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  color: var(--text);
}

.b-label__optional {
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}

.b-hint {
  font-size: var(--fs-sm);
  line-height: 1.4;
  color: var(--text-muted);
}

.b-error {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.4;
  color: var(--danger);
}

.b-input,
.b-textarea,
.b-select {
  display: block;
  width: 100%;
  min-width: 0;
  min-height: var(--control-lg);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background-color: var(--field-bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-base); /* 16px — stops iOS zooming on focus */
  line-height: var(--lh-snug);
  appearance: none;
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}

.b-input--sm,
.b-select--sm {
  min-height: var(--control-md);
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
}

.b-textarea {
  min-height: 7.5rem;
  padding-block: var(--space-3);
  line-height: var(--lh-normal);
  resize: vertical;
}

.b-input::placeholder,
.b-textarea::placeholder {
  color: var(--text-faint);
  opacity: 1;
}

.b-input:hover,
.b-textarea:hover,
.b-select:hover {
  border-color: var(--text-muted);
}

.b-input:focus-visible,
.b-textarea:focus-visible,
.b-select:focus-visible {
  border-color: var(--text);
  outline-offset: 1px;
}

/* a second hairline in the danger colour: the border reads as 2px, no halo */
.b-input[aria-invalid="true"],
.b-textarea[aria-invalid="true"],
.b-select[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: inset 0 0 0 1px var(--danger);
}

.b-input:disabled,
.b-textarea:disabled,
.b-select:disabled {
  border-color: var(--border);
  background-color: var(--surface-2);
  color: var(--text-muted);
  cursor: not-allowed;
}

.b-select {
  padding-inline-end: var(--space-10);
  cursor: pointer;
  /* chevron drawn in currentColor so it follows the theme */
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 1.25rem) 50%,
    calc(100% - 0.875rem) 50%;
  background-size: 0.375rem 0.375rem;
  background-repeat: no-repeat;
}

/* input with a leading icon: <div class="b-input-icon"><svg/><input class="b-input"></div> */
.b-input-icon {
  position: relative;
  display: block;
}

.b-input-icon > svg {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: var(--space-4);
  width: 1.125rem;
  height: 1.125rem;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}

.b-input-icon > .b-input {
  padding-inline-start: calc(var(--space-4) + 1.125rem + var(--space-2));
}

/* 5 ─ Chip ─────────────────────────────────────────────────────────────────
   Static:  <span class="b-chip">Draft</span>
   Toggle:  <button class="b-chip b-chip--toggle" aria-pressed="true">…</button>
       or   <label class="b-chip b-chip--toggle"><input type="checkbox" class="b-visually-hidden">…</label>
   The selected state adds a tick as well as colour, so it never relies on hue. */

.b-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  min-height: var(--control-sm);
  max-width: 100%;
  padding: 0 var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.1;
  white-space: nowrap;
}

.b-chip > svg {
  flex: none;
  width: 1em;
  height: 1em;
}

.b-chip--toggle {
  position: relative;
  min-height: 2.25rem;
  border-color: var(--border-strong);
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.b-chip--toggle:hover {
  background: var(--surface-2);
  border-color: var(--text);
  color: var(--text);
}

.b-chip--toggle:active {
  background: var(--surface-3);
}

/* selected: an ink outline, ink text, a tick. No tint. */
.b-chip--toggle[aria-pressed="true"],
.b-chip--toggle[aria-checked="true"],
.b-chip--toggle:has(input:checked) {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
  color: var(--text);
  font-weight: var(--fw-semibold);
}

/* the tick */
.b-chip--toggle[aria-pressed="true"]::after,
.b-chip--toggle[aria-checked="true"]::after,
.b-chip--toggle:has(input:checked)::after {
  content: "";
  flex: none;
  width: 0.875em;
  height: 0.875em;
  background: currentColor;
  clip-path: polygon(12% 52%, 26% 38%, 42% 54%, 76% 18%, 90% 32%, 42% 82%);
}

.b-chip--toggle:has(input:focus-visible) {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

.b-chip--toggle[aria-disabled="true"],
.b-chip--toggle:disabled,
.b-chip--toggle:has(input:disabled) {
  border-color: var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* 6 ─ Badge ────────────────────────────────────────────────────────────────
   <span class="b-badge b-badge--success">Published</span>
   <span class="b-badge b-badge--count" aria-label="12 unread">12</span>
   <span class="b-badge b-badge--agent">agent</span>   ← anything your AI agent did  */

.b-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  min-height: 1.375rem;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--surface-3);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  white-space: nowrap;
  vertical-align: middle;
}

.b-badge > svg {
  width: 0.9em;
  height: 0.9em;
}

.b-badge--primary {
  background: var(--primary-soft);
  color: var(--primary-text);
}

.b-badge--accent,
.b-badge--agent {
  background: var(--accent-soft);
  color: var(--accent-text);
}

/* the agent badge carries a small horn so it reads without colour */
.b-badge--agent::before {
  content: "";
  width: 0.6em;
  height: 0.8em;
  background: currentColor;
  clip-path: polygon(0 0, 55% 22%, 100% 70%, 100% 100%, 22% 100%, 18% 50%);
}

.b-badge--success {
  background: var(--success-soft);
  color: var(--success);
}

.b-badge--warning {
  background: var(--warning-soft);
  color: var(--warning);
}

.b-badge--danger {
  background: var(--danger-soft);
  color: var(--danger);
}

.b-badge--info {
  background: var(--info-soft);
  color: var(--info);
}

/* unread counter */
.b-badge--count {
  min-width: 1.25rem;
  min-height: 1.25rem;
  padding: 0 0.375rem;
  background: var(--primary);
  color: var(--primary-contrast);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

/* presence / unread dot — pair with visually hidden text */
.b-badge--dot {
  width: 0.625rem;
  min-width: 0;
  height: 0.625rem;
  min-height: 0;
  padding: 0;
  background: var(--primary);
}

/* 7 ─ Card ─────────────────────────────────────────────────────────────────
   <article class="b-card"> … </article>
   Flat: a surface and a hairline. No shadow at rest, on hover or ever.
   --interactive (whole card is a link/button) · --tint (quiet fill) ·
   --feature (ink edge; one per view) · --flat (same as the default, kept for old markup) */

.b-card {
  display: block;
  min-width: 0;
  padding: var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
}

.b-card--flat {
  /* cards are flat by default now */
}

.b-card--tint {
  background: var(--surface-2);
}

.b-card--feature {
  border-color: var(--text);
}

.b-card--interactive {
  text-decoration: none;
  cursor: pointer;
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    background-color var(--duration-fast) var(--ease-standard);
}

.b-card--interactive:hover {
  border-color: var(--text);
}

.b-card--interactive:active {
  background: var(--surface-2);
}

.b-card__header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  margin-block-end: var(--space-4);
}

.b-card__title {
  font-family: var(--font-sans);
  font-variation-settings: normal;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
}

.b-card__body {
  min-width: 0;
}

.b-card__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-4);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--border);
}

/* 8 ─ Skeleton ─────────────────────────────────────────────────────────────
   <span class="b-skeleton b-skeleton--text" style="width:60%"></span>
   Wrap a loading region in aria-busy="true" and give it a visually hidden label. */

.b-skeleton {
  display: block;
  min-height: 0.75rem;
  border-radius: var(--radius-sm);
  background: linear-gradient(100deg, var(--surface-2) 30%, var(--surface-3) 50%, var(--surface-2) 70%) 0 0 / 300% 100%;
  animation: b-shimmer 1.6s linear infinite;
}

.b-skeleton--text {
  height: 0.75em;
  margin-block: 0.4em;
  border-radius: var(--radius-full);
}

.b-skeleton--circle {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
}

.b-skeleton--block {
  height: 9rem;
  border-radius: var(--radius-md);
}

@keyframes b-shimmer {
  from {
    background-position: 100% 0;
  }
  to {
    background-position: -50% 0;
  }
}

/* 9 ─ Avatar ───────────────────────────────────────────────────────────────
   <span class="b-avatar" data-platform="instagram">
     <img src="…" alt="">          (or initials as text)
     <span class="b-avatar__dot" aria-hidden="true"></span>
   </span>
   Sizes: --xs 24 · --sm 32 · (default 40) · --lg 56 · --xl 72
   --ring: a hairline ring in the signature colour = has something new          */

.b-avatar {
  --_size: 2.5rem;
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: var(--_size);
  height: var(--_size);
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: calc(var(--_size) * 0.38);
  font-weight: var(--fw-semibold);
  line-height: 1;
  text-transform: uppercase;
  user-select: none;
}

.b-avatar > img {
  width: 100%;
  height: 100%;
  border-radius: inherit;
  object-fit: cover;
}

.b-avatar--xs {
  --_size: 1.5rem;
}

.b-avatar--sm {
  --_size: 2rem;
}

.b-avatar--lg {
  --_size: 3.5rem;
}

.b-avatar--xl {
  --_size: 4.5rem;
}

.b-avatar--accent {
  background: var(--accent-soft);
  color: var(--accent-text);
}

/* which platform this account lives on */
.b-avatar__dot {
  position: absolute;
  inset-block-end: -2px;
  inset-inline-end: -2px;
  display: grid;
  place-items: center;
  width: max(0.75rem, calc(var(--_size) * 0.36));
  height: max(0.75rem, calc(var(--_size) * 0.36));
  border-radius: 50%;
  background: var(--_platform, var(--text-muted));
  color: var(--surface);
  box-shadow: 0 0 0 2px var(--surface);
}

.b-avatar__dot > svg {
  width: 62%;
  height: 62%;
}

.b-avatar--ring::before {
  content: "";
  position: absolute;
  inset: -4px;
  border: 1.5px solid var(--primary);
  border-radius: 50%;
}

.b-avatar-stack {
  display: inline-flex;
}

.b-avatar-stack > .b-avatar {
  box-shadow: 0 0 0 2px var(--surface);
}

.b-avatar-stack > .b-avatar + .b-avatar {
  margin-inline-start: calc(var(--_size) * -0.18);
}

/* 10 ─ Platform ────────────────────────────────────────────────────────────
   Put data-platform on the element or any ancestor; children read --_platform.
   <span class="b-platform" data-platform="bluesky">Bluesky</span>
   <span class="b-platform-dot" data-platform="youtube"></span>
   Platform colours identify platforms. They are never decoration.              */

[data-platform="facebook"] {
  --_platform: var(--platform-facebook);
}
[data-platform="instagram"] {
  --_platform: var(--platform-instagram);
}
[data-platform="youtube"] {
  --_platform: var(--platform-youtube);
}
[data-platform="tiktok"] {
  --_platform: var(--platform-tiktok);
}
[data-platform="bluesky"] {
  --_platform: var(--platform-bluesky);
}
[data-platform="mastodon"] {
  --_platform: var(--platform-mastodon);
}
[data-platform="telegram"] {
  --_platform: var(--platform-telegram);
}
[data-platform="whatsapp"] {
  --_platform: var(--platform-whatsapp);
}
[data-platform="x"] {
  --_platform: var(--platform-x);
}
[data-platform="threads"] {
  --_platform: var(--platform-threads);
}
[data-platform="linkedin"] {
  --_platform: var(--platform-linkedin);
}

/* A neutral hairline pill. The platform's colour is the dot (or the icon),
   the name is ink: identity without a row of coloured labels. */
.b-platform {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  min-height: 1.625rem;
  max-width: 100%;
  padding: 0 var(--space-3) 0 var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1;
  white-space: nowrap;
}

.b-platform::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--_platform, var(--text-muted));
}

.b-platform:has(> svg)::before {
  display: none;
}

.b-platform > svg {
  flex: none;
  width: 0.875rem;
  height: 0.875rem;
  color: var(--_platform, var(--text-muted));
}

.b-platform--solid {
  border-color: transparent;
  background: var(--_platform, var(--text-muted));
  color: var(--surface);
}

.b-platform--solid::before {
  background: currentColor;
}

.b-platform--solid > svg {
  color: inherit;
}

.b-platform-dot {
  display: inline-block;
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--_platform, var(--text-muted));
}

/* 11 ─ Tabs ────────────────────────────────────────────────────────────────
   <div class="b-tabs" role="tablist" aria-label="Inbox">
     <button class="b-tab" role="tab" aria-selected="true">All</button> …
   Arrow-key roving focus is the app's job (WAI-ARIA tabs pattern).             */

.b-tabs {
  display: flex;
  gap: var(--space-1);
  min-width: 0;
  border-block-end: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}

.b-tabs::-webkit-scrollbar {
  display: none;
}

.b-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
  min-height: var(--tap-min);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-standard);
}

.b-tab:hover {
  color: var(--text);
}

.b-tab:focus-visible {
  outline-offset: -3px;
}

.b-tab::after {
  content: "";
  position: absolute;
  inset: auto var(--space-3) 0;
  height: 2px;
  background: var(--text);
  transform: scaleX(0);
  transition: transform var(--duration-base) var(--ease-out);
}

.b-tab[aria-selected="true"],
.b-tab[aria-current="page"] {
  color: var(--text);
  font-weight: var(--fw-semibold);
}

.b-tab[aria-selected="true"]::after,
.b-tab[aria-current="page"]::after {
  transform: scaleX(1);
}

/* 12 ─ Segmented control ───────────────────────────────────────────────────
   <div class="b-segmented" role="radiogroup" aria-label="Theme">
     <button class="b-segmented__item" role="radio" aria-checked="true">System</button> …  */

.b-segmented {
  display: inline-flex;
  gap: 2px;
  max-width: 100%;
  padding: 3px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  background: var(--surface);
}

.b-segmented__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1-5);
  position: relative;
  flex: 1 1 auto;
  min-height: var(--control-sm);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.b-segmented__item > svg {
  width: 1rem;
  height: 1rem;
}

.b-segmented__item:hover {
  color: var(--text);
  background: var(--surface-2);
}

.b-segmented__item[aria-checked="true"],
.b-segmented__item[aria-pressed="true"],
.b-segmented__item[aria-selected="true"] {
  background: var(--ink);
  color: var(--ink-contrast);
  font-weight: var(--fw-semibold);
}

/* 13 ─ Alert ───────────────────────────────────────────────────────────────
   Inline, persistent message. This is where the voice goes plain and precise.
   <div class="b-alert b-alert--danger" role="alert">
     <svg class="b-alert__icon">…</svg>
     <div><p class="b-alert__title">…</p><p>…</p></div>
   </div>                                                                       */

.b-alert {
  --_c: var(--text-muted);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-sm);
  line-height: 1.45;
}

.b-alert > div {
  flex: 1;
  min-width: 0;
}

.b-alert__icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-block-start: 0.05rem;
  color: var(--_c);
}

.b-alert__title {
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.b-alert--info {
  --_c: var(--info);
  border-color: var(--info-border);
  background: var(--info-soft);
}

.b-alert--success {
  --_c: var(--success);
  border-color: var(--success-border);
  background: var(--success-soft);
}

.b-alert--warning {
  --_c: var(--warning);
  border-color: var(--warning-border);
  background: var(--warning-soft);
}

.b-alert--danger {
  --_c: var(--danger);
  border-color: var(--danger-border);
  background: var(--danger-soft);
}

/* 14 ─ Toast ───────────────────────────────────────────────────────────────
   <div class="b-toast-region" role="region" aria-label="Notifications">
     <div class="b-toast b-toast--success" role="status">
       <span class="b-toast__icon"><svg/></span>
       <div class="b-toast__content"><p class="b-toast__title">…</p><p class="b-toast__text">…</p></div>
       <button class="b-btn b-btn--ghost b-btn--sm b-btn--icon" aria-label="Dismiss">×</button>
     </div>
   </div>
   Use role="alert" only for --danger. Never auto-dismiss a toast that has an action. */

.b-toast-region {
  position: fixed;
  inset-block-end: var(--space-4);
  inset-inline-end: var(--space-4);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: min(24rem, calc(100vw - var(--space-8)));
  pointer-events: none;
}

.b-toast-region > * {
  pointer-events: auto;
}

.b-toast {
  --_c: var(--text);
  --_soft: var(--surface-2);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  padding-inline-start: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-elevated);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  animation: b-toast-in var(--duration-slow) var(--ease-out) both;
}

.b-toast__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--_soft);
  color: var(--_c);
}

.b-toast__icon > svg {
  width: 1.125rem;
  height: 1.125rem;
}

.b-toast__content {
  flex: 1;
  min-width: 0;
  padding-block-start: 0.2rem;
}

.b-toast__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
}

.b-toast__text {
  margin-block-start: 2px;
  font-size: var(--fs-sm);
  line-height: 1.4;
  color: var(--text-muted);
}

.b-toast__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
}

.b-toast--success {
  --_c: var(--success);
  --_soft: var(--success-soft);
}

.b-toast--warning {
  --_c: var(--warning);
  --_soft: var(--warning-soft);
}

.b-toast--danger {
  --_c: var(--danger);
  --_soft: var(--danger-soft);
  border-color: var(--danger-border);
}

.b-toast--info {
  --_c: var(--info);
  --_soft: var(--info-soft);
}

@keyframes b-toast-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

@media (max-width: 480px) {
  .b-toast-region {
    inset-inline: var(--space-3);
    inset-block-end: var(--space-3);
    width: auto;
  }
}

/* 15 ─ Modal ───────────────────────────────────────────────────────────────
   Preferred: the native element, opened with showModal() (focus trap + Esc for free).
   <dialog class="b-modal" aria-labelledby="t">
     <div class="b-modal__header"><h2 class="b-modal__title" id="t">…</h2></div>
     <div class="b-modal__body">…</div>
     <div class="b-modal__footer"><button class="b-btn">Cancel</button><button class="b-btn b-btn--danger">Delete post</button></div>
   </dialog>
   Without <dialog>: wrap .b-modal in .b-modal-backdrop and manage focus yourself. */

.b-modal {
  width: min(32.5rem, calc(100vw - var(--space-8)));
  max-width: none;
  max-height: min(85dvh, 45rem);
  margin: auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--bg-elevated);
  color: var(--text);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
}

.b-modal[open],
.b-modal-backdrop > .b-modal,
div.b-modal {
  display: flex;
  flex-direction: column;
}

.b-modal[open] {
  animation: b-modal-in var(--duration-slow) var(--ease-out) both;
}

.b-modal::backdrop {
  background: var(--scrim);
}

.b-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: var(--scrim);
}

.b-modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-6) 0;
}

/* a dialog asks for a decision, so its title is plain: the sans, not the serif */
.b-modal__title {
  font-family: var(--font-sans);
  font-variation-settings: normal;
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
}

.b-modal__body {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-6) var(--space-2);
  color: var(--text-muted);
  overflow-y: auto;
}

.b-modal__body strong {
  color: var(--text);
}

.b-modal__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6) var(--space-6);
}

@keyframes b-modal-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

@media (max-width: 480px) {
  .b-modal {
    width: calc(100vw - var(--space-6));
    border-radius: var(--radius-lg);
  }

  .b-modal__header {
    padding: var(--space-5) var(--space-5) 0;
  }

  .b-modal__body {
    padding-inline: var(--space-5);
  }

  /* stacked in the order they are written, so what you see is the order focus moves in:
     the safe choice first, the action under it, both full-width thumb targets */
  .b-modal__footer {
    flex-direction: column;
    padding: var(--space-4) var(--space-5) var(--space-5);
  }

  .b-modal__footer > .b-btn {
    width: 100%;
    min-height: var(--control-lg);
  }
}

/* 16 ─ Empty state ─────────────────────────────────────────────────────────
   Where the brand gets to speak: the title is in the serif. One line of
   personality, one clear action. The art is a plain glyph in a hairline ring.
   <div class="b-empty">
     <div class="b-empty__art"><svg/></div>
     <h3 class="b-empty__title">Inbox zero. Iconic.</h3>
     <p class="b-empty__text">…</p>
     <div class="b-empty__actions"><button class="b-btn b-btn--primary">…</button></div>
   </div>                                                                       */

.b-empty {
  display: grid;
  justify-items: center;
  gap: var(--space-2);
  max-width: 26rem;
  margin-inline: auto;
  padding: var(--space-10) var(--space-5);
  text-align: center;
}

.b-empty__art {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  margin-block-end: var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  color: var(--text);
}

.b-empty__art > svg {
  width: 1.75rem;
  height: 1.75rem;
}

.b-empty__title {
  font-family: var(--font-display);
  font-variation-settings: "opsz" var(--opsz-title);
  font-size: var(--fs-3xl);
  font-weight: var(--fw-display);
  line-height: 1.12;
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
}

.b-empty__text {
  color: var(--text-muted);
}

.b-empty__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-block-start: var(--space-4);
}

/* 17 ─ Tooltip ─────────────────────────────────────────────────────────────
   <span class="b-tooltip">
     <button class="b-btn b-btn--icon" aria-describedby="tip-1">…</button>
     <span class="b-tooltip__bubble" role="tooltip" id="tip-1">Schedule for later</span>
   </span>
   Shows on hover and keyboard focus, stays while hovered. Placement: --bottom, --start, --end.
   Supplementary text only — never the sole place a critical instruction lives.  */

.b-tooltip {
  position: relative;
  display: inline-flex;
}

.b-tooltip__bubble {
  position: absolute;
  inset-block-end: calc(100% + var(--space-2));
  inset-inline-start: 50%;
  z-index: var(--z-tooltip);
  width: max-content;
  max-width: min(16rem, 80vw);
  padding: var(--space-1-5) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--bg-inverse);
  color: var(--text-inverse);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.35;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, calc(4px * var(--motion-scale)));
  transition:
    opacity var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-out),
    visibility 0s linear var(--duration-fast);
}

.b-tooltip:hover > .b-tooltip__bubble,
.b-tooltip:focus-within > .b-tooltip__bubble,
.b-tooltip__bubble[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
}

.b-tooltip--bottom > .b-tooltip__bubble {
  inset-block: calc(100% + var(--space-2)) auto;
}

.b-tooltip--start > .b-tooltip__bubble {
  inset-inline-start: 0;
  transform: translate(0, calc(4px * var(--motion-scale)));
}

.b-tooltip--end > .b-tooltip__bubble {
  inset-inline: auto 0;
  transform: translate(0, calc(4px * var(--motion-scale)));
}

.b-tooltip--start:hover > .b-tooltip__bubble,
.b-tooltip--start:focus-within > .b-tooltip__bubble,
.b-tooltip--end:hover > .b-tooltip__bubble,
.b-tooltip--end:focus-within > .b-tooltip__bubble {
  transform: none;
}

/* 18 ─ Switch, checkbox, radio ─────────────────────────────────────────────
   <label class="b-switch-row">
     <input type="checkbox" role="switch" class="b-switch" checked>
     <span>Ask before the agent posts</span>
   </label>                                                                     */

.b-switch {
  position: relative;
  flex: none;
  width: 2.75rem;
  height: 1.625rem;
  margin: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--border-strong);
  appearance: none;
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-standard);
}

.b-switch::before {
  content: "";
  position: absolute;
  inset-block-start: 3px;
  inset-inline-start: 3px;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: var(--surface);
  transition: transform var(--duration-base) var(--ease-out);
}

.b-switch:checked {
  background: var(--ink);
}

.b-switch:checked::before {
  background: var(--ink-contrast);
  transform: translateX(1.125rem);
}

/* a tick in the thumb, so "on" never depends on colour alone */
.b-switch:checked::after {
  content: "";
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-start: 1.625rem;
  width: 0.625rem;
  height: 0.625rem;
  background: var(--ink);
  clip-path: polygon(10% 52%, 26% 36%, 42% 54%, 76% 16%, 92% 32%, 42% 84%);
}

.b-switch:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.b-switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--tap-min);
  cursor: pointer;
}

.b-switch-row > :not(.b-switch) {
  flex: 1;
  min-width: 0;
}

.b-checkbox,
.b-radio {
  position: relative;
  flex: none;
  width: 1.375rem;
  height: 1.375rem;
  margin: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-xs);
  background: var(--field-bg);
  appearance: none;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard);
}

.b-radio {
  border-radius: 50%;
}

.b-checkbox:checked,
.b-radio:checked {
  border-color: var(--ink);
  background: var(--ink);
}

.b-checkbox:checked::before {
  content: "";
  position: absolute;
  inset: 3px;
  background: var(--ink-contrast);
  clip-path: polygon(10% 52%, 24% 38%, 42% 56%, 78% 16%, 92% 30%, 42% 84%);
}

.b-radio:checked::before {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: var(--ink-contrast);
}

.b-checkbox:disabled,
.b-radio:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.b-check-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--tap-min);
  padding-block: var(--space-2);
  cursor: pointer;
}

/* 19 ─ Sidebar & nav item ──────────────────────────────────────────────────
   <nav class="b-sidebar" aria-label="Main">
     <a class="b-nav-item" href="/inbox" aria-current="page">
       <svg class="b-nav-item__icon"/> <span class="b-nav-item__label">Inbox</span>
       <span class="b-badge b-badge--count">12</span>
     </a>
   </nav>                                                                       */

.b-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: var(--sidebar-w);
  max-width: 100%;
  padding: var(--space-4) var(--space-3);
  border-inline-end: 1px solid var(--border);
  background: var(--surface);
}

.b-sidebar__section {
  margin-block-start: var(--space-4);
  padding: 0 var(--space-3) var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}

.b-nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--tap-min);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.b-nav-item:hover {
  background: var(--surface-2);
  color: var(--text);
}

.b-nav-item:focus-visible {
  outline-offset: -1px;
}

/* current page: a quiet fill and heavier ink. Two signals, neither of them a
   colour, and no stripe down the side. */
.b-nav-item[aria-current="page"],
.b-nav-item[aria-selected="true"] {
  background: var(--surface-2);
  color: var(--text);
  font-weight: var(--fw-semibold);
}

.b-nav-item__icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

.b-nav-item__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 20 ─ Row (inbox thread, account, notification) ───────────────────────────
   <a class="b-row" href="…" data-unread="true">
     <span class="b-avatar" data-platform="instagram">…</span>
     <span class="b-row__body">
       <span class="b-row__title">Maya Okafor</span>
       <span class="b-row__text">is the lilac one restocking?</span>
     </span>
     <span class="b-row__meta"><time>2m</time><span class="b-badge b-badge--count">2</span></span>
   </a>                                                                         */

.b-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 4rem;
  padding: var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-standard);
}

.b-row:hover {
  background: var(--surface-2);
}

.b-row:focus-visible {
  outline-offset: -1px;
}

/* the open conversation keeps the fill a hovered row gets, and steps it up on hover */
.b-row[aria-current="true"],
.b-row[aria-selected="true"] {
  background: var(--surface-2);
}

.b-row[aria-current="true"]:hover,
.b-row[aria-selected="true"]:hover {
  background: var(--surface-3);
}

.b-row__body {
  display: grid;
  flex: 1;
  gap: 2px;
  min-width: 0;
}

.b-row__title {
  overflow: hidden;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.b-row__text {
  overflow: hidden;
  font-size: var(--fs-sm);
  line-height: 1.4;
  color: var(--text-muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.b-row__meta {
  display: grid;
  flex: none;
  justify-items: end;
  gap: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  white-space: nowrap;
}

/* unread = heavier type + counter/dot; weight carries it without colour */
.b-row[data-unread="true"] .b-row__title {
  font-weight: var(--fw-bold);
}

.b-row[data-unread="true"] .b-row__text {
  color: var(--text);
  font-weight: var(--fw-medium);
}

/* 21 ─ Bits ────────────────────────────────────────────────────────────── */

.b-spinner {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  border: 2px solid var(--surface-3);
  border-top-color: var(--text);
  border-radius: 50%;
  animation: b-spin 0.8s linear infinite;
}

@keyframes b-spin {
  to {
    transform: rotate(360deg);
  }
}

.b-kbd {
  display: inline-block;
  min-width: 1.5em;
  padding: 0.1em 0.4em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.8125em;
  line-height: 1.4;
  text-align: center;
}

.b-divider {
  height: 1px;
  margin: 0;
  border: 0;
  background: var(--border);
}

/* success moment: add to an icon or badge when something lands.
   It settles into place; it does not bounce. */
.b-pop {
  animation: b-pop var(--duration-slow) var(--ease-out) both;
}

@keyframes b-pop {
  from {
    opacity: 0;
    transform: scale(0.92);
  }
}

/* 22 ─ Stage, shade, quote ─────────────────────────────────────────────────
   Stage: a black plate inside any page, in either theme. The one place a page
   goes dark on purpose, the way a campaign does.
     <section class="b-stage" data-theme="dark"> … </section>
   data-theme="dark" switches every token inside it; .b-stage paints the plate.
   A stage that carries the gradient mark has no brand button: the mark is its
   one signature moment, and its main action is .b-btn--primary.

   Shade: a section filled flat with the signature colour, pink by day and
   purple by night. It IS that view's one signature moment, so nothing else in
   the view uses the colour. For marketing and for a welcome, never inside a
   working screen. Its main button turns inside out.
     <section class="b-shade"> <h2>…</h2> <a class="b-btn b-btn--primary">…</a> </section>

   Quote: the exact words of something, shown in full. --agent marks words your
   agent wrote. A fill and a hairline all round, never a stripe down one side.
     <blockquote class="b-quote b-quote--agent">…</blockquote>                 */

.b-stage {
  background: var(--bg);
  color: var(--text);
}

.b-shade {
  background: var(--primary);
  color: var(--primary-contrast);
}

.b-shade ::selection {
  background: var(--primary-contrast);
  color: var(--primary-text);
}

.b-shade .b-btn--primary,
.b-shade .b-btn--primary:hover,
.b-shade .b-btn--primary:active {
  border-color: var(--primary-contrast);
  background: var(--primary-contrast);
  color: var(--primary-text);
}

.b-shade .b-btn--primary:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.b-shade :focus-visible {
  outline-color: var(--primary-contrast);
}

.b-quote {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--text);
  overflow-wrap: anywhere;
}

.b-quote--agent {
  border-color: var(--accent-border);
  background: var(--accent-soft);
}

/* 23 ─ Reduced motion, forced colours ──────────────────────────────────────
   tokens.css already zeroes the duration tokens; this catches hard-coded loops. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .b-skeleton {
    animation: none !important;
    background: var(--surface-3);
  }

  /* a spinner is information, not decoration: keep it, slowly */
  .b-spinner,
  .b-btn[aria-busy="true"]::before {
    animation-duration: 2.4s !important;
    animation-iteration-count: infinite !important;
  }
}

@media (forced-colors: active) {
  .b-btn,
  .b-chip,
  .b-badge,
  .b-platform,
  .b-segmented__item,
  .b-nav-item,
  .b-switch {
    border: 1px solid ButtonText;
  }

  .b-btn--primary,
  .b-btn--brand,
  .b-segmented__item[aria-checked="true"],
  .b-segmented__item[aria-pressed="true"],
  .b-segmented__item[aria-selected="true"],
  .b-chip--toggle[aria-pressed="true"],
  .b-chip--toggle:has(input:checked),
  .b-nav-item[aria-current="page"] {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    border-color: Highlight;
  }

  .b-switch::before {
    background: ButtonText;
  }
}
