/*
 * Fightclub look for LibreChat, applied on top of its own theme variables.
 * LibreChat's tokens are plain colours used as var(--x) (only --brand-purple is an RGB triplet). This file only sets values;
 * every colour comes from the kit's brand contract (resources/js/brands/fightclub.css):
 *   ink #0b0b0b = 11 11 11     ink raised #2b2b2b = 43 43 43     ink sunken #0f0f0f = 15 15 15
 *   paper #efebe1 = 239 235 225   paper subtle #f5f5f6 = 245 245 246   paper muted #ededed = 237 237 237
 *   red #ff3f37 = 255 63 55    white = 255 255 255
 */

@font-face { font-family: "Nohemi"; font-weight: 400; font-display: swap; src: url("/assets/fc/assets/fonts/nohemi-400.woff2") format("woff2"); }
@font-face { font-family: "Nohemi"; font-weight: 500; font-display: swap; src: url("/assets/fc/assets/fonts/nohemi-500.woff2") format("woff2"); }
@font-face { font-family: "Nohemi"; font-weight: 700; font-display: swap; src: url("/assets/fc/assets/fonts/nohemi-700.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 400; font-display: swap; src: url("/assets/fc/assets/fonts/manrope-400.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 500; font-display: swap; src: url("/assets/fc/assets/fonts/manrope-500.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 600; font-display: swap; src: url("/assets/fc/assets/fonts/manrope-600.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 700; font-display: swap; src: url("/assets/fc/assets/fonts/manrope-700.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 800; font-display: swap; src: url("/assets/fc/assets/fonts/manrope-800.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 500; font-display: swap; src: url("/assets/fc/assets/fonts/poppins-500.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 600; font-display: swap; src: url("/assets/fc/assets/fonts/poppins-600.woff2") format("woff2"); }

/* Light: white panel, ink text, one red accent. The rail is scoped below. Only on the root: LibreChat also puts a "light"
 * class on every answer's markdown, and light values there turned code blocks light with white text in dark mode. */
:root,
html,
html.light {
  --brand-purple: 255 63 55;
  --presentation: #ffffff;
  --surface-primary: #ffffff;
  --surface-primary-alt: #f5f5f6;
  --surface-primary-contrast: #f5f5f6;
  --surface-secondary: #f5f5f6;
  --surface-secondary-alt: #f5f5f6;
  --surface-tertiary: #ededed;
  --surface-tertiary-alt: #ededed;
  --surface-chat: #f5f5f6;
  --surface-composer-hover: #ededed;
  --surface-hover: #ededed;
  --surface-hover-alt: #ededed;
  --surface-active: #ededed;
  --surface-active-alt: #f5f5f6;
  --surface-dialog: #ffffff;
  --surface-submit: #ff3f37;
  --surface-submit-hover: #e6342d;
  --surface-code: #f5f5f6;
  --surface-inverted: #0b0b0b;
  --surface-inverted-hover: #2b2b2b;
  --surface-destructive: #ff3f37;
  --surface-destructive-hover: #e6342d;
  --text-primary: #0b0b0b;
  --text-secondary: #4a4a4a;
  --text-secondary-alt: #6b6b6b;
  --text-tertiary: #6b6b6b;
  --text-muted: #6b6b6b;
  --text-inverted: #efebe1;
  --text-warning: #ff3f37;
  --header-primary: #ffffff;
  --header-hover: #ededed;
  --header-button-hover: #ededed;
  --link: #0b0b0b;
  --link-hover: #ff3f37;
  --ring-primary: #ff3f37;
  --border-light: rgba(11, 11, 11, 0.08);
  --border-medium: rgba(11, 11, 11, 0.12);
  --border-medium-alt: rgba(11, 11, 11, 0.12);
  --border-heavy: rgba(11, 11, 11, 0.2);
  --border-xheavy: rgba(11, 11, 11, 0.3);
  --radius: 1rem;
  --theme-font-family: "Manrope", "Inter", sans-serif;
}

/* Dark: ink page, raised ink surfaces, cream text; the red stays the same. */
.dark {
  --brand-purple: 255 63 55;
  --presentation: #0f0f0f;
  --surface-primary: #0f0f0f;
  --surface-primary-alt: #0b0b0b;
  --surface-primary-contrast: #2b2b2b;
  --surface-secondary: #1a1a1a;
  --surface-secondary-alt: #1a1a1a;
  --surface-tertiary: #2b2b2b;
  --surface-tertiary-alt: #2b2b2b;
  --surface-chat: #1a1a1a;
  --surface-composer-hover: #2b2b2b;
  --surface-hover: #2b2b2b;
  --surface-hover-alt: #2b2b2b;
  --surface-active: #2b2b2b;
  --surface-active-alt: #1a1a1a;
  --surface-dialog: #0f0f0f;
  --surface-submit: #ff3f37;
  --surface-submit-hover: #e6342d;
  --surface-code: #0b0b0b;
  --surface-inverted: #efebe1;
  --surface-inverted-hover: #ffffff;
  --surface-destructive: #ff3f37;
  --surface-destructive-hover: #e6342d;
  --text-primary: #efebe1;
  --text-secondary: #c8c5bd;
  --text-secondary-alt: #aaa8a0;
  --text-tertiary: #aaa8a0;
  --text-muted: #aaa8a0;
  --text-inverted: #0b0b0b;
  --text-warning: #ff3f37;
  --header-primary: #0f0f0f;
  --header-hover: #2b2b2b;
  --header-button-hover: #2b2b2b;
  --link: #efebe1;
  --link-hover: #ff3f37;
  --border-light: rgba(239, 235, 225, 0.1);
  --border-medium: rgba(239, 235, 225, 0.15);
  --border-medium-alt: rgba(239, 235, 225, 0.15);
  --border-heavy: rgba(239, 235, 225, 0.25);
  --border-xheavy: rgba(239, 235, 225, 0.35);
}

/* The rail: the sidebar (icon strip plus conversations) is ink in both modes, like the kit's SidebarLayout.
 * Hover and active are opaque: the title fade in the chat list is a gradient from these colours, so a translucent value would stack. */
aside:has(nav) {
  --surface-primary: #0b0b0b;
  --surface-primary-alt: #0b0b0b;
  --surface-secondary: #151515;
  --surface-secondary-alt: #151515;
  --surface-tertiary: #2b2b2b;
  --surface-hover: #242424;
  --surface-hover-alt: #242424;
  --surface-active: #2b2b2b;
  --surface-active-alt: #2b2b2b;
  --text-primary: #efebe1;
  --text-secondary: #aaa8a0;
  --text-secondary-alt: #aaa8a0;
  --text-tertiary: #aaa8a0;
  --border-light: rgba(239, 235, 225, 0.1);
  --border-medium: rgba(239, 235, 225, 0.15);
  /* shadcn's HSL tokens for a hovered control (the rail icons, the memory panel's buttons): light by default, ink here */
  --accent: 0 0% 14%;
  --accent-foreground: 43 30% 91%;
  color: #efebe1;
  color-scheme: dark;
}
aside:has(nav) input {
  color: #efebe1;
}
/* LibreChat draws the new-chat pencil beside "Chats" and a project in black (white in dark mode): on the ink rail it takes its button's colour like every other icon */
aside:has(nav) .text-black.dark\:text-white {
  color: inherit;
}
/* The small buttons beside "Chats" and a project (new chat, more) hover like every other rail control, not in the active colour */
aside:has(nav) .hover\:bg-surface-active-alt:hover {
  background-color: var(--surface-hover);
}
aside:has(nav) input::placeholder {
  color: #aaa8a0;
}

/* The frame is ink: a sub-pixel gap under the app then shows ink, not the browser's white canvas. */
html,
body {
  background-color: #0b0b0b;
}
/* Scrollbars: thin, no track, a quiet thumb */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-medium) transparent;
}

/* Type: Nohemi for headings, Manrope for text, Poppins for buttons. */
body,
#root {
  font-family: "Manrope", "Inter", sans-serif;
  letter-spacing: 0;
}
h1,
h2,
h3,
.prose h1,
.prose h2,
.prose h3 {
  font-family: "Nohemi", "Manrope", sans-serif;
  font-weight: 700;
  letter-spacing: -0.01em;
}
button,
[role="button"] {
  font-family: "Poppins", "Manrope", sans-serif;
  font-weight: 500;
}
/* The welcome line on an empty chat: a Nohemi headline. */
div.flex.flex-col.items-center.gap-0.p-2 {
  font-family: "Nohemi", "Manrope", sans-serif;
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* Shape: the kit's radii. Cards 20px, pills for controls. */
[class*="rounded-3xl"],
[class*="rounded-2xl"] {
  border-radius: 20px !important;
}
input[type="text"],
input[type="email"],
input[type="password"],
[data-testid="model-selector-button"] {
  border-radius: 9999px !important;
}

/* The one red thing: the send button (and the primary button on the login screens).
 * Scoped to buttons and links: LibreChat also uses bg-green-500 for a connected MCP status dot, which must stay green. */
button[data-testid="send-button"] {
  background: #ff3f37 !important;
  color: #efebe1 !important;
}
/* LibreChat's green primary buttons and links become the red one. Only those: the same class colours status dots
 * too (an MCP server that is connected), and those stay green. */
button.bg-green-600,
button.bg-green-500,
a.bg-green-600,
a.bg-green-500 {
  background-color: #ff3f37 !important;
  color: #efebe1 !important;
}
button.hover\:bg-green-700:hover,
button.hover\:bg-green-600:hover,
a.hover\:bg-green-700:hover,
a.hover\:bg-green-600:hover {
  background-color: #e6342d !important;
}
/* LibreChat's own button classes (editing a message: "Save & Submit", "Save", "Cancel"): the primary one ink on paper
 * (paper on ink in dark mode), since red stays the send button's; the secondary one plain */
.btn-primary {
  background-color: var(--surface-inverted);
  color: var(--text-inverted);
}
.btn-primary:hover {
  background-color: var(--surface-inverted-hover);
}
.btn-secondary {
  background-color: var(--surface-tertiary);
  color: var(--text-primary);
}
.btn-secondary:hover {
  background-color: var(--surface-hover);
}
/* Ring's answers are not editable: an edited answer (or its thoughts, which hold Ring's own status lines) would rewrite what
 * the model reads back as its own words. Your own messages keep their edit button. */
[aria-label^="Message"]:has(.agent-turn) button[id^="edit-"] {
  display: none;
}
/* The memory panel's usage pill: LibreChat's green, a plain chip here */
.bg-green-100.text-green-700 {
  background-color: var(--surface-tertiary);
  color: var(--text-secondary);
}
.text-green-600,
.text-green-500,
.dark .text-green-500 {
  color: #0b0b0b !important;
}
.dark .text-green-600,
.dark .text-green-500 {
  color: #efebe1 !important;
}

/* Logo and avatar: the Fightclub mark, and no purple initials. */
img[alt="FChat Logo"],
img[alt="Ring Logo"],
img[src$="assets/logo.svg"] {
  content: url("/assets/fc/assets/mark.svg");
}
img[alt$="avatar"] {
  filter: grayscale(1);
}

/* The price line under an answer (FChat's footer, an italic last paragraph): small and muted. */
.markdown > p:last-child > em:only-child,
.prose > p:last-child > em:only-child {
  display: inline-block;
  margin-top: 0.25rem;
  font-size: 0.8rem;
  font-style: normal;
  color: var(--text-secondary-alt);
}
/* Hidden unless "Toon model en kosten onder antwoorden" is on in the chat settings (fc-details.js marks the line). */
html:not(.fc-show-details) .fc-price {
  display: none;
}
/* The paragraph above the hidden line then ends the answer: drop its bottom margin too, or the answer keeps the space. */
html:not(.fc-show-details) .markdown > :has(+ .fc-price:last-child),
html:not(.fc-show-details) .prose > :has(+ .fc-price:last-child) {
  margin-bottom: 0;
}

/* The frame: like the kit's SidebarLayout, the content is a rounded panel on the ink page. */
#root > div.flex > div.relative.z-0.flex.h-full.w-full.overflow-hidden {
  background: #0b0b0b;
}
#root > div.flex > div.relative.z-0 > div.flex-col.overflow-hidden > div.bg-presentation {
  height: calc(100% - 1rem);
  width: calc(100% - 1rem) !important;
  margin: 0.5rem;
  border-radius: 20px;
  border: 1px solid rgba(239, 235, 225, 0.08);
  overflow: hidden;
}
.dark #root > div.flex > div.relative.z-0 > div.flex-col.overflow-hidden > div.bg-presentation {
  background: #0f0f0f;
  border-color: rgba(239, 235, 225, 0.12);
}
/* The rail sits flush against the panel: no border line between them. */
aside:has(nav) .border-r {
  border-right-color: transparent;
}

