/* Bridge Design System: generated from tokens.json by build/build-tokens.mjs */
@font-face {
  font-family: 'Roboto';
  src: local('Roboto'), local('Roboto Regular'), local('Roboto-Regular'), url('fonts/Roboto-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  ascent-override: 95.2%;
  descent-override: 21.3%;
  line-gap-override: 2.8%;
  font-display: swap;
}
@font-face {
  font-family: 'Roboto';
  src: local('Roboto Medium'), local('Roboto-Medium'), url('fonts/Roboto-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  ascent-override: 97.5%;
  descent-override: 21.7%;
  line-gap-override: 2.9%;
  font-display: swap;
}
@font-face {
  font-family: 'Roboto';
  src: local('Roboto Italic'), local('Roboto-Italic'), url('fonts/Roboto-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  ascent-override: 95.7%;
  descent-override: 21.3%;
  line-gap-override: 2.8%;
  font-display: swap;
}
@font-face {
  font-family: 'Roboto';
  src: local('Roboto Medium Italic'), local('Roboto-MediumItalic'), url('fonts/Roboto-MediumItalic.woff2') format('woff2');
  font-weight: 500;
  font-style: italic;
  ascent-override: 97.5%;
  descent-override: 21.7%;
  line-gap-override: 2.9%;
  font-display: swap;
}
:root, [data-theme="light"] {
  --brand-primary: #3e6ee5; /* Primary buttons, active navigation glyphs, checked controls, focus, the active sort glyph. White text on it reads 4.6:1 (light) and 4.95:1 (dark). A fill and icon colour: small text in the brand colour uses text-brand (links use text-link), which is tuned to 4.5:1 on every ground. */
  --brand-primary-hover: #2f58c4; /* Hover of the primary button fill. It darkens in both themes, so white text on it reads 6.3:1 (light) and 6.0:1 (dark). Not a text colour: link hover is text-link-hover. */
  --brand-primary-soft: #eaf1fd; /* Soft brand fill: the active row of the Bridge App menu (through nav-item-active-bg), selected and brand-tone chips, own message bubbles, count badges, the drag-over dropzone. Text on it is text-primary (15:1 light, 12.4:1 dark); brand-primary text on it reads 4.05:1 light and 3.06:1 dark. */
  --brand-primary-subtle: #f0f5fe; /* The lightest step of the brand blue, between bg-subtle and brand-primary-soft: the ground of a selected row (through row-selected: the selected table row, the selected conversation row, the open chat of the chat list). Text on it: text-primary (15.6:1 light, 10.3:1 dark) and text-secondary (4.95:1, 5.65:1); brand text takes text-link-hover (4.5:1 or more in both themes). */
  --brand-primary-border: #d6e2f4; /* Border of Container (r12 on bg-subtle), brand-tone attribute chips, the bulk action bar and the filter bar. Decorative separation, never a state. */
  --brand-primary-dark: #0e2841; /* Deep navy accent: the bulk action bar count and the bullet chart target marker. Lifts to a light blue in dark so it keeps reading on bg-app. */
  --brand-teal: #3a8a9c; /* Illustration tile only (EmptyState, NoPermissionState): the 32px outline icon and the 14% inset wash. Never text, never data. */
  --brand-teal-light: #7ad6e3; /* Illustration tile only: the 76px r20 square wash at 16%. Never text, never data. */
  --brand-teal-soft: #e3f3f6; /* Brand teal, soft ground: the teal twin of brand-primary-soft, a tinted circle or band in the family of the Bridge isotipo. Carries brand-teal-ink (6.2:1 light, 7.6:1 dark) and text-brand (4.6:1 light). Never a state. */
  --brand-teal-ink: #22606e; /* Brand teal for a glyph or text on a soft ground: brand-teal tuned to read 4.5:1 or more on brand-teal-soft (6.2:1 light, 7.6:1 dark) and on bg-app. brand-teal itself reads 3.5:1 there, too little for a glyph. */
  --data-blue-1: #16306b; /* Legacy sequential blue scale, step 1 (darkest). Kept for older consumers; no chart uses it. New work reads Data · Sequential: data-seq-1…5. */
  --data-blue-2: #213d84; /* Legacy sequential blue scale, step 2. Kept for older consumers; no chart uses it. New work: data-seq-1…5. */
  --data-blue-3: #2b5ea7; /* Legacy sequential blue scale, step 3. Kept for older consumers; no chart uses it. New work: data-seq-1…5. */
  --data-blue-4: #5c8ac8; /* Legacy sequential blue scale, step 4. Kept for older consumers; no chart uses it. New work: data-seq-1…5. */
  --data-blue-5: #93b4df; /* Legacy sequential blue scale, step 5. Kept for older consumers; no chart uses it. New work: data-seq-1…5. */
  --data-blue-6: #d6e2f4; /* Legacy sequential blue scale, step 6 (lightest). Kept for older consumers; no chart uses it. New work: data-seq-1…5. */
  --data-teal: #3a8a9c; /* Legacy data teal. Kept for older consumers; no chart uses it. New work: data-cat-6. */
  --data-teal-light: #7ad6e3; /* Legacy light data teal. Kept for older consumers; no chart uses it. */
  --data-slate: #5a6b85; /* Legacy data slate. Kept for older consumers; no chart uses it. */
  --data-other: #d4d2c9; /* The aggregated tail when a chart has more than six series (the "Other" band, slice or segment) and its legend dot. Never a series of its own. */
  --data-cat-1: #3e6ee5; /* Bridge Blue. Categorical data palette (Color 4 · midpoint): Reporting & Dashboards only: series fills, strokes, donut slices, distribution bars, bubbles by segment. Never for states, participants or the intensity of one metric (that is data-seq-*). Used at: 1 · 2 · 3 · 4 · 5–6 series. Neighbours sit 8.4–9.3 ΔE (OKLab) apart in light and 9.4–16.5 in dark, any two slots ≥ 8.4 / ≥ 7.6, so stacked and adjacent segments stay distinct. 4.6:1 on bg-app in light. */
  --data-cat-2: #498cff; /* Bright Azure. Categorical data palette (Color 4 · midpoint): Reporting & Dashboards only: series fills, strokes, donut slices, distribution bars, bubbles by segment. Never for states, participants or the intensity of one metric (that is data-seq-*). Used at: 4 · 5–6 series. Neighbours sit 8.4–9.3 ΔE (OKLab) apart in light and 9.4–16.5 in dark, any two slots ≥ 8.4 / ≥ 7.6, so stacked and adjacent segments stay distinct. 3.2:1 on bg-app in light. */
  --data-cat-3: #2489ca; /* Vivid Cerulean. Categorical data palette (Color 4 · midpoint): Reporting & Dashboards only: series fills, strokes, donut slices, distribution bars, bubbles by segment. Never for states, participants or the intensity of one metric (that is data-seq-*). Used at: 3 · 5–6 series. Neighbours sit 8.4–9.3 ΔE (OKLab) apart in light and 9.4–16.5 in dark, any two slots ≥ 8.4 / ≥ 7.6, so stacked and adjacent segments stay distinct. 3.8:1 on bg-app in light. */
  --data-cat-4: #00aae6; /* Bright Cyan. Categorical data palette (Color 4 · midpoint): Reporting & Dashboards only: series fills, strokes, donut slices, distribution bars, bubbles by segment. Never for states, participants or the intensity of one metric (that is data-seq-*). Used at: 2 · 4 · 5–6 series. Neighbours sit 8.4–9.3 ΔE (OKLab) apart in light and 9.4–16.5 in dark, any two slots ≥ 8.4 / ≥ 7.6, so stacked and adjacent segments stay distinct. 2.7:1 on bg-app in light. Below 3:1 there: never the only carrier of meaning, always pair it with a label, direct value or legend. */
  --data-cat-5: #00c6db; /* Vivid Aqua. Categorical data palette (Color 4 · midpoint): Reporting & Dashboards only: series fills, strokes, donut slices, distribution bars, bubbles by segment. Never for states, participants or the intensity of one metric (that is data-seq-*). Used at: 5–6 series. Neighbours sit 8.4–9.3 ΔE (OKLab) apart in light and 9.4–16.5 in dark, any two slots ≥ 8.4 / ≥ 7.6, so stacked and adjacent segments stay distinct. 2.1:1 on bg-app in light. Below 3:1 there: never the only carrier of meaning, always pair it with a label, direct value or legend. */
  --data-cat-6: #56e0d7; /* Cool Teal. Categorical data palette (Color 4 · midpoint): Reporting & Dashboards only: series fills, strokes, donut slices, distribution bars, bubbles by segment. Never for states, participants or the intensity of one metric (that is data-seq-*). Used at: 3 · 4 · 5–6 series. Neighbours sit 8.4–9.3 ΔE (OKLab) apart in light and 9.4–16.5 in dark, any two slots ≥ 8.4 / ≥ 7.6, so stacked and adjacent segments stay distinct. 1.6:1 on bg-app in light. Below 3:1 there: never the only carrier of meaning, always pair it with a label, direct value or legend. */
  --data-cat-ink-1: #3569e3; /* Bridge Blue ink; same hue as data-cat-1, for text, labels, legend text, direct values and 1–1.5px lines; never a fill. ≥4.6:1 on bg-app and bg-subtle in both themes (4.9 and 4.7:1 light, 5.4 and 4.9:1 dark), so any size of text reads on either ground. */
  --data-cat-ink-2: #2a6ddf; /* Bright Azure ink; same hue as data-cat-2, for text, labels, legend text, direct values and 1–1.5px lines; never a fill. ≥4.6:1 on bg-app and bg-subtle in both themes (4.8 and 4.6:1 light, 8.0 and 7.3:1 dark), so any size of text reads on either ground. */
  --data-cat-ink-3: #0777b6; /* Vivid Cerulean ink; same hue as data-cat-3, for text, labels, legend text, direct values and 1–1.5px lines; never a fill. ≥4.6:1 on bg-app and bg-subtle in both themes (4.9 and 4.6:1 light, 5.1 and 4.6:1 dark), so any size of text reads on either ground. */
  --data-cat-ink-4: #057aa6; /* Bright Cyan ink; same hue as data-cat-4, for text, labels, legend text, direct values and 1–1.5px lines; never a fill. ≥4.6:1 on bg-app and bg-subtle in both themes (4.8 and 4.6:1 light, 6.7 and 6.0:1 dark), so any size of text reads on either ground. */
  --data-cat-ink-5: #057d8b; /* Vivid Aqua ink; same hue as data-cat-5, for text, labels, legend text, direct values and 1–1.5px lines; never a fill. ≥4.6:1 on bg-app and bg-subtle in both themes (4.9 and 4.7:1 light, 9.7 and 8.8:1 dark), so any size of text reads on either ground. */
  --data-cat-ink-6: #017f79; /* Cool Teal ink; same hue as data-cat-6, for text, labels, legend text, direct values and 1–1.5px lines; never a fill. ≥4.6:1 on bg-app and bg-subtle in both themes (4.9 and 4.7:1 light, 12.9 and 11.7:1 dark), so any size of text reads on either ground. */
  --data-seq-1: #dff4fe; /* Data · Sequential (cool cyan), level 1 of 5: the intensity of ONE metric (Heatmap cells and legend). Level 0 (empty / zero) is bg-subtle with text-muted. Magnitude, never a judgement: no semantic variant. Text on it is data-seq-ink-1. */
  --data-seq-2: #b6e3f8; /* Data · Sequential (cool cyan), level 2 of 5: the intensity of ONE metric (Heatmap cells and legend). Level 0 (empty / zero) is bg-subtle with text-muted. Magnitude, never a judgement: no semantic variant. Text on it is data-seq-ink-2. */
  --data-seq-3: #7dc9ec; /* Data · Sequential (cool cyan), level 3 of 5: the intensity of ONE metric (Heatmap cells and legend). Level 0 (empty / zero) is bg-subtle with text-muted. Magnitude, never a judgement: no semantic variant. Text on it is data-seq-ink-3. */
  --data-seq-4: #3aaad7; /* Data · Sequential (cool cyan), level 4 of 5: the intensity of ONE metric (Heatmap cells and legend). Level 0 (empty / zero) is bg-subtle with text-muted. Magnitude, never a judgement: no semantic variant. Text on it is data-seq-ink-4. */
  --data-seq-5: #067ca3; /* Data · Sequential (cool cyan), level 5 of 5: the intensity of ONE metric (Heatmap cells and legend). Level 0 (empty / zero) is bg-subtle with text-muted. Magnitude, never a judgement: no semantic variant. Text on it is data-seq-ink-5. */
  --data-seq-ink-1: #0e374e; /* Value printed on data-seq-1: same-family deep cyan ink. 11.1:1 light, 11.7:1 dark. 11px regular, tabular figures. */
  --data-seq-ink-2: #0e374e; /* Value printed on data-seq-2: same-family deep cyan ink. 9.2:1 light, 8.4:1 dark. 11px regular, tabular figures. */
  --data-seq-ink-3: #0e374e; /* Value printed on data-seq-3: same-family deep cyan ink. 6.8:1 light, 5.5:1 dark. 11px regular, tabular figures. */
  --data-seq-ink-4: #0e374e; /* Value printed on data-seq-4: same-family deep cyan ink. 4.7:1 light, 4.9:1 dark. 11px regular, tabular figures. */
  --data-seq-ink-5: #ffffff; /* Value printed on data-seq-5: same-family deep cyan ink (white in light at level 5). 4.8:1 light, 7.3:1 dark. 11px regular, tabular figures. */
  --data-seq-ring: #0e374e; /* Hover ring of a sequential cell: box-shadow 0 0 0 2px bg-app, 0 0 0 3.5px data-seq-ring. Same ink as data-seq-ink-1, so the focus reads on every level. */
  --data-stage-1: #009ace; /* Data · Sequential ordered progression, stage 1: Funnel / journey bars, one step of the cyan family per stage (stage 1 strongest). Position in the flow, never success or failure; stages past 5 keep data-stage-5. Bars carry no text: the value sits above the bar. */
  --data-stage-2: #30a8da; /* Data · Sequential ordered progression, stage 2: Funnel / journey bars, one step of the cyan family per stage (stage 1 strongest). Position in the flow, never success or failure; stages past 5 keep data-stage-5. Bars carry no text: the value sits above the bar. */
  --data-stage-3: #5bbcea; /* Data · Sequential ordered progression, stage 3: Funnel / journey bars, one step of the cyan family per stage (stage 1 strongest). Position in the flow, never success or failure; stages past 5 keep data-stage-5. Bars carry no text: the value sits above the bar. */
  --data-stage-4: #85cff4; /* Data · Sequential ordered progression, stage 4: Funnel / journey bars, one step of the cyan family per stage (stage 1 strongest). Position in the flow, never success or failure; stages past 5 keep data-stage-5. Bars carry no text: the value sits above the bar. */
  --data-stage-5: #a8dffb; /* Data · Sequential ordered progression, stage 5: Funnel / journey bars, one step of the cyan family per stage (stage 1 strongest). Position in the flow, never success or failure; stages past 5 keep data-stage-5. Bars carry no text: the value sits above the bar. */
  --data-single: var(--data-stage-1); /* Single metric / Ranking: one cyan for every item of one metric (BarHorizontal, TableRanked mini bar, the Gauge arc below its warning threshold). Order and length tell the rank, never the colour. Alias of data-stage-1. */
  --participant-user-bg: #eaf1fd; /* Avatar of a Bridge user: the circle, and the first (lightest) section of an internal chat's divided circle. Initials in participant-user-ink (5.6:1 light, 6.0:1 dark). Dark values sit a step above bg-app so the circle and its sections stay visible on dark surfaces. Tone 1 (the lightest) of the four a single avatar can take in a chat list (Avatar `tone`), and the first section of a divided circle. */
  --participant-user-ink: #2a4fb0; /* Initials on a Bridge user's avatar, and user-tone text in FilterRow counts. On participant-user-bg · -bg-2 · -bg-3 · -bg-4: 6.5 · 6.0 · 5.5 · 4.6:1 (light), 6.0 · 5.6 · 5.2 · 4.5:1 (dark); one step darker in light since 7.3.0 (was #2f58c4, 3.9:1 on the darkest tone) so every tone holds 4.5:1. */
  --participant-user-solid: #3e6ee5; /* The full-strength Bridge user hue, for a mark that names a user where a tint is too quiet. White text on it reads 4.6:1 (light), 4.95:1 (dark). */
  --participant-contact-bg: #f1ecfb; /* Avatar of a contact: the circle, and the first (lightest) section of a divided circle in a chat with contacts. Initials in participant-contact-ink (6.9:1 light, 6.1:1 dark). Dark values sit a step above bg-app so the circle and its sections stay visible on dark surfaces. Tone 1 (the lightest) of the four a single avatar can take in a chat list (Avatar `tone`), and the first section of a divided circle. */
  --participant-contact-ink: #56389e; /* Initials on a contact's avatar. On participant-contact-bg · -bg-2 · -bg-3 · -bg-4: 7.4 · 6.7 · 6.0 · 4.7:1 (light), 6.1 · 5.7 · 5.3 · 4.6:1 (dark); one step darker in light since 7.3.0 (was #5b3ba6, 4.4:1 on the darkest tone) so every tone holds 4.5:1. */
  --participant-contact-solid: #7c5ad6; /* The full-strength contact hue, for a mark that names a contact where a tint is too quiet. White text on it reads 4.9:1 (light), 4.0:1 (dark, source value, kept). */
  --participant-contact-bg-2: #e8dff8; /* Tone 2 of the contact family, one step darker than the base (since 7.3.0; before, -bg-2 was the step now called -bg-3). Only a single avatar of a contact in a chat list (Avatar `tone` 2, from avatarTones): never a section of a divided circle. */
  --participant-contact-bg-3: #e0d2f5; /* Tone 3 of the contact family (since 7.3.0; it was -bg-2): the second section of a divided circle in a chat with contacts (at least one contact), and tone 3 of a single avatar in a chat list. */
  --participant-contact-bg-4: #cdb7ed; /* Tone 4, the darkest of the contact family (since 7.3.0; it was -bg-3): the third section of a divided circle in a chat with contacts (at least one contact), and tone 4 of a single avatar in a chat list. */
  --participant-user-bg-2: #dce8fc; /* Tone 2 of the user family, one step darker than the base (since 7.3.0; before, -bg-2 was the step now called -bg-3). Only a single avatar of a Bridge user in a chat list (Avatar `tone` 2, from avatarTones): never a section of a divided circle. */
  --participant-user-bg-3: #cfe0fa; /* Tone 3 of the user family (since 7.3.0; it was -bg-2): the second section of a divided circle in an internal chat (Bridge users only), and tone 3 of a single avatar in a chat list. */
  --participant-user-bg-4: #b4cdf5; /* Tone 4, the darkest of the user family (since 7.3.0; it was -bg-3): the third section of a divided circle in an internal chat (Bridge users only), and tone 4 of a single avatar in a chat list. */
  --avatar-notification-bg: var(--brand-teal-soft); /* Avatar of Notificaciones (Bridge speaking, kind notification): the circle. The base brand-teal-soft; never a person's or a state's colour. */
  --avatar-notification-ink: var(--brand-teal-ink); /* The glyph (bell) on avatar-notification-bg. The base brand-teal-ink: 6.2:1 light, 7.6:1 dark. */
  --avatar-ai-bg-from: var(--brand-primary-soft); /* Start (top left) of the 135° ground of the Bridge IA avatar (Briefings, kind ai). The base brand-primary-soft. */
  --avatar-ai-bg-to: var(--brand-teal-soft); /* End (bottom right) of the ground of an AI avatar. The base brand-teal-soft. */
  --avatar-ai-ink-from: var(--text-brand); /* Start of the AI glyph's gradient stroke. The base text-brand: 4.6:1 light, 4.9:1 dark on avatar-ai-bg-from. */
  --avatar-ai-ink-to: var(--brand-teal-ink); /* End of the AI glyph's gradient stroke. The base brand-teal-ink: 6.2:1 light, 7.6:1 dark on avatar-ai-bg-to. */
  --avatar-agent-bg-from: var(--brand-primary-soft); /* Start (top left) of the 135° ground of an AI agent's avatar (an agent answering inside a conversation, kind agent). The base brand-primary-soft: the same blue the Bridge IA ground starts with. */
  --avatar-agent-bg-to: var(--participant-contact-bg); /* End (bottom right) of the ground of an AI agent's avatar: the base participant-contact-bg (lilac), because the agent answers for the company to its contacts. Blue → lilac tells it apart from Bridge IA (blue → teal). An approved exception to «never a person's colour» (Avatar README, Special avatars). */
  --avatar-agent-ink-from: var(--text-brand); /* Start of the agent glyph's gradient stroke (agent-ai), as Bridge IA's glyph runs its own. The base text-brand: 4.6:1 light, 4.9:1 dark on avatar-agent-bg-from. */
  --avatar-agent-ink-to: var(--participant-contact-ink); /* End of the agent glyph's gradient stroke. The base participant-contact-ink: 6.9:1 light, 6.1:1 dark on avatar-agent-bg-to. Part of the same approved exception as avatar-agent-bg-to. */
  --avatar-api-bg: var(--success-bg); /* Avatar of a message sent by an integration through the API (kind api), only inside a conversation: the circle. The base success-bg, a soft green, so it never reads as a contact without a name (neutral grey). An approved exception to «never a state's colour» (Avatar README, Special avatars). */
  --avatar-api-ink: var(--success-tx); /* The glyph (Lucide webhook) on avatar-api-bg. The base success-tx: 5.9:1 light, 9.6:1 dark. Part of the same approved exception as avatar-api-bg. */
  --avatar-unknown-bg: var(--neutral-bg); /* Avatar of a contact without a name (nothing to write initials from): the circle. The base neutral-bg: the person is not identified yet, so never purple or blue. */
  --avatar-unknown-ink: var(--neutral-tx); /* The question-mark glyph (Lucide circle-question-mark) on avatar-unknown-bg. The base neutral-tx: 6.1:1 light, 8.1:1 dark. */
  --avatar-notify-bg: var(--avatar-notification-bg); /* Deprecated (6.1.0): the old name of avatar-notification-bg, kept so 6.0.0 code keeps working. Removing it is a major. */
  --avatar-notify-ink: var(--avatar-notification-ink); /* Deprecated (6.1.0): the old name of avatar-notification-ink, kept so 6.0.0 code keeps working. Removing it is a major. */
  --success-bg: #e2fbe9; /* Semantic v3. Status pill background for resolved, completed, delivered, recovered. Text on it is success-tx. */
  --success-tx: #0a6d37; /* Semantic v3. Text and icon of a success pill (5.9:1 on success-bg light, 9.6:1 dark); success text and values on bg-app (6.5:1, 11.8:1) and bg-subtle (6.2:1, 10.7:1). */
  --success-solid: #2ab463; /* Semantic v3. Fills that encode a success outcome: chart segments (Resolved), SplitBar stages, mini bars, completed stepper nodes, the Online presence dot, legend dots. Same perceptual intensity as warning, error and neutral solids; kept ≥16 ΔE from data-cat-6 so it never reads as a series. Never under text (white on it reads 2.7:1 light, 2.0:1 dark). */
  --warning-bg: #fff6e1; /* Semantic v3. Status pill background for pending and at risk; the warning threshold zone of a Gauge track. Text on it is warning-tx. */
  --warning-tx: #9c5906; /* Semantic v3. Text and icon of a warning pill (5.1:1 on warning-bg light, 10.1:1 dark); warning text on bg-app (5.5:1, 12.4:1): threshold labels, a Funnel drop above its alert threshold. */
  --warning-solid: #f6b324; /* Semantic v3. Fills that encode a warning outcome: chart segments (Pending, At risk), SplitBar stages, the Gauge arc from the warning threshold, the Away presence dot. The weakest dot on white (1.8:1 light): a warning mark always travels with its label or value. Never under text. */
  --error-bg: #ffefef; /* Semantic v3. Status pill background for failed, abandoned, SLA breached, not delivered; the error threshold zone of a Gauge track; the rejected upload row. Text on it is error-tx. */
  --error-tx: #b9292d; /* Semantic v3. Text and icon of an error pill (5.5:1 on error-bg light, 8.4:1 dark); field errors, invalid input borders, destructive menu items and the error state glyph (6.1:1 on bg-app light, 9.9:1 dark). */
  --error-solid: #e94b4a; /* Semantic v3. Fills that encode an error outcome: chart segments (Failed, Abandoned, SLA breached), SplitBar stages, the Gauge arc from the error threshold, the Busy presence dot. Keep it a fill: white on it reads 3.8:1 light, 2.9:1 dark. */
  --info-bg: #eaf1fd; /* Status pill background for contextual information. Text on it is info-tx. */
  --info-tx: #213d84; /* Text and icon of an info pill (9.0:1 on info-bg light, 7.2:1 dark); info glyphs in dialogs and attribute chips. */
  --info-solid: #2b5ea7; /* Fills that encode an informational state in a chart or SplitBar. Never under small text. */
  --neutral-bg: #eef4fc; /* Semantic v3 (cool slate). Status pill background for escalated, unknown and not available; Out of office and Offline pills; neutral message and row chips. Text on it is neutral-tx. */
  --neutral-tx: #4d5c72; /* Semantic v3 (cool slate). Text and icon of a neutral pill (6.1:1 on neutral-bg light, 8.1:1 dark); 6.8:1 on bg-app light, 10.3:1 dark. */
  --neutral-solid: #9cacc1; /* Semantic v3 (cool slate). Fills that encode a neutral outcome in a chart or SplitBar (Escalated), and the queue nodes of a semantic Sankey. 2.3:1 on bg-app light, 6.1:1 dark: always with its label. The Offline and Out of office dots have their own slate tones (presence-offline, presence-ooo). */
  --trend-favorable: var(--success-tx); /* A change whose meaning is good (a rise in Qualification Rate, a fall in Average Response Time): TrendChip and KPI deltas. Chosen by meaning, never by arrow direction. Alias of success-tx: 6.5:1 on bg-app light, 11.8:1 dark. */
  --trend-unfavorable: var(--error-tx); /* A change whose meaning is bad: TrendChip and KPI deltas. Alias of error-tx: 6.1:1 on bg-app light, 9.9:1 dark. */
  --trend-warning: var(--warning-tx); /* A change that needs watching without being bad yet: TrendChip and KPI deltas. Alias of warning-tx: 5.5:1 light, 12.4:1 dark. */
  --trend-neutral: var(--neutral-tx); /* A change with no inherent reading: TrendChip and KPI deltas render neutral by default, never green or red. Alias of neutral-tx: 6.8:1 light, 10.3:1 dark. */
  --bg-app: #ffffff; /* Page, card, table, input and panel surface; the ground every text note in this file is measured on. Also the thread of an AI conversation (AssistantChat), never bg-subtle: the blue thread surface is reserved for general conversations (MessageThread). */
  --bg-sidebar: #fbfbfa; /* The menu column (Navbar) and the docked composer: the warm chrome neutral that makes the menu recede. In dark it is the darkest surface. Never mixed with the blue-tinted neutrals inside one element. */
  --bg-subtle: #f8fafd; /* Blue-tinted secondary surface: hover of table rows, chat list rows and group headings, secondary, ghost and icon buttons and floating-panel rows; card footer bands; containers; disabled fields. A menu navigation item never takes it. It is also the surface of the history of a general conversation (contact, group and internal chats): MessageThread paints it, so the screen never sets it. An AI conversation (AssistantChat) never takes it: its thread stays on bg-app, because next to a chat the two blue surfaces run together. */
  --border-default: #e1e8f2; /* Every 1px content border: cards, tables, inputs, popovers, the top strip's bottom edge. Separation only (1.2:1 on bg-app), never a state or the only edge of a control that needs finding. */
  --border-soft: #ecece9; /* Warm 1px chrome edges: the menu's right edge, menu header and footer rules, section dividers in the account panel and switchers. */
  --grid: #f0f4fa; /* Chart gridlines and empty tracks: progress and gauge tracks, the off toggle, the upload progress track. */
  --text-primary: #1a1a2e; /* Body copy, values, input text and hovered navigation text. 17.1:1 on bg-app (light), 14.2:1 (dark); 12.4:1 or better on every tinted surface. */
  --text-heading: #0e2841; /* Headings, card titles, KPI values and the page title. 15.0:1 on bg-app (light), 16.1:1 (dark). */
  --text-secondary: #5a6b85; /* Supporting copy, descriptions, axis labels, breadcrumb trail. 5.4:1 on bg-app (light), 7.8:1 (dark); 5.2:1 on bg-subtle and bg-sidebar. */
  --text-tertiary: #72716e; /* Inactive navigation text and glyphs, placeholders, helper glyphs. 4.88:1 on bg-app and 4.67:1 on bg-subtle (light), 6.2:1 on bg-app (dark). */
  --text-muted: #6d6c69; /* Timestamps, metadata, captions, table header labels, footnotes. 5.25:1 on bg-app, 5.0:1 on bg-subtle and 4.6:1 on brand-primary-soft (own message bubbles, brand chips) in light; 5.2:1 on bg-app and 4.7:1 on bg-subtle in dark. */
  --text-brand: #3865d8; /* Small text in the brand colour on any ground: links (through text-link), selected and brand-tone chips, count badges, the active sort label, the chosen preset. The same hue as brand-primary, tuned so it reads 4.5:1 or better everywhere: light 5.2:1 on bg-app, 5.0:1 on bg-subtle, 4.6:1 on brand-primary-soft; dark 5.7:1 on bg-app, 5.1:1 on bg-subtle, 4.9:1 on brand-primary-soft. brand-primary itself stays for fills, icons and large text. */
  --text-link: var(--text-brand); /* Link text and link-style actions (a back link, Clear selection, Create in a list): text-brand in both themes, 5.2:1 on bg-app and 5.0:1 on bg-subtle in light, 5.7:1 and 5.1:1 in dark. */
  --text-link-hover: var(--brand-primary-hover); /* Hovered link text. Light darkens to brand-primary-hover (6.3:1 on bg-app); dark lightens (8.3:1 on bg-app, 7.5:1 on bg-subtle). */
  --text-on-fill: #ffffff; /* Labels and glyphs on a solid fill: the primary and destructive buttons (resting and hover), the selected day, checked boxes, the switch knob, notification badges. 4.5:1 or better on brand-primary, brand-primary-hover, destructive and destructive-hover in both themes. Never on success-solid, warning-solid or the data colours, which are too light for it. */
  --destructive: #a32d2d; /* Destructive button fill and the notification badge. White text on it reads 7.1:1 (light), 4.6:1 (dark). As text in dark it reads 3.8:1 (source value, kept): destructive words use error-tx. */
  --destructive-hover: #8a2626; /* Hover of the destructive button. It darkens in both themes, so white text on it reads 8.8:1 (light) and 5.6:1 (dark). */
  --icon-idle: #93918a; /* Idle sort glyphs, disclosure chevrons, idle icons and the comparison series of AreaComparison. 3.2:1 on bg-app (light), 4.7:1 (dark): meets 3:1 for icons, never for text. */
  --row-hover: var(--bg-subtle); /* Hover of a row in a list panel: ChatListItem and the collapsible ChatListGroup heading. Light is bg-subtle (#f8fafd), the hover of table rows; dark takes neutral-bg (#292e35), one step up the cool slate, because bg-subtle sits too close to bg-app in dark to be seen. Always a step lighter than row-selected's tint, so hover never reads as selection. On it the time and a group label step up to text-secondary (6.1:1 dark); a read preview in text-tertiary keeps 4.7:1 light and 4.8:1 dark. */
  --row-selected: var(--brand-primary-subtle); /* Background of the selected row: the selected table row and conversation row (DataTable, ConversationRow, where the rail carries the emphasis) and the open chat of the chat list (ChatListItem, with no rail). It is brand-primary-subtle in both themes (#f0f5fe light, #253255 dark), the lightest step of the brand blue, so the open chat is seen in dark too; hover under it is row-hover. Text on it stays text-primary (15.6:1 light, 10.3:1 dark); a read preview and the time on the open chat use text-secondary (4.95:1, 5.65:1). text-muted and text-tertiary are not used on it in dark (3.8:1, 4.5:1). */
  --row-selected-rail: #213d84; /* The 3px left rail of a selected row (10.2:1 on bg-app light, 3.5:1 dark). */
  --accent-50: #e1f5ee; /* Deprecated legacy green scale. Reads as success: never in new work. */
  --accent-200: #5dcaa5; /* Deprecated legacy green scale. Reads as success: never in new work. */
  --accent-400: #1d9e75; /* Deprecated legacy green scale. Reads as success: never in new work. */
  --accent-600: #0f6e56; /* Deprecated legacy green scale. Reads as success: never in new work. */
  --accent-800: #085041; /* Deprecated legacy green scale. Reads as success: never in new work. */
  --logo-teal-base: #3a8a9c; /* Deprecated. The logo carries its own colours in its files; nothing recolours it. */
  --logo-teal-light: #7ad6e3; /* Deprecated. The logo carries its own colours in its files; nothing recolours it. */
  --data-amber: #d98c3f; /* Deprecated warm data tone. Reads as a warning: never in new work; series use Data · Categorical. */
  --data-gold: #e8c05a; /* Deprecated warm data tone. Reads as a warning: never in new work. */
  --data-clay: #b0442f; /* Deprecated warm data tone. Reads as an error: never in new work. */
  --data-wine: #8e3b52; /* Deprecated warm data tone. Reads as an error: never in new work. */
  --data-sand: #e0a38a; /* Deprecated warm data tone. Never in new work. */
  --series-2b: #2b5ea7; /* Legacy second series of the old fixed order. Kept for older consumers; new charts resolve colours through seriesColor(i, count). */
  --neutral-4: #d4d2c9; /* Legacy neutral, the same value as data-other. Kept for older consumers. */
  --scrim: rgba(14, 40, 65, 0.45); /* The overlay behind Modal and Drawer (overlay variant), and behind the menu drawer under bp-sm. The only transparent surface besides the glass level (glass-surface), the illustration tile washes and chart fills. */
  --glass-surface: rgba(255, 255, 255, 0.84); /* The glass level: bg-app at 84% (light) and 80% (dark) over glass-backdrop, so the thread reads softly through it. Only the message action bar, its More options menu and its reactions panel (MessageBubble actions, Dropdown surface="glass"). Ink on it is measured on bg-app; never put it over a photo or under body text. */
  --glass-surface-border: rgba(225, 232, 242, 0.75); /* The rim of a glass surface and its dividers: border-default at 75%, so the edge reads as a lens and not a box. */
  --ink-veil: rgba(26, 26, 46, 0.05); /* A 5% veil of text-primary that darkens (light) or lifts (dark) the ground it sits on: the quoted message inside a bubble on bg-app (MessageBubble replyTo on incoming, internal and rich messages). text-brand and text-secondary keep 4.5:1 on it over bg-app. Never a ground for a control at rest. */
  --ink-veil-strong: rgba(26, 26, 46, 0.07); /* A 7% veil of text-primary: hover and open state of a control or a row on a glass surface (the action bar's buttons, a glass menu's rows) and the hover of a quoted message on bg-app, where text-brand still reads 4.5:1. On solid grounds the hover stays bg-subtle. */
  --app-veil: rgba(255, 255, 255, 0.6); /* A 60% veil of bg-app: the quoted message inside a bubble on a tinted ground (MessageBubble replyTo on outgoing, team and internal-own messages, on brand-primary-soft), so text-brand reads 4.96:1 (light) and 5.4:1 (dark) and text-secondary more; its hover is bg-app. A darkening veil there would drop under 4.5:1. */
  --scrollbar-thumb: #a9b4c5; /* Thumb of a scroll area while it scrolls (AppShell's scrollbar behaviour); hidden at rest, the track is always transparent. Quiet by design: 2.1:1 on bg-app light, 2.55:1 dark. */
  --scrollbar-thumb-hover: #7d8ba1; /* Thumb while the pointer rests on a scroll area's edge, so it can be grabbed. Clears 3:1 as a UI component: 3.45:1 on bg-app and 3.3:1 on bg-subtle light, 3.76:1 and 3.4:1 dark. */
  --wa-wallpaper: #efeae2; /* WhatsAppPreview only: the chat wallpaper behind the bubble, WhatsApp's own. */
  --wa-header: #075e54; /* WhatsAppPreview only: the business bar at the top of the phone. */
  --wa-header-ink: #ffffff; /* WhatsAppPreview only: name and initial on wa-header: 7.67:1 light, 12.1:1 dark. */
  --wa-header-tile: rgba(255, 255, 255, 0.22); /* WhatsAppPreview only: the round initial tile on wa-header. */
  --wa-bubble: #ffffff; /* WhatsAppPreview only: the received message bubble and its buttons. */
  --wa-bubble-edge: rgba(11, 20, 26, 0.13); /* WhatsAppPreview only: the 1px shadow under a bubble or button. */
  --wa-ink: #111b21; /* WhatsAppPreview only: message text on wa-bubble: 17.5:1 light, 12.1:1 dark; also the media label on wa-media. */
  --wa-meta: #667781; /* WhatsAppPreview only: footer and time on wa-bubble: 4.65:1 light, 4.68:1 dark. */
  --wa-link: #027eb5; /* WhatsAppPreview only: button labels on wa-bubble: 4.51:1 light, 6.7:1 dark. */
  --wa-media: #e9edef; /* WhatsAppPreview only: the placeholder for an image, video or document header. */
  --wa-media-scrim: rgba(11, 20, 26, 0.55); /* WhatsAppPreview only: the dark wash under the play button and the duration of a video header, over the poster, so white reads on any frame. The same in both themes, as WhatsApp draws it. */
  --presence-online: var(--success-solid); /* Presence dot for Online on a Bridge user's avatar, with a 1.5px ring in the surface behind it. */
  --presence-online-bg: var(--success-bg); /* Background of the Online status pill in the account panel and status picker. */
  --presence-online-tx: var(--success-tx); /* Text and icon of the Online status pill. */
  --presence-busy: var(--error-solid); /* Presence dot for Busy on a Bridge user's avatar, with a 1.5px ring in the surface behind it. */
  --presence-busy-bg: var(--error-bg); /* Background of the Busy status pill in the account panel and status picker. */
  --presence-busy-tx: var(--error-tx); /* Text and icon of the Busy status pill. */
  --presence-away: var(--warning-solid); /* Presence dot for Away on a Bridge user's avatar, with a 1.5px ring in the surface behind it; the Away segment of a presence SplitBar. In light the dot reads 1.8:1 on bg-app: it is never the only signal, the pill carries the clock icon and the word. */
  --presence-away-bg: var(--warning-bg); /* Background of the Away status pill in the account panel and status picker. */
  --presence-away-tx: var(--warning-tx); /* Text and icon of the Away status pill. */
  --presence-offline: #cfd7e2; /* Presence dot for Offline on a Bridge user's avatar, with a 1.5px ring in the surface behind it; the Offline segment of a presence SplitBar. Light slate, one tone below presence-ooo so the two separate by lightness in a bar (1.5:1 light, 2.2:1 dark on bg-app): always with the word or icon. */
  --presence-offline-bg: var(--neutral-bg); /* Background of the Offline status pill in the account panel and status picker. */
  --presence-offline-tx: var(--neutral-tx); /* Text and icon of the Offline status pill. */
  --presence-ooo: var(--participant-contact-solid); /* Presence dot for Out of office on a Bridge user's avatar; the Out of office segment of a presence SplitBar. Purple, the base participant-contact-solid (5.0:1 light, 4.6:1 dark on bg-app): a status of a Bridge user, so it is only ever a dot or a segment, never a circle. */
  --presence-ooo-bg: var(--participant-contact-bg); /* Background of the Out of office status pill: purple, the base participant-contact-bg. */
  --presence-ooo-tx: var(--participant-contact-ink); /* Text and icon of the Out of office status pill: the base participant-contact-ink on presence-ooo-bg. */
  --presence-dnd: var(--error-solid); /* Do not disturb dot on a Bridge user's avatar, set by the system while that person shares their screen in a call (Avatar `screenSharing`); never a status a person picks. The red of presence-busy in light; in dark the deeper destructive red, so the white minus keeps 3:1 (4.6:1; the busy red reads 2.9:1). The only presence dot that carries a glyph (Lucide `minus` in presence-dnd-ink). */
  --presence-dnd-ink: var(--text-on-fill); /* The Lucide `minus` inside the do not disturb dot (presence-dnd), at least 3:1 on it in both themes. */
  --bubble-private-bg: #fff6e1; /* A private message (only the team sees it, never the contact): the warm amber ground of its bubble on the web and on the phone (MessageBubble private, private-own), so it can never be mistaken for a message the contact received. */
  --bubble-private-border: #f8e3ae; /* The 1px border of a private message bubble. */
  --bubble-private-ink: #6f5a2c; /* The lock glyph and the Private label of a private message, on bubble-private-bg (5.6:1 light, 9.2:1 dark). */
  --file-pdf: #d93b36; /* The kind badge of a PDF in a file message, web and phone. White text on it reads 4.5:1 or more in both themes (the same fill in dark: a lighter one would fail). */
  --file-doc: #2f6bd8; /* The kind badge of a Word document in a file message, web and phone. White text on it, 4.5:1 or more in both themes. */
  --file-xls: #1e864a; /* The kind badge of an Excel workbook in a file message, web and phone. White text on it, 4.5:1 or more in both themes. */
  --file-ppt: #c4532a; /* The kind badge of a PowerPoint deck in a file message, web and phone. White text on it, 4.5:1 or more in both themes. */
  --shadow-1: 0 4px 12px rgba(14, 40, 65, 0.08); /* Floating level: Dropdown, Popover, Tooltip, ToastStack, Combobox and date panels, menu flyouts, the switcher and account panels, the floating composer, and every control that floats over content (IconButton appearance="floating", such as the opener of a hidden SidePanel). Nothing else floats, except the glass level of the message action bar (shadow-glass). */
  --shadow-2: 0 12px 32px rgba(14, 40, 65, 0.16); /* Overlay level: Modal and Drawer. Navy-tinted in light, true black at higher opacity in dark. */
  --shadow-thumb: 0 1px 2px rgba(14, 40, 65, 0.14), 0 3px 8px rgba(14, 40, 65, 0.10); /* A part that rises inside a control (10.1.0): the chosen option of the pill SegmentedControl, on web and Mobile. Not the floating level: menus, popovers and tooltips keep shadow-1. */
  --focus-ring: 0 0 0 2px #3e6ee5; /* Keyboard focus on every interactive element: outline none, box-shadow focus-ring, shown on :focus-visible only. A solid 2px ring in the brand colour, 4.6:1 against bg-app in light and 5.7:1 in dark, so it reads on its own around borderless controls, links, rows and filled buttons. Rows and cells inside a scrolling or clipped box use focus-ring-inset. */
  --focus-ring-destructive: 0 0 0 2px #a32d2d; /* Keyboard focus on destructive buttons and icon buttons: a solid 2px ring, 7.1:1 against bg-app in light and 6.0:1 in dark. */
  --focus-ring-inset: inset 0 0 0 2px #3e6ee5; /* Keyboard focus drawn inside the element: table rows, list rows and tabs that sit in a scrolling or clipped box, where an outer ring would be cut off. */
  --focus-halo: 0 0 0 3px rgba(33, 61, 132, 0.15); /* The soft 3px glow of a focused text field (Input, Textarea, Select, SearchInput, Combobox, Multiselect, DateInput, the composer). Decoration only: the field's border turning brand-primary is what marks focus at 3:1 or better. */
  --shadow-glass: 0 10px 30px rgba(14, 40, 65, 0.14), 0 2px 6px rgba(14, 40, 65, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.65); /* The glass level's depth: a soft navy drop (true black in dark) plus a 1px light caught on the upper edge. Only with glass-surface: the message action bar, Dropdown surface="glass" and the reactions panel. The floating level stays shadow-1. */
}
[data-theme="dark"] {
  --brand-primary: #3f6ad6;
  --brand-primary-hover: #2c5bcf;
  --brand-primary-soft: #1b2540;
  --brand-primary-subtle: #253255;
  --brand-primary-border: #2c3a5c;
  --brand-primary-dark: #afc4f0;
  --brand-teal: #4fa8bc;
  --brand-teal-light: #7ad6e3;
  --brand-teal-soft: #16353d;
  --brand-teal-ink: #86d1de;
  --data-blue-1: #2a4a8e;
  --data-blue-2: #3f6ad6;
  --data-blue-3: #4a7bc4;
  --data-blue-4: #557fe4;
  --data-blue-5: #93b3f2;
  --data-blue-6: #afc4f0;
  --data-teal: #4fa8bc;
  --data-teal-light: #7ad6e3;
  --data-slate: #a6aebe;
  --data-other: #4b4a45;
  --data-cat-1: #698de2;
  --data-cat-2: #84b1fe;
  --data-cat-3: #2587c7;
  --data-cat-4: #16ace6;
  --data-cat-5: #46d3e6;
  --data-cat-6: #71f2e9;
  --data-cat-ink-1: #698de2;
  --data-cat-ink-2: #84b1fe;
  --data-cat-ink-3: #2e92d4;
  --data-cat-ink-4: #16ace6;
  --data-cat-ink-5: #46d3e6;
  --data-cat-ink-6: #71f2e9;
  --data-seq-1: #16323e;
  --data-seq-2: #154a5f;
  --data-seq-3: #0f6786;
  --data-seq-4: #2f97c0;
  --data-seq-5: #55b8e2;
  --data-seq-ink-1: #e1f2f9;
  --data-seq-ink-2: #e1f2f9;
  --data-seq-ink-3: #e1f2f9;
  --data-seq-ink-4: #0a2230;
  --data-seq-ink-5: #0a2230;
  --data-seq-ring: #e1f2f9;
  --data-stage-1: #4dbff2;
  --data-stage-2: #3dabdb;
  --data-stage-3: #2392be;
  --data-stage-4: #1c789e;
  --data-stage-5: #15607f;
  --data-single: var(--data-stage-1);
  --participant-user-bg: #253255;
  --participant-user-ink: #93b3f2;
  --participant-user-solid: #3f6ad6;
  --participant-contact-bg: #352d51;
  --participant-contact-ink: #bca9ec;
  --participant-contact-solid: #8b6be0;
  --participant-contact-bg-2: #3a3158;
  --participant-contact-bg-3: #3f3560;
  --participant-contact-bg-4: #493c70;
  --participant-user-bg-2: #28365c;
  --participant-user-bg-3: #2b3b64;
  --participant-user-bg-4: #314474;
  --avatar-notification-bg: var(--brand-teal-soft);
  --avatar-notification-ink: var(--brand-teal-ink);
  --avatar-ai-bg-from: var(--brand-primary-soft);
  --avatar-ai-bg-to: var(--brand-teal-soft);
  --avatar-ai-ink-from: var(--text-brand);
  --avatar-ai-ink-to: var(--brand-teal-ink);
  --avatar-agent-bg-from: var(--brand-primary-soft);
  --avatar-agent-bg-to: var(--participant-contact-bg);
  --avatar-agent-ink-from: var(--text-brand);
  --avatar-agent-ink-to: var(--participant-contact-ink);
  --avatar-api-bg: var(--success-bg);
  --avatar-api-ink: var(--success-tx);
  --avatar-unknown-bg: var(--neutral-bg);
  --avatar-unknown-ink: var(--neutral-tx);
  --avatar-notify-bg: var(--avatar-notification-bg);
  --avatar-notify-ink: var(--avatar-notification-ink);
  --success-bg: #163120;
  --success-tx: #99e6ad;
  --success-solid: #52cd7d;
  --warning-bg: #38280f;
  --warning-tx: #fcd583;
  --warning-solid: #fbc044;
  --error-bg: #401f1f;
  --error-tx: #ffafac;
  --error-solid: #f66c69;
  --info-bg: #1b2540;
  --info-tx: #93b3f2;
  --info-solid: #4a7bc4;
  --neutral-bg: #292e35;
  --neutral-tx: #bfc8d4;
  --neutral-solid: #8c9aab;
  --trend-favorable: var(--success-tx);
  --trend-unfavorable: var(--error-tx);
  --trend-warning: var(--warning-tx);
  --trend-neutral: var(--neutral-tx);
  --bg-app: #191a1d;
  --bg-sidebar: #141517;
  --bg-subtle: #212328;
  --border-default: #2e3138;
  --border-soft: #26282c;
  --grid: #24272c;
  --text-primary: #e7e8eb;
  --text-heading: #f5f6f8;
  --text-secondary: #a6aebe;
  --text-tertiary: #9b9a94;
  --text-muted: #8e8d88;
  --text-brand: #7191e1;
  --text-link: var(--text-brand);
  --text-link-hover: #93b3f2;
  --text-on-fill: #ffffff;
  --destructive: #c25151;
  --destructive-hover: #b53f3f;
  --icon-idle: #86857e;
  --row-hover: var(--neutral-bg);
  --row-selected: var(--brand-primary-subtle);
  --row-selected-rail: #3f6ad6;
  --accent-50: #11291f;
  --accent-200: #6fd9b5;
  --accent-400: #2fbf90;
  --accent-600: #5fcfa6;
  --accent-800: #1e7a5f;
  --logo-teal-base: #4fa8bc;
  --logo-teal-light: #7ad6e3;
  --data-amber: #e8a45c;
  --data-gold: #f0cf7a;
  --data-clay: #d46a50;
  --data-wine: #c4667f;
  --data-sand: #efc0a8;
  --series-2b: #4a7bc4;
  --neutral-4: #4b4a45;
  --scrim: rgba(0, 0, 0, 0.62);
  --glass-surface: rgba(25, 26, 29, 0.8);
  --glass-surface-border: rgba(46, 49, 56, 0.75);
  --ink-veil: rgba(231, 232, 235, 0.05);
  --ink-veil-strong: rgba(231, 232, 235, 0.07);
  --app-veil: rgba(25, 26, 29, 0.6);
  --scrollbar-thumb: #555b67;
  --scrollbar-thumb-hover: #6e7584;
  --wa-wallpaper: #0b141a;
  --wa-header: #202c33;
  --wa-header-ink: #e9edef;
  --wa-header-tile: rgba(233, 237, 239, 0.16);
  --wa-bubble: #202c33;
  --wa-bubble-edge: rgba(0, 0, 0, 0.4);
  --wa-ink: #e9edef;
  --wa-meta: #8696a0;
  --wa-link: #53bdeb;
  --wa-media: #2a3942;
  --wa-media-scrim: rgba(11, 20, 26, 0.55);
  --presence-online: var(--success-solid);
  --presence-online-bg: var(--success-bg);
  --presence-online-tx: var(--success-tx);
  --presence-busy: var(--error-solid);
  --presence-busy-bg: var(--error-bg);
  --presence-busy-tx: var(--error-tx);
  --presence-away: var(--warning-solid);
  --presence-away-bg: var(--warning-bg);
  --presence-away-tx: var(--warning-tx);
  --presence-offline: #4a525e;
  --presence-offline-bg: var(--neutral-bg);
  --presence-offline-tx: var(--neutral-tx);
  --presence-ooo: var(--participant-contact-solid);
  --presence-ooo-bg: var(--participant-contact-bg);
  --presence-ooo-tx: var(--participant-contact-ink);
  --presence-dnd: var(--destructive);
  --presence-dnd-ink: var(--text-on-fill);
  --bubble-private-bg: #38280f;
  --bubble-private-border: #4f3a17;
  --bubble-private-ink: #e8d3a3;
  --file-pdf: #d93b36;
  --file-doc: #2f6bd8;
  --file-xls: #1e864a;
  --file-ppt: #c4532a;
  --shadow-1: 0 4px 14px rgba(0, 0, 0, 0.45);
  --shadow-2: 0 14px 34px rgba(0, 0, 0, 0.6);
  --shadow-thumb: 0 1px 2px rgba(0, 0, 0, 0.55), 0 3px 8px rgba(0, 0, 0, 0.40);
  --focus-ring: 0 0 0 2px #7191e1;
  --focus-ring-destructive: 0 0 0 2px #f66c69;
  --focus-ring-inset: inset 0 0 0 2px #7191e1;
  --focus-halo: 0 0 0 3px rgba(90, 134, 232, 0.34);
  --shadow-glass: 0 12px 32px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
:root {
  --r-menu: 3px; /* Radius 3: menu rows, dropdown and flyout rows, switcher tiles, small chips inside menus, chart bars' outer end. */
  --r-control: 6px; /* Radius 6: buttons, inputs, selects, icon buttons, segmented controls, pagination buttons. */
  --r-card: 12px; /* Radius 12: cards (Card, the same on web and Mobile), tables, KPI cards, toasts, accordions, the account panel, and every surface that reads it. */
  --r-pill: 10px; /* Radius 10: status pills, trend chips, filter chips, count and notification badges, message bubbles. */
  --r-container: 12px; /* Radius 12: Container and Modal (the floating composer takes composer-r). A card inside a container takes the same 12 (r-card, 10.0.0): the container's padding sets them apart. */
  --r-full: 999px; /* Capsule: fully round ends at any height. Search fields (SearchInput) and the pill SegmentedControl (filters under a search: Todos / No leídos, Todos / Mi equipo / Contactos), so a search and the filters under it read as one family. Never on cards, containers or menus. */
  --sidebar-w: 222px; /* Width of the open menu (Navbar), 222px, and of the menu drawer under bp-sm. */
  --sidebar-w-collapsed: 56px; /* Width of the collapsed menu rail, 56px. */
  --topstrip-h: 46px; /* Height of the Console TopStrip, 46px. */
  --header-h: 56px; /* Height of the Bridge App header row: the Navbar header (mark and workspace) and PageHeader surface="app", which is as tall so their lines meet (golden rule 13). Replaces nav-head. */
  --content-max: 1440px; /* Cap of the content column in AppShell and the TopStrip, 1440px; the column centres beyond it. */
  --panel-w-sm: 480px; /* Side panel width scale, step sm, 480px: the preferred width of brief content and one-off cases (a short record, a single form, a note, a Bridge AI panel). A preferred width, never a fixed one: the panel narrows when the space does not allow it and never grows past it on its own. Read by Drawer (size="sm", the default) and by any future side panel. */
  --panel-w-md: 720px; /* Side panel width scale, step md, 720px: the preferred width of lists and details of medium complexity (a live list or an evidence table of 3 to 4 columns, a record with a few sections). Preferred, never fixed: see panel-w-sm. */
  --panel-w-lg: 960px; /* Side panel width scale, step lg, 960px: the preferred width of rankings, wider tables and panels that navigate between levels. Preferred, never fixed: see panel-w-sm. */
  --panel-w-xl: 1200px; /* Side panel width scale, step xl, 1200px: the preferred width of broad details with metrics and multi-column tables. Also the ceiling of the scale: no side panel is ever wider, a person's resize included. Preferred, never fixed: see panel-w-sm. */
  --drawer-w-sm: 480px; /* Deprecated alias of panel-w-sm (same value), kept so screens that read --drawer-w-sm directly do not break. Read panel-w-sm instead; this token is removed in a later delivery. */
  --drawer-w-md: 720px; /* Deprecated alias of panel-w-md (same value), kept so screens that read --drawer-w-md directly do not break. Read panel-w-md instead; this token is removed in a later delivery. */
  --drawer-w-lg: 960px; /* Deprecated alias of panel-w-lg (same value), kept so screens that read --drawer-w-lg directly do not break. Read panel-w-lg instead; this token is removed in a later delivery. */
  --drawer-w-xl: 1200px; /* Deprecated alias of panel-w-xl (same value), kept so screens that read --drawer-w-xl directly do not break. Read panel-w-xl instead; this token is removed in a later delivery. */
  --layout-main-min: 600px; /* Layout: the fallback minimum width of the sibling a dynamic Drawer pushes, 600px, when the sibling declares none (Drawer siblingMinWidth). The drawer pushes while its container minus this leaves room for it, and floats when it does not. A sibling that needs more declares its own (Chat: the conversation, chat-conversation-min). */
  --layout-context-min: 240px; /* Layout: the context an overlay side panel tries to leave visible behind it, 240px. When its preferred width would leave less, the panel narrows (by at most panel-reduce-max) and, past that, takes the whole width beside the menu. */
  --pad-modal: 24px; /* Inner padding of Modal and ConfirmDialog. */
  --pad-popover: 12px; /* Inner padding of Popover. */
  --gap-dense: 12px; /* Dense gap, 12px: between controls in a toolbar and in dense stacks; also where a Console switcher panel opens under the open menu's brand row. */
  --gap-standard: 16px; /* Standard gap, 16px: between cards in a grid and between blocks on a page. */
  --menu-w: 200px; /* Default width of a menu: Dropdown, the account menu of the Navbar user row and of the TopStrip, and the minimum width of the Console rail flyout. */
  --person-card-w: 272px; /* PersonCard (structural): width of the card a chat row opens on its avatar, room for the name, the start-chat button and a full email. */
  --guide-scene-h: 236px; /* Guide (structural): height of the animated scene of every step of a guide, the same in every guide so the dialog never jumps between steps or between pages. */
  --wa-media-h: 160px; /* WhatsAppPreview (structural): the tallest an image, video poster or document thumbnail header draws in the preview; a taller file is cropped to it (object-fit cover), a shorter one keeps its height. */
  --border-width: 1px; /* Every border in the system is 1px: no 2px, no inset, no double. Also the ring width of an avatar's divided sections. */
  --border-width-ring: 1.5px; /* The ring in the ground colour that separates a small marker from what sits under it: the Navbar's unread, presence and pending dots, the presence dot of AccountPanel, the Sparkline's hover point. Drawn as a box-shadow in the surface colour, never as a border that takes space. */
  --border-width-indicator: 1.5px; /* Width of a status stroke drawn on the inner edge of a row, following its radius: the SLA indicator of ChatListItem (at risk: warning-solid; breached: error-solid), and the upload progress line of a Composer attachment. A state mark, never a decorative left-border card. */
  --nav-switcher-w: 248px; /* Navbar (structural): width of the switch panel (a picker: switch workspace, Console contexts), sized to its rows of tile, name and note. No other component shares it. */
  --nav-finder-w: 268px; /* Navbar (structural): width of a finder panel (search across companies), wider than the picker for its search field and longer names. No other component shares it. */
  --account-panel-w: 304px; /* Width of AccountPanel, the Bridge App account panel opened from the menu's user row. A structural decision of that component: no other panel shares it. */
  --composer-max-w: 780px; /* Composer (structural): contained width of the floating composer card, centred over the thread, 780px. Holds whatever the spacing scale does; the docked composer fills its panel. */
  --composer-r: 16px; /* Composer (structural): radius of the floating composer card, 16px, a little rounder than r-container so the write surface reads as its own object over the thread. A private note's frame takes it too and its inner surface composer-r minus space-4 (12px). The docked composer keeps r-card. */
  --chat-list-w: 308px; /* Chat (structural): width of the chat list column beside the conversation, 308px. A decision of the Chat screen, not of any panel: it sits outside the Drawer's container, so the container already discounts it. */
  --chat-list-item-menu-w: 220px; /* ChatListItem (structural): width of a chat row's options menu and of the «Mover a nueva sección» popover that opens in its place, so «Mover a nueva sección…» never wraps. Only for that menu: every other menu keeps menu-w. */
  --chat-conversation-min: 544px; /* Chat (structural): the narrowest the conversation column still reads as a conversation, 544px (validated in the Drawer lab). With the chat list outside the Drawer's container, Chat passes it as the Drawer's siblingMinWidth; it is never a Drawer rule and no other screen inherits it. */
  --space-1: 1px; /* Spacing step, 1px: half the 2px between menu rows (the margin above and below each row), the gap between two stacked lines in a menu or switcher row, a 1px nudge. */
  --space-2: 2px; /* Spacing step, 2px: between option rows of the menu and of a switcher panel; small offsets of a dot on a glyph. */
  --space-3: 3px; /* Spacing step, 3px: odd step kept for the Navbar's measured geometry (the unread dot's inset on the chevron, a child row's vertical padding). Prefer an even step in new work. */
  --space-4: 4px; /* Spacing step, 4px: between icon and label in tight controls, a panel's inner padding, the space above a divider, a panel opening under its trigger. */
  --space-5: 5px; /* Spacing step, 5px: odd step kept for the Navbar's measured geometry (a section title's bottom padding, the rail flyout's padding and heading). Prefer an even step in new work. */
  --space-6: 6px; /* Spacing step, 6px: a switcher row's vertical padding, the header's inset around the Bridge App workspace control, small gaps. */
  --space-7: 7px; /* Spacing step, 7px: odd step kept for the Console Working on row (its tile-to-text gap and side padding). Prefer an even step in new work. */
  --space-8: 8px; /* Spacing step, 8px: between a glyph and its label in a menu row, the side padding of rows in panels, the right padding of a row's text. */
  --space-10: 10px; /* Spacing step, 10px: between the brand mark and its words, the menu list's padding in the rail, the space before the account row's foot. */
  --space-12: 12px; /* Spacing step, 12px: the Console menu list's side padding, a row's left padding to its glyph. The same value as gap-dense, which names the gap between controls. */
  --space-16: 16px; /* Spacing step, 16px: the brand row's side padding (the mark 16px from the menu edge), a section title's left padding. The same value as gap-standard. */
  --space-24: 24px; /* Spacing step, 24px: the indent of a Console child row under its parent. */
  --nav-panel-list-max-h: 300px; /* Navbar (structural): a switch or finder panel's list scrolls past this height. Other lists keep their own caps (Combobox 240px, PhoneInput 260px): converging them would change how many rows they show, so it is not a global decision. */
  --icon-xs: 8px; /* 8px icons, only a glyph inside a small Badge (`icon` without a number at size sm, the 8px circle, and md, the 12px circle: the do not disturb minus on an avatar). Never a glyph on its own: below 12px a glyph only reads inside its filled circle. */
  --icon-sm: 12px; /* 12px icons, the micro step: disclosure chevrons in dense rows, glyphs inside pills, chips and status marks, clear and remove controls, checks in lists, checkboxes and checklists, the Timeline marker glyph (size="sm"). */
  --icon-base: 16px; /* 16px icons, the default for every control: buttons, icon buttons, inputs, menus, overlays, alerts, pagination, the Navbar option glyphs of both surfaces open and in the rail, and its collapse controls (size="base"). Mobile: glyphs inside pills, chips, message meta (read ticks) and field adornments. */
  --icon-lg: 20px; /* 20px icons: the CompanyCard logo tile and the ConfirmDialog glyph (size="lg"). Mobile: glyphs inside buttons and rows (the leading icon of a list row). */
  --icon-xl: 24px; /* 24px icons: illustrative glyphs inside a component, such as the FileUpload dropzone (size="xl"). Mobile: the default glyph (size="xl"): header actions, tab bar, icon buttons, composer actions. */
  --icon-2xl: 32px; /* 32px icons: the glyph inside the illustration tile of empty, error and no-permission states (size="2xl"). Mobile: the glyph inside the illustration tile of empty and error states. */
  --control-xs: 24px; /* Control height, 24px: compact controls inside dense chrome (a chip remover row, a calendar header button, the Console menu collapse control). */
  --control-sm: 28px; /* Control height, 28px: menu rows (every Navbar option and child row, a section slot, the Bridge App collapse control), IconButton's default square, the chevron cell of the workspace control. Menu rows grow to 40px on a finger (data-bridge-tap="row"). */
  --control-md: 32px; /* Control height, 32px: medium controls such as the CompanyCard logo tile, a DataTable toolbar action or a calendar month button. */
  --control-lg: 36px; /* Control height, 36px: text fields, selects, comboboxes, date and phone inputs, buttons. */
  --control-xl: 44px; /* Control height, 44px: the minimum touch target, and rows sized to it (the Navbar user row). */
  --control-2xl: 48px; /* Control height, 48px: large round actions that lead a surface, such as IconButton shape="circle" appearance="filled" in a call's controls row (mute, hold, add, transfer, hang up). */
  --control-3xl: 56px; /* Control height, 56px: the last step of the control scale, taken by the phone only today: its Button size="3xl" (the main call to action of a screen, as in Calls) and the rows of a Sheet menu. One scale on both platforms (9.1.0): each picks its steps, a name never means two values. */
  --avatar-2xs: 20px; /* Avatar size, 20px (9.0.0): a person inside a chip or a dense pill. */
  --avatar-xs: 24px; /* Avatar and tile size, 24px: a workspace or company tile in a switch panel and in the open context row. */
  --avatar-sm: 28px; /* Avatar and tile size, 28px: the Navbar avatar (both surfaces), the brand mark open and in the rail, the Console lockup height, a context tile in the rail, Avatar's default, ConversationRow. */
  --avatar-md: 32px; /* Avatar size, 32px: ChatListItem and ConversationHeader. */
  --avatar-lg: 36px; /* Avatar size, 36px: the AccountPanel identity and ContactCard. */
  --avatar-xl: 40px; /* Avatar size, 40px (9.0.0): the phone's chat row, pickers, people and conversation header. */
  --avatar-2xl: 48px; /* Avatar size, 48px (9.0.0, was avatar-xl): a person card in a grid (each participant of a group call). */
  --avatar-3xl: 56px; /* Avatar size, 56px (9.0.0, was avatar-2xl): the person a panel is about when the panel also holds a message or a form (a call that needs permission, a finished call). */
  --avatar-4xl: 72px; /* Avatar size, 72px (9.0.0, was avatar-3xl): the one person a whole surface is about (a 1:1 call while it rings or is connected). On the web the largest step used: a profile header uses it too. */
  --avatar-5xl: 96px; /* Avatar size, 96px (9.0.0): the person on a full-screen call on the phone. The largest step. */
  --dot-sm: 6px; /* Dot diameter, 6px: unread and pending dots (the Navbar option glyphs in both surfaces, the workspace control and switch panel), chart legend swatches. */
  --dot-md: 8px; /* Dot diameter, 8px: presence dots on an avatar (Navbar user row, AccountPanel). */
  --badge-sm: 16px; /* Badge height scale, small (9.0.0): the web's numbered Badge, soft or solid; its height and minimum width. */
  --badge-md: 20px; /* Badge height scale, medium (9.0.0): the phone's numbered Badge, sized with its type so a count reads at a glance. */
  --touch-min: 44px; /* The smallest area that answers a finger on a web touch screen (pointer: coarse), 44 × 44: a control drawn smaller grows its area with the HIT helpers, never its drawing (README, Touch area). The phone's value is 48. */
  --data-bar-h: 10px; /* Distribution bar (SplitBar) height on its own or in a table cell: the P1.2 spec. The default size. */
  --data-bar-h-compact: 5px; /* Distribution bar (SplitBar) height inside a card footer (KpiSimple and every other card): half the table bar, so the bar never outweighs the card's figure. SplitBar size="compact". */
  --radius: 6px; /* shadcn/ui --radius, the same 6px as r-control. For projects on shadcn/ui only; components use the r-* tokens. */
  --dur-fast: 120ms; /* Colour and hover transitions, 120ms: text colour in menus, button and row backgrounds, borders on focus. 0ms under prefers-reduced-motion. */
  --dur-base: 200ms; /* Collapse and switch, 200ms: the menu's width, accordions, tab colour, the bulk bar and modal scrims fading in. 0ms under prefers-reduced-motion. */
  --dur-slow: 320ms; /* Entering surfaces, 320ms: drawers sliding in, modals and toasts rising, the narrow-viewport menu drawer. 0ms under prefers-reduced-motion. */
  --dur-loop: 1800ms; /* One cycle of a looping attention motion, 1800ms: the rings of Avatar pending (a person being reached: a call ringing, an invitation waiting). 0ms under prefers-reduced-motion, where the motion stays still. */
  --ease-out: cubic-bezier(0.2, 0, 0, 1); /* Anything entering or expanding: hovers, panels, drawers. No bounce, no spring, no overshoot. */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); /* Anything that moves and returns: the tab indicator, the skeleton pulse. */
  --nav-peek-delay: 220ms; /* Navbar (structural): how long the pointer rests on the Bridge App rail before the menu opens over the page, so crossing it does nothing. A hover-intent delay, not an animation: unlike dur-*, it keeps its value under prefers-reduced-motion, so it cannot be a duration token. */
  --hover-card-delay: 300ms; /* How long the pointer rests on an avatar before its PersonCard opens, so crossing a list opens nothing. A hover-intent delay, not an animation: it keeps its value under prefers-reduced-motion. */
  --hover-card-close: 150ms; /* How long a PersonCard stays after the pointer leaves the avatar and the card, so moving from one to the other keeps it open. A hover-intent delay: it keeps its value under prefers-reduced-motion. */
  --copied-hold: 1500ms; /* How long a copy button shows its check («Copiado») before it turns back into the copy glyph: PersonCard. A feedback hold, not an animation: it keeps its value under prefers-reduced-motion. */
  --lh-none: 1; /* Line height 1: a box that centres one glyph or a short run of glyphs on its own height, with no leading (the initials of Avatar and of each section of a composite avatar). */
  --lh-tight: 1.15; /* Line height of the kicker line in the menu brand row (the small line over the product name). */
  --lh-heading: 1.3; /* Line height of headings and the page title (PageHeader). Components write the same 1.3 as a number today. */
  --lh-meta: 18px; /* Line height of a metadata line and of what sits in it: an entity drawer's subtitle (Drawer subtitleTone="meta") and CopyValue, which is exactly this high. A fixed 18px so a row of text and a row of copy buttons have the same height. */
  --fw-regular: 400; /* Weight 400: body copy, inactive navigation, values. One of only two weights. */
  --fw-medium: 500; /* Weight 500: headings, active navigation, KPI values, table headers, pill text, section titles. 600 and 700 are never used. */
  --ls-appname: -0.2px; /* Letter spacing of the product name in the menu brand row and of initials in an avatar. */
  --ls-section: 0.4px; /* Letter spacing of uppercase section titles in the menu, the switchers and the account panel. */
  --icon-stroke: 2; /* Stroke width of every Lucide glyph on its 24 grid, applied by Icon. Never set strokeWidth on a single icon. */
  --icon-stroke-dot: 3; /* Stroke width, on the 24 grid, of a glyph alone inside a small Badge (icon without a number: the do not disturb minus of Avatar). 3 is the heaviest stroke Lucide ships (its default is 2, --icon-stroke): the glyph is small (8 or 12px), so a 2 stroke would draw under a pixel. It never goes past 3, so the glyph keeps Lucide's proportions. Only for a glyph inside a badge. */
  --bp-sm: 768px; /* Below 768px the menu becomes a 222px drawer over the scrim, the breadcrumb keeps only the current page and the account drops its name. Read through BP and useNarrow, never a viewport query of your own. */
  --bp-md: 1100px; /* Below 1100px SplitView collapses to one pane with a back control. */
  --bp-lg: 1440px; /* At 1440px the content column stops growing (content-max). */
  --layout-split-min: 1024px; /* Deprecated: the v1 viewport threshold of side panels, 1024px. Drawer v2 has no viewport breakpoint (the container minus the sibling's minimum decides) and no longer reads it. Kept so nothing breaks; removed in a later delivery. */
  --panel-reduce-max: 20%; /* Layout: how much an overlay side panel may narrow below its preferred width to leave layout-context-min of context behind it, 20%. Past it the panel takes the whole width beside the menu (Full width). Does not apply to a panel in push, which narrows down to its minimum to keep the main surface usable. */
  --background: 0 0% 100%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--background)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --foreground: 240 28% 14%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --card: 0 0% 100%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--card)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --card-foreground: 205 65% 15%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--card-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --popover: 0 0% 100%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--popover)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --popover-foreground: 240 28% 14%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--popover-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --primary: 223 60% 33%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--primary)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --primary-foreground: 0 0% 100%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--primary-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --secondary: 213 60% 98%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--secondary)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --secondary-foreground: 240 28% 14%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--secondary-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --muted: 213 60% 98%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--muted)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --muted-foreground: 217 19% 44%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--muted-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --accent: 213 60% 98%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--accent)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --accent-foreground: 240 28% 14%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--accent-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --destructive-hsl: 0 56% 41%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--destructive-hsl)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --destructive-foreground: 0 0% 100%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--destructive-foreground)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --border: 213 40% 91%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--border)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --input: 213 40% 91%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--input)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --ring: 223 60% 33%; /* shadcn/ui token bridge, HSL channels read as hsl(var(--ring)). For projects on shadcn/ui only; bundle.css holds the dark values under [data-theme='dark'] and repeats these for a light island inside a dark root. */
  --z-base: 0; /* Layer 0: the page content. */
  --z-raised: 10; /* Layer 1: an element lifted inside the content it belongs to (the floating Composer, a chart tooltip over its plot). Ordering inside one chart (pinned heatmap columns, scatter labels) stays local, below this layer. */
  --z-sticky: 100; /* Layer 2: sticky page chrome (TopStrip, PageHeader surface="app"). */
  --z-dropdown: 200; /* Layer 3: menus and lists that open from a control (Dropdown, the Combobox, Multiselect and DateInput lists) and the Navbar while it opens over the page, with its header, switch panels and user row. */
  --z-overlay: 300; /* Layer 4: surfaces over the frame with or without a scrim (Drawer, the narrow Console menu drawer and its scrim). */
  --z-modal: 400; /* Layer 5: modal dialogs, over a drawer so a confirmation can open from one (Modal, ConfirmDialog). */
  --z-popover: 500; /* Layer 6: popovers anchored to a control, over any overlay or dialog (Popover, the PhoneInput country panel, the Console rail flyout). */
  --z-toast: 600; /* Layer 7: toasts, over everything the user works in. */
  --z-tooltip: 700; /* Layer 8: tooltips, the top layer (Tooltip, the Navbar rail tooltip). */
  --opacity-disabled: 0.55; /* Opacity of a disabled or permission-gated control that stays visible and does nothing: Toggle, Radio, Checkbox, IconButton, the Pagination arrows, PermissionGate and the Navbar's options. The one disabled opacity of the system. */
  --glass-backdrop: blur(20px) saturate(180%); /* backdrop-filter of a glass surface (with -webkit-backdrop-filter): what lies behind blurs and keeps its colour. A surface with it never nests another glass surface inside it (a backdrop-filter inside one does not blur): a glass menu opens beside its bar, never inside it. */
  --font-sans: 'Helvetica Neue', Roboto, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --text-fs-10: 400 10px/1.4 var(--font-sans); /* 10px. Web: the initial inside a workspace or company tile (avatar-xs). */
  --text-fs-10-5: 400 10.5px/1.4 var(--font-sans); /* 10.5px. Web: chart annotations and axis ticks, message meta, chat list times, avatar initials under 32px, small menu counts; table header labels in uppercase at --fw-medium with --ls-th. */
  --text-fs-11: 400 11px/1.4 var(--font-sans); /* 11px. Web: uppercase section titles in menus (with --ls-section) and count pills. Mobile: tab bar labels and count badges (tab, on 14), the platform floor. */
  --text-fs-11-5: 400 11.5px/1.4 var(--font-sans); /* 11.5px. Web: captions, chart legends and tooltips, card titles and eyebrows, timeline and stepper notes. */
  --text-fs-12: 400 12px/1.4 var(--font-sans); /* 12px. Web: field labels, filter controls, pagination, description list terms, breadcrumbs. Mobile: caption (on 16), the smallest reading size. */
  --text-fs-12-5: 400 12.5px/1.4 var(--font-sans); /* 12.5px. Web: secondary lines, list previews, dropdown rows, dialog body text. */
  --text-fs-13: 400 13px/1.5 var(--font-sans); /* 13px on 1.5. Web: body copy, inputs, buttons and table cells, the default everywhere. Mobile: meta (on 18), times and section headers. */
  --text-fs-13-5: 400 13.5px/1.3 var(--font-sans); /* 13.5px on 1.3. Web: menu items in Navbar, conversation header titles. */
  --text-fs-14: 400 14px/1.4 var(--font-sans); /* 14px. Web: the product name in a menu brand row and the Chats title of the chat list panel (at --fw-medium). Mobile: secondary and label (on 20). */
  --text-fs-16: 400 16px/1.375 var(--font-sans); /* 16px. Mobile: body and body-strong (on 22), the default for anything read in full. */
  --text-fs-17: 400 17px/1.3 var(--font-sans); /* 17px. Mobile: the title of a compact header (header, on 22). */
  --text-fs-18: 400 18px/1.3 var(--font-sans); /* 18px on 1.3. Web: the page title (PageHeader) at --fw-medium, one per screen. */
  --text-fs-22: 400 22px/1.4 var(--font-sans); /* 22px. Web: KPI values and the figure inside a donut or gauge, at --fw-medium with --ls-metric. Mobile: sheet, dialog and profile titles (title, on 28). */
  --text-fs-30: 400 30px/1.2 var(--font-sans); /* 30px. Mobile: the large title of a root tab screen (largeTitle, on 36), once per screen. */
  --text-body: 400 13px/1.5 var(--font-sans); /* The body text of every screen, as base/reset.css set it: 13px on 1.5, weight 400. */
}
.fs-10 {
  font-family: var(--font-sans);
  font-size: 10px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-10-5 {
  font-family: var(--font-sans);
  font-size: 10.5px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-11 {
  font-family: var(--font-sans);
  font-size: 11px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-11-5 {
  font-family: var(--font-sans);
  font-size: 11.5px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-12 {
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-12-5 {
  font-family: var(--font-sans);
  font-size: 12.5px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-13 {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-13-5 {
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-14 {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-16 {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.375;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-17 {
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-18 {
  font-family: var(--font-sans);
  font-size: 18px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-22 {
  font-family: var(--font-sans);
  font-size: 22px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
}
.fs-30 {
  font-family: var(--font-sans);
  font-size: 30px;
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: 0;
}
.body {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0;
}