/* Rail buttons (the icon strip): a visible cream wash on hover, the icon turns cream. In the list next to it a control
 * brightens its text only; rows and small buttons there draw their own hover, so washes never stack and a section title
 * ("Chats", the client) stays aligned with the rows under it. */
aside:has(nav) .border-r :is(button, a):hover {
  background-color: #242424;
  color: #efebe1;
}
aside:has(nav) :is(button, a):hover {
  color: #efebe1;
}
aside:has(nav) button[aria-pressed="true"],
aside:has(nav) button[data-state="active"],
aside:has(nav) [aria-current="page"] {
  background-color: #2b2b2b;
  color: #efebe1;
}

/* The tools menu stays: that is where the MCP servers (Notion, Airtable, Google) are picked and authorised. */

/* Only the user's messages sit in a bubble, on the right in ink. The model's answer is the page itself: no box, the full
 * column, so headings, tables and code blocks read as a document and nothing grows around the text while it streams.
 * A turn is .message-render > [avatar column] + .user-turn | .agent-turn > h2 + (content column > .text-message parts + actions row). */
.message-render:has(> .user-turn) {
  flex-direction: row-reverse;
}
.message-render > .user-turn > h2 {
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
}
/* The time keeps LibreChat's own show-on-hover, but sits left of the name and always takes its space: nothing shifts. */
.message-render > .user-turn > h2 > time {
  order: -1;
  margin-left: 0;
  margin-right: 0.5rem;
}
.message-render > .user-turn div.mt-1.justify-start {
  justify-content: flex-end;
}
.message-render > .user-turn .text-message {
  width: fit-content;
  align-self: flex-end;
  max-width: 85%;
  padding: 0.75rem 1rem;
  border-radius: 20px;
  border-top-right-radius: 6px;
  background: #0b0b0b;
  color: #efebe1;
}
.dark .message-render > .user-turn .text-message {
  background: #efebe1;
  color: #0b0b0b;
}
/* While editing a message the bubble holds a textarea: full width again, and the composer's look instead of the bubble's
 * (LibreChat's edit box sets the page's text colour, which on the ink bubble left the text invisible). Only "Save & Submit":
 * an edited message is meant to be sent again, a plain "Save" would rewrite the history without an answer to it. */
.message-render > .user-turn .text-message:has(textarea),
.dark .message-render > .user-turn .text-message:has(textarea) {
  width: 100%;
  max-width: 100%;
  background: var(--surface-chat);
  color: var(--text-primary);
}
.message-render > .user-turn .text-message:has(textarea) .btn-secondary {
  display: none;
}
/* The prose inside the user bubble follows the bubble's colour, not the page's. */
.message-render > .user-turn .text-message .markdown,
.message-render > .user-turn .text-message .markdown :is(p, li, strong, em, a, code, h1, h2, h3, h4, h5, h6, blockquote) {
  color: inherit;
}
.message-render > .user-turn .text-message .markdown > :first-child {
  margin-top: 0;
}
.message-render .text-message .markdown > :last-child {
  margin-bottom: 0;
}
/* An app or vaardigheid the message names with @ (RingMentionText, remarkRingMention): the same text, a shade lighter
 * behind it, no colour. The dark-mode bubble is cream, so there the shade is darker. */
.fc-mention {
  font-weight: 600;
  background: rgba(255, 255, 255, 0.14);
  border-radius: 6px;
  padding: 1px 5px;
  margin-right: 2px;
}
.dark .fc-mention {
  background: rgba(0, 0, 0, 0.08);
}
/* Sidebar titles: no coloured fade block over the rounded rows (it never matched the hover colour); clip with an ellipsis instead. */
aside:has(nav) [class*="gradient-to-l"],
aside:has(nav) [class*="linear-to-l"] {
  display: none !important;
}
aside:has(nav) a[href^="/c/"] {
  overflow: hidden;
  border-radius: 0.5rem;
}
aside:has(nav) a[href^="/c/"] [class*="truncate"],
aside:has(nav) a[href^="/c/"] [class*="line-clamp"] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: 1.75rem;
}

/* Motion: a new turn eases in (opacity plus a 6px rise, 220ms ease-out) via @starting-style; the scroll glide lives in
 * fc-scroll.js. LibreChat's own transition-all on the turn is narrowed to these two properties. Reduced motion keeps the fade. */
:root {
  --fc-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}
div.message-render {
  opacity: 1;
  translate: none;
  transition: opacity 220ms var(--fc-ease-out), translate 220ms var(--fc-ease-out);
}
@starting-style {
  div.message-render {
    opacity: 0;
    translate: 0 6px;
  }
}
@media (prefers-reduced-motion: reduce) {
  div.message-render {
    transition: opacity 220ms var(--fc-ease-out);
  }
  @starting-style {
    div.message-render {
      translate: none;
    }
  }
}

/* Help hover cards (the fork menu) are a fixed 20rem wide. patch-locale.sh lets them flip to the side with room; on a narrow
 * screen neither side has 20rem, so they never grow past the room Ariakit measured beside the anchor. */
.z-\[999\].w-80 {
  max-width: var(--popover-available-width, 20rem);
}

/* The approval app has its own kit styles inside this isolated frame. */
.fc-approval-frame {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  z-index: 2147483000;
}

/* FChat's own icons (the Ring mark, the vendor logos) have their own shape. LibreChat frames icons in a circle and crops
 * them to fill it, which cut the sides off the mark and the corners off square logos: show them whole. */
.rounded-full:has(> img[src*="/assets/fc/assets/"]),
img[src*="/assets/fc/assets/"] {
  border-radius: 0 !important;
}
img[src*="/assets/fc/assets/"] {
  object-fit: contain !important;
}

/* The Anthropic, OpenAI and xAI marks are drawn in ink; in dark mode and in the always-dark sidebar they turn light. */
.dark img[src*="/assets/fc/assets/vendors/anthropic.svg"],
.dark img[src*="/assets/fc/assets/vendors/openai.svg"],
.dark img[src*="/assets/fc/assets/vendors/xai.svg"],
nav img[src*="/assets/fc/assets/vendors/anthropic.svg"],
nav img[src*="/assets/fc/assets/vendors/openai.svg"],
nav img[src*="/assets/fc/assets/vendors/xai.svg"] {
  filter: invert(1);
}

/* The model picker's search field sits flush in its menu, so the menu's edge clipped the focus ring around it. Round
 * the field like the menu and draw the focus line inside it. */
#model-search {
  border-radius: 12px !important;
}
#model-search:focus,
#model-search:focus-visible {
  box-shadow: inset 0 0 0 1px var(--border-heavy) !important;
  outline: none !important;
}

/* "Nadenken" (fc-reasoning.js): a pill next to the tools button, with its menu opening upwards like LibreChat's own. */
.fc-reasoning {
  position: relative;
  display: flex;
  align-items: center;
}
.fc-reasoning-button {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 14px;
  border-radius: 9999px;
  border: 1px solid var(--border-light);
  color: var(--text-secondary);
  font-size: 0.8125rem;
  white-space: nowrap;
  transition: background-color 150ms, color 150ms;
}
.fc-reasoning-button:hover,
.fc-reasoning-button[aria-expanded="true"] {
  background: var(--surface-hover);
  color: var(--text-primary);
}
.fc-reasoning-button:not([data-level="auto"]) {
  color: var(--text-primary);
}
.fc-reasoning-button:focus-visible {
  outline: 2px solid var(--border-heavy);
  outline-offset: 2px;
}
.fc-reasoning-menu {
  position: fixed;
  z-index: 1000;
  min-width: 260px;
  padding: 6px;
  border-radius: 16px;
  border: 1px solid var(--border-light);
  background: var(--surface-primary);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}
.fc-reasoning-option {
  display: flex;
  width: 100%;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 8px 12px;
  border-radius: 10px;
  text-align: left;
}
.fc-reasoning-option:hover,
.fc-reasoning-option:focus-visible {
  background: var(--surface-hover);
  outline: none;
}
.fc-reasoning-option[aria-checked="true"] .fc-reasoning-name::after {
  content: " ✓";
}
.fc-reasoning-name {
  font-size: 0.875rem;
  color: var(--text-primary);
}
.fc-reasoning-hint {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

/* What Ring did (fc-status.js): one live line while Ring works, one folded summary once the answer is there. */
.fc-status { margin: 2px 0 6px; }
.fc-status:empty { display: none; }
.fc-status-ico { width: 16px; height: 16px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.fc-live { display: flex; align-items: center; gap: 9px; min-height: 28px; color: var(--text-secondary); font-size: 0.95rem; }
.fc-live .fc-status-ico { color: var(--text-tertiary); flex: none; }
/* one line, whatever the model is thinking: a long thought ends in an ellipsis instead of pushing the answer down */
.fc-live .fc-shimmer { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.fc-live .fc-timer { flex: none; }
/* work mode: where in the plan Ring is ("Stap 2 van 5 · ronde 7"), quiet, after what it does */
.fc-live-ctx { flex: none; color: var(--text-tertiary); font-size: 0.85rem; font-variant-numeric: tabular-nums; }
/* work mode: Ring's plan as a checklist, above the live line and in the steps behind the summary. An open circle for a
 * step to do, the red dot pulsing like the one where the answer starts for the step Ring is on, a tick when done. */
.fc-plan { list-style: none; margin: 4px 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 0.9rem; line-height: 1.35; }
.fc-plan li { display: grid; grid-template-columns: 16px 1fr; gap: 10px; align-items: start; color: var(--text-tertiary); }
.fc-plan li[data-status="in_progress"] { color: var(--text-primary); font-weight: 600; }
.fc-plan li[data-status="completed"] { color: var(--text-secondary); }
.fc-plan-mark { display: grid; place-items: center; width: 16px; height: 1.2em; }
.fc-plan-mark .fc-status-ico { width: 14px; height: 14px; color: var(--text-primary); stroke-width: 2.2; }
.fc-plan-open { width: 11px; height: 11px; border-radius: 999px; border: 1.5px solid var(--border-xheavy); }
.fc-plan-skip { width: 10px; height: 1.5px; border-radius: 1px; background: var(--text-tertiary); }
.fc-plan li[data-status="skipped"] { color: var(--text-tertiary); text-decoration: line-through; text-decoration-color: var(--border-xheavy); }
.fc-plan-now { width: 10px; height: 10px; border-radius: 999px; background: #ff3f37; animation: fc-dot 1.4s ease-in-out infinite; }
.fc-plan-note { margin: -2px 0 8px 26px; font-size: 0.85rem; color: var(--text-tertiary); }
.fc-panel .fc-plan { margin: 8px 0 2px; }
.fc-shimmer {
  background: linear-gradient(90deg, var(--text-tertiary) 0%, var(--text-tertiary) 40%, var(--text-primary) 50%, var(--text-tertiary) 60%, var(--text-tertiary) 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: fc-shimmer 2.2s linear infinite;
}
@keyframes fc-shimmer { from { background-position: 100% 0; } to { background-position: -150% 0; } }
.fc-timer { color: var(--text-tertiary); font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.fc-summary { display: inline-flex; align-items: center; gap: 8px; min-height: 28px; padding: 3px 0; color: var(--text-secondary); font-size: 0.9rem; text-align: left; }
.fc-summary:hover { color: var(--text-primary); }
.fc-summary:focus-visible { outline: 2px solid var(--border-heavy); outline-offset: 3px; border-radius: 6px; }
.fc-summary .fc-sep { color: var(--text-tertiary); }
.fc-summary > .fc-status-ico:last-child { width: 15px; height: 15px; transition: transform 0.2s; }
.fc-summary[aria-expanded="true"] > .fc-status-ico:last-child { transform: rotate(180deg); }
.fc-panel { margin: 8px 0 6px 2px; padding: 12px 14px 0; border-left: 2px solid var(--border-light); }
.fc-steps { list-style: none; margin: 0; padding: 0; }
.fc-steps > li { position: relative; display: grid; grid-template-columns: 22px 1fr; gap: 10px; padding-bottom: 12px; }
.fc-steps > li:not(:last-child)::before { content: ""; position: absolute; left: 10px; top: 22px; bottom: 2px; width: 1px; background: var(--border-medium); }
.fc-dot { width: 22px; height: 22px; border-radius: 999px; display: grid; place-items: center; background: var(--surface-tertiary); color: var(--text-secondary); }
.fc-dot .fc-status-ico { width: 13px; height: 13px; }
.fc-steps > li.fc-failed .fc-dot { background: rgba(255, 63, 55, 0.15); color: #ff3f37; }
.fc-step-t { font-weight: 600; font-size: 0.9rem; line-height: 22px; color: var(--text-primary); }
.fc-step-d { font-size: 0.85rem; color: var(--text-secondary); margin-top: 1px; }
.fc-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.fc-chip { display: inline-flex; align-items: center; gap: 6px; padding: 2px 9px 2px 4px; border-radius: 999px; background: var(--surface-tertiary); font-size: 0.8rem; color: var(--text-secondary); }
/* the model's thoughts inside the thinking step: the text as it came, quiet, scrolling when long */
.fc-thoughts { margin-top: 6px; max-height: 16rem; overflow-y: auto; white-space: pre-wrap; font-size: 0.85rem; line-height: 1.5; color: var(--text-secondary); }
.fc-tile { flex: none; display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 4px; font: 700 9.5px "Manrope", sans-serif; color: #fff; }
.fc-status-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Where the answer will start, a pulsing dot until its first word. LibreChat draws one only for an empty answer, and a
 * Ring answer never is: its steps stream in as thinking from the start. So the dot is drawn here, under the live line. */
.agent-turn:has(> .fc-status > .fc-live) > .flex-col > :first-child:not(:has(.markdown))::after {
  content: "";
  display: block;
  width: 12px;
  height: 12px;
  margin: 4px 0 0 2px;
  border-radius: 999px;
  background: var(--text-primary);
  animation: fc-dot 1.4s ease-in-out infinite;
}
@keyframes fc-dot {
  0%, 100% { scale: 0.7; opacity: 0.5; }
  50% { scale: 1; opacity: 1; }
}
/* an app's logo where the status has an icon: the summary of an apps turn, the live line while its tool runs, its step */
.fc-status-app { width: 16px; height: 16px; flex: none; }
.fc-dot .fc-status-app { width: 13px; height: 13px; }
/* Once a turn has its summary, the tool calls that finished well fold into it ("Gmail · 4 mails gelezen"): LibreChat's rows
 * (ToolCall.tsx) and groups (ToolCallGroup.tsx) mark themselves with data-fc-*. A row that errored, still runs or waits for
 * a sign-in stays, and so does a Gmail card. A row goes with its details (the block right after it); a group with its
 * header and body. What the tools made (a picture) stays. The details and the body carry LibreChat's inline
 * `display: grid` (useExpandCollapse), which only !important beats: without it a block opened by hand or by "expand tools"
 * would stay on screen after its header, the only way to close it, went. */
.agent-turn:has(> .fc-status > .fc-summary) [data-fc-tool][data-fc-done="true"][data-fc-error="false"]:not([data-fc-card]),
.agent-turn:has(> .fc-status > .fc-summary) [data-fc-tool][data-fc-done="true"][data-fc-error="false"]:not([data-fc-card]) + div,
.agent-turn:has(> .fc-status > .fc-summary) [data-fc-tool-group][data-fc-done="true"][data-fc-error="false"] > button:first-child,
.agent-turn:has(> .fc-status > .fc-summary) [data-fc-tool-group][data-fc-done="true"][data-fc-error="false"] > button:first-child + div,
.agent-turn:has(> .fc-status > .fc-summary) [data-fc-tool-group][data-fc-done="true"][data-fc-error="false"]:not(:has(> :nth-child(3))) {
  display: none !important;
}
/* A running tool row does not shimmer: the status line above already moves while Ring works, and a second moving line
 * per row made a work run restless. The row's words say it runs ("Bouwt een presentatie"). */
.agent-turn [data-fc-tool] .shimmer {
  animation: none;
  background: none;
  -webkit-text-fill-color: currentColor;
}
/* Less motion asked for: tool rows and groups (ToolCall.tsx, ToolCallGroup.tsx) open and close without sliding, their
 * chevrons turn without turning and their icons do not pulse. The inline `transition` is useExpandCollapse's. */
@media (prefers-reduced-motion: reduce) {
  .agent-turn [data-fc-tool] .animate-pulse,
  .agent-turn [data-fc-tool-group] .animate-pulse { animation: none; }
  .agent-turn [data-fc-tool] .transition-transform { transition: none; }
  .agent-turn [data-fc-tool] + div[style],
  .agent-turn [data-fc-tool-group] > div[style] { transition: none !important; }
}
/* What a rewrite took out ("Wat de Humanizer weghaalde"): FChat's heading and list are hidden, fc-status.js shows a copy
 * after them, quiet, with a rule on the left, dashes and the quoted words in the text colour. */
.markdown .fc-changed-head, .markdown .fc-changed-list { display: none; }
.markdown .fc-changed { margin: 4px 0 14px 2px; padding: 10px 14px 4px; border-left: 2px solid var(--border-light); }
.markdown .fc-changed-t { margin: 0 0 6px; font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }
.markdown .fc-changed ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; font-size: 0.875rem; line-height: 1.45; color: var(--text-secondary); }
.markdown .fc-changed li { position: relative; margin: 0; padding: 2px 0 2px 22px; }
.markdown .fc-changed li::before { content: "–"; position: absolute; left: 2px; color: var(--text-tertiary); }
.markdown .fc-changed-q { color: var(--text-primary); }
/* In a Ring turn LibreChat's thinking blocks are hidden: the status shows Ring's steps and the model's thoughts as one of them */
[class*="group/reasoning"].fc-status-bare { display: none; }
/* the sources under an answer: a stack of initials with "N bronnen" that opens the list */
.markdown .fc-sources-head, .markdown .fc-sources-list { display: none; }
.markdown.fc-sources-open .fc-sources-head, .markdown.fc-sources-open .fc-sources-list { display: block; }
/* a block of its own under the answer: its margin falls together with the paragraph's instead of adding a line; line-height 1 centres the text on the tiles */
.fc-sources { display: flex; width: fit-content; align-items: center; gap: 8px; margin-top: 10px; padding: 4px 11px 4px 6px; line-height: 1; border-radius: 999px; background: var(--surface-tertiary); font-size: 0.8rem; color: var(--text-secondary); }
.fc-sources:hover { color: var(--text-primary); }
.fc-sources:focus-visible { outline: 2px solid var(--border-heavy); outline-offset: 2px; }
.fc-tiles { display: inline-flex; }
.fc-tiles .fc-tile { margin-left: -5px; box-shadow: 0 0 0 2px var(--surface-tertiary); }
.fc-tiles .fc-tile:first-child { margin-left: 0; }
@media (prefers-reduced-motion: reduce) {
  .fc-shimmer { animation: none; background: none; color: var(--text-secondary); }
  .fc-plan-now { animation: none; }
  .fc-summary > .fc-status-ico:last-child { transition: none; }
  .agent-turn > .flex-col > :first-child::after { animation: none; }
}

/* The step before WorkOS on /login: the whole page is the wait. Logo (the one red thing), a Nohemi line, one sentence and
 * a quiet ring turning; nothing to click, since the browser is already on its way. */
.ring-signin {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  align-items: center;
  justify-content: center;
  padding: 1.5rem 1rem;
  background: var(--surface-primary);
  color: var(--text-primary);
}
.ring-signin__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: 24rem;
  text-align: center;
  animation: ring-signin-in 0.4s ease-out both;
}
.ring-signin__logo {
  height: 2.75rem;
  width: auto;
  margin-bottom: 1.25rem;
}
.ring-signin__logo--dark { display: none; }
.dark .ring-signin__logo--light { display: none; }
.dark .ring-signin__logo--dark { display: block; }
.ring-signin__title {
  margin: 0;
  font-family: "Nohemi", "Manrope", sans-serif;
  font-weight: 500;
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.ring-signin__text {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--text-secondary);
}
.ring-signin__spinner {
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 1rem;
  border-radius: 9999px;
  border: 2px solid var(--border-medium);
  border-top-color: var(--text-primary);
  animation: ring-signin-turn 0.9s linear infinite;
}
@keyframes ring-signin-turn {
  to { transform: rotate(360deg); }
}
@keyframes ring-signin-in {
  from { opacity: 0; transform: translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .ring-signin__panel { animation: none; }
  .ring-signin__spinner { animation-duration: 2.4s; }
}
