/* Developer Platform Phase C1 Task 4 — brand tokens copied verbatim from
   frontend/src/styles.css's Tailwind 4 `@theme` block (re-measure that file
   before changing any value here; never invent a palette — D-C1-04). */
:root {
  --lb-color-canvas: #f9f9f9;
  --lb-color-surface: #ffffff;
  --lb-color-surface-alt: #f3f5f8;
  --lb-color-surface-2: #eaedf2;
  --lb-color-border: #ececf0;
  --lb-color-border-soft: #eef0f4;

  --lb-color-fg: #3b4049;
  --lb-color-fg-strong: #1a1d24;
  --lb-color-fg-muted: #676e7d;
  --lb-color-fg-subtle: #9aa1ad;

  --lb-color-brand-50: #eef2ff;
  --lb-color-brand-100: #dfe6ff;
  --lb-color-brand-200: #c2cdfb;
  --lb-color-brand-500: #4a6bff;
  --lb-color-brand-600: #3355ff; /* primary accent — CTAs, links, focus rings */
  --lb-color-brand-700: #2b49e0; /* hover/active on primary */
  --lb-color-brand-900: #1e2f8a;

  --lb-color-success-600: #15935b;
  --lb-color-warning-600: #c5820a;
  --lb-color-danger-600: #d4453b;
  --lb-color-info-600: #2570d6;

  --lb-font-sans: "Figtree", "Inter", "ui-sans-serif", "system-ui", sans-serif;
  --lb-font-mono: "JetBrains Mono", "ui-monospace", "SFMono-Regular", monospace;

  --lb-radius-xs: 4px;
  --lb-radius-sm: 6px;
  --lb-radius-md: 9px;
  --lb-radius-lg: 14px;

  --lb-shadow-xs: 0 1px 2px rgba(15, 18, 30, 0.05);
  --lb-shadow-sm: 0 1px 3px rgba(15, 18, 30, 0.07), 0 1px 2px rgba(15, 18, 30, 0.04);
  --lb-shadow-md: 0 8px 24px -10px rgba(15, 18, 30, 0.18), 0 2px 6px -2px rgba(15, 18, 30, 0.06);
}

/* Vendored fonts (Task 1/4) — the woff2 files are copied into
   site/assets/fonts/ by the Dockerfile's assets stage; nothing is fetched
   from Google Fonts, keeping the docs CSP at 'self'. Paths are relative to
   this stylesheet (/assets/brand/extra.css → /assets/fonts/). */
@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/figtree-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Figtree";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/figtree-latin-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/figtree-latin-700-normal.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-700-normal.woff2") format("woff2");
}

[data-md-color-primary="custom"] {
  --md-primary-fg-color: var(--lb-color-brand-600);
  --md-primary-fg-color--dark: var(--lb-color-brand-700);
  --md-accent-fg-color: var(--lb-color-brand-600);
  --md-typeset-a-color: var(--lb-color-brand-600);
}

/* --- Base typography ---------------------------------------------------- */
body,
.md-typeset {
  font-family: var(--lb-font-sans);
  color: var(--lb-color-fg);
  font-size: 0.82rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.md-typeset h1,
.md-typeset h2,
.md-typeset h3,
.md-typeset h4 {
  color: var(--lb-color-fg-strong);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.md-typeset h1 {
  font-size: 1.9rem;
  line-height: 1.15;
  margin: 0 0 1.25rem;
}
.md-typeset h2 {
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 2.25rem 0 0.75rem;
}
.md-typeset h3 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.md-typeset a {
  color: var(--lb-color-brand-600);
  text-decoration: none;
  transition: color 120ms ease;
}
.md-typeset a:hover {
  color: var(--lb-color-brand-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.md-typeset strong {
  color: var(--lb-color-fg-strong);
  font-weight: 600;
}

/* Inline code — quiet chip, not a shout. */
.md-typeset :not(pre) > code {
  font-family: var(--lb-font-mono);
  font-size: 0.78em;
  color: var(--lb-color-fg-strong);
  background: var(--lb-color-surface-2);
  border: 1px solid var(--lb-color-border);
  border-radius: var(--lb-radius-xs);
  padding: 0.1em 0.35em;
}

/* Code blocks — light ledger paper, hairline frame. */
.md-typeset .highlight {
  border: 1px solid var(--lb-color-border);
  border-radius: var(--lb-radius-md);
  box-shadow: var(--lb-shadow-xs);
}
.md-typeset .highlight pre {
  font-family: var(--lb-font-mono);
  border-radius: var(--lb-radius-md);
}
.md-typeset .highlighttable {
  border-radius: var(--lb-radius-md);
}

/* Tables — hairline rules, header on surface-alt. */
.md-typeset table:not([class]) {
  border: 1px solid var(--lb-color-border);
  border-radius: var(--lb-radius-md);
  box-shadow: var(--lb-shadow-xs);
  font-size: 0.78rem;
}
.md-typeset table:not([class]) th {
  background: var(--lb-color-surface-alt);
  color: var(--lb-color-fg-strong);
  font-weight: 600;
}
.md-typeset table:not([class]) td {
  border-top: 1px solid var(--lb-color-border-soft);
}

/* Admonitions — squared-off hairline cards with a semantic spine. */
.md-typeset .admonition,
.md-typeset details {
  border-radius: var(--lb-radius-md);
  box-shadow: var(--lb-shadow-xs);
  border: 1px solid var(--lb-color-border);
  border-left-width: 3px;
}
.md-typeset .admonition-title,
.md-typeset summary {
  font-weight: 600;
}

/* Keyboard focus — always visible, brand ring. */
:focus-visible {
  outline: 2px solid var(--lb-color-brand-600);
  outline-offset: 2px;
  border-radius: var(--lb-radius-xs);
}

/* --- Header: brand gradient bar ----------------------------------------- */
.md-header {
  background: linear-gradient(
    105deg,
    var(--lb-color-brand-600) 0%,
    var(--lb-color-brand-700) 55%,
    var(--lb-color-brand-900) 130%
  );
}
.md-header__button.md-logo,
.md-header__button.md-logo img,
.md-header__button.md-logo svg {
  height: 1.5rem !important;
  width: auto !important;
}
.md-header__button.md-logo {
  padding: 0.25rem 0.5rem !important;
  margin-right: 0.25rem !important;
}
.md-header__title {
  font-weight: 700;
  letter-spacing: -0.01em;
}
.md-header__title > .md-header__ellipsis {
  font-weight: 400;
  opacity: 0.85;
}

/* Tabs are a SIBLING of .md-header (measured: header's own box ends above
   the tabs row), so they need the same gradient themselves — transparent
   here renders white links over the white page and the row vanishes. The
   horizontal stop list matches .md-header's so the two bars read as one. */
.md-tabs {
  background: linear-gradient(
    105deg,
    var(--lb-color-brand-600) 0%,
    var(--lb-color-brand-700) 55%,
    var(--lb-color-brand-900) 130%
  );
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.md-tabs__link {
  font-weight: 500;
  opacity: 0.82;
  transition: opacity 120ms ease;
}
.md-tabs__link:hover {
  opacity: 1;
}
/* Material 9.5 marks the active tab on the ITEM, not the link. */
.md-tabs__item--active .md-tabs__link,
.md-tabs__link--active,
.md-tabs__link[aria-current="page"] {
  font-weight: 600;
  opacity: 1;
  box-shadow: inset 0 -2px 0 rgba(255, 255, 255, 0.9);
}

/* Search field — frosted pill on the gradient. */
.md-search__input {
  background: rgba(255, 255, 255, 0.14);
  border-radius: var(--lb-radius-md);
  transition: background 120ms ease;
}
.md-search__input:hover {
  background: rgba(255, 255, 255, 0.2);
}
.md-search__input::placeholder {
  color: rgba(255, 255, 255, 0.75);
}

/* --- Sidebars ------------------------------------------------------------ */
/* Section labels ("Guides", "Brand", …) read as mono kickers — the
   platform's data voice, small and uppercase. With navigation.sections
   these are the top-level <label class="md-nav__link"> toggles, not
   .md-nav__title (that's the drawer logo row). */
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--nested > label.md-nav__link {
  font-family: var(--lb-font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lb-color-fg-subtle);
}
.md-sidebar--primary .md-nav__link {
  border-radius: var(--lb-radius-sm);
  transition: background 120ms ease, color 120ms ease;
}
.md-sidebar--primary .md-nav__link:hover {
  background: var(--lb-color-surface-alt);
}
.md-sidebar--primary .md-nav__link--active,
.md-sidebar--primary .md-nav__link[aria-current="page"] {
  color: var(--lb-color-brand-700);
  font-weight: 600;
  background: var(--lb-color-brand-50);
}

/* Table of contents — brand spine on the active entry. */
.md-sidebar--secondary .md-nav__title {
  font-family: var(--lb-font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lb-color-fg-subtle);
}
.md-sidebar--secondary .md-nav__link--active,
.md-sidebar--secondary .md-nav__link[aria-current="page"] {
  color: var(--lb-color-fg-strong);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--lb-color-brand-600);
}

/* --- Footer --------------------------------------------------------------- */
.md-footer-meta {
  background: var(--lb-color-fg-strong);
}
.md-footer-meta a {
  color: rgba(255, 255, 255, 0.85);
}

/* --- Buttons -------------------------------------------------------------- */
.md-typeset .md-button {
  background: var(--lb-color-brand-600);
  border-color: var(--lb-color-brand-600);
  border-radius: var(--lb-radius-md);
  font-weight: 600;
}
.md-typeset .md-button:hover {
  background: var(--lb-color-brand-700);
  border-color: var(--lb-color-brand-700);
}

/* --- Home page: hero + path cards ---------------------------------------- */
.lb-hero {
  padding: 2.5rem 0 2rem;
  border-bottom: 1px solid var(--lb-color-border-soft);
  margin-bottom: 2.25rem;
}
.lb-eyebrow {
  font-family: var(--lb-font-mono);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lb-color-brand-600);
  margin: 0 0 0.9rem;
}
.lb-hero h1 {
  font-size: clamp(2rem, 3.6vw, 2.7rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--lb-color-fg-strong);
  margin: 0 0 1rem;
  max-width: 24ch;
}
.lb-hero__lede {
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--lb-color-fg-muted);
  max-width: 64ch;
  margin: 0;
}

.lb-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin: 0 0 2.5rem;
}
.lb-card {
  display: flex;
  flex-direction: column;
  background: var(--lb-color-surface);
  border: 1px solid var(--lb-color-border);
  border-radius: var(--lb-radius-lg);
  box-shadow: var(--lb-shadow-xs);
  padding: 1.4rem 1.4rem 1.2rem;
  transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}
.lb-card:hover {
  border-color: var(--lb-color-brand-200);
  box-shadow: var(--lb-shadow-md);
  transform: translateY(-2px);
}
.lb-card__kicker {
  font-family: var(--lb-font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lb-color-brand-600);
  margin: 0 0 0.7rem;
}
.lb-card h3 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--lb-color-fg-strong);
  margin: 0 0 0.5rem;
}
.lb-card p {
  flex: 1;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--lb-color-fg-muted);
  margin: 0 0 1rem;
}
.lb-card__link {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--lb-color-brand-600);
  text-decoration: none;
}
.lb-card__link:hover {
  color: var(--lb-color-brand-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lb-card__link .lb-arrow {
  display: inline-block;
  transition: transform 140ms ease;
}
.lb-card:hover .lb-card__link .lb-arrow {
  transform: translateX(3px);
}

@media (max-width: 60rem) {
  .lb-cards {
    grid-template-columns: 1fr;
  }
}

/* Home page gets a wider canvas than the 61rem article column — the hero +
   card grid are landing-page material, not prose. Its ToC sidebar would be
   empty (the hero headings are HTML, not markdown), so drop it. Scoped via
   :has(.lb-hero), same no-JS trick as the Redoc page below. */
body:has(.lb-hero) .md-main__inner {
  max-width: 74rem;
}
body:has(.lb-hero) .md-sidebar--secondary {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .lb-card,
  .lb-card__link .lb-arrow {
    transition: none;
  }
  .lb-card:hover {
    transform: none;
  }
}

/* --- API reference (Redoc) needs the full viewport width — its own
   three-pane layout is unreadable inside Material's 61rem article column
   AND next to a duplicate Material sidebar. Scope via :has(redoc) so no
   JS class-toggling / no timing race — every modern browser we support
   (Chrome 105+, Safari 15.4+, Firefox 121+) has :has(). */
body:has(#redoc-container) .md-main__inner {
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
}
body:has(#redoc-container) .md-sidebar,
body:has(#redoc-container) .md-sidebar--primary,
body:has(#redoc-container) .md-sidebar--secondary {
  display: none !important;
}
body:has(#redoc-container) .md-content {
  max-width: none !important;
  margin: 0 !important;
}
body:has(#redoc-container) .md-content__inner {
  padding: 0 !important;
  margin: 0 !important;
  max-width: none !important;
}
body:has(#redoc-container) .md-content__inner::before,
body:has(#redoc-container) .md-content__inner::after {
  display: none !important;
}
body:has(#redoc-container) .md-main {
  padding: 0 !important;
}
body:has(#redoc-container) #redoc-container {
  display: block;
  min-height: calc(100vh - 6.5rem);
}
/* Redoc's own left nav has its own scroll; hide MkDocs' top gutter that
   would otherwise push Redoc down by an extra hairline. */
body:has(#redoc-container) .md-content__button {
  display: none !important;
}
/* Redoc owns the viewport on the reference page — the docs footer would
   sit as an orphaned strip under a full-height app surface. */
body:has(#redoc-container) .md-footer {
  display: none !important;
}
/* Cap REMOVED (Stripe-style full-bleed): the three panes span the whole
   viewport. The sidebar is sticky INSIDE .redoc-wrap and the sample cells
   are in-flow, so re-adding a max-width here would center the whole unit
   (sidebar + docs + sample column) as one app. */
body:has(#redoc-container) .redoc-wrap {
  max-width: none;
  margin: 0;
}
/* Redoc's JSON sample viewer ships dark-rail token colours (keys render
   white-on-white on our light rail). Re-key the prism palette to LuciBook
   tokens — scoped to .api-content's <code> (the .redoc-json viewer is
   code>ul, NOT wrapped in <pre>; prose code chips contain no .token spans,
   so they're untouched either way). */
body:has(#redoc-container) .api-content code .token.string {
  color: var(--lb-color-success-600) !important;
}
body:has(#redoc-container) .api-content code .token.property {
  color: var(--lb-color-fg-strong) !important;
}
body:has(#redoc-container) .api-content code .token.number {
  color: var(--lb-color-info-600) !important;
}
body:has(#redoc-container) .api-content code .token.boolean,
body:has(#redoc-container) .api-content code .token.null,
body:has(#redoc-container) .api-content code .token.keyword {
  color: var(--lb-color-warning-600) !important;
}
body:has(#redoc-container) .api-content code .token.operator {
  color: var(--lb-color-fg-muted) !important;
}

/* Hide Redoc's info block ("LuciBook API (1)" + download + description):
   it is the only section whose dark sample cell stays permanently empty,
   which read as a broken void above the fold, and its "(1)" title is the
   raw info.version. The spec download it hosted is linked from
   reference/postman.md instead. It's always .api-content's first child and
   the only one containing an h1; the :has(h1) guard makes the rule a no-op
   if a Redoc upgrade ever reorders the tree. (`hideInfoSection` exists in
   the bundle's option schema but is never read by its render path —
   measured, hence CSS.) */
body:has(#redoc-container) .api-content > div:first-child:has(h1) {
  display: none;
}

/* Sidebar group collapse — this Redoc CE renders the chevron but wires no
   toggle (measured in the bundle: the mobx store has toggle(), no caller).
   redoc-init.js's delegation toggles .lb-collapsed on the menuitem root;
   the store's `expanded` stays true so React never unmounts the children
   and the CSS rule below is the only thing hiding them. */
#redoc-container label.-depth1 > svg {
  cursor: pointer;
  transition: transform 140ms ease;
}
#redoc-container li.lb-collapsed > ul {
  display: none;
}
#redoc-container li.lb-collapsed > label.-depth1 > svg {
  transform: rotate(-90deg);
}

/* Inline request card (Stripe-style, above the Responses docs) — injected
   statically by redoc-init.js after Redoc.init resolves. Dark ink card on
   LuciBook tokens; the matching RESPONSE card carries a fully-expanded
   clone of the rail's response JSON. */
.lb-reqcard,
.lb-respcard {
  background: var(--lb-color-fg-strong);
  border-radius: var(--lb-radius-lg);
  box-shadow: var(--lb-shadow-md);
  overflow: hidden;
}
.lb-reqcard {
  margin: 1.5rem 0 0.75rem;
}
.lb-respcard {
  margin: 0 0 1.75rem;
}
.lb-reqcard__bar,
.lb-respcard__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.lb-reqcard__lang {
  background: rgba(255, 255, 255, 0.08);
  color: #eaedf2; /* surface-2 */
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--lb-radius-sm);
  font-family: var(--lb-font-sans);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.3rem 0.45rem;
  cursor: pointer;
}
.lb-reqcard__lang option {
  color: var(--lb-color-fg-strong); /* option list renders on white */
}
.lb-reqcard__copy {
  background: transparent;
  color: var(--lb-color-brand-200);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--lb-radius-sm);
  font-family: var(--lb-font-sans);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.3rem 0.7rem;
  cursor: pointer;
  transition: background 120ms ease;
}
.lb-reqcard__copy:hover {
  background: rgba(255, 255, 255, 0.08);
}
.lb-reqcard__code {
  margin: 0;
  padding: 0.85rem 1rem;
  overflow-x: auto;
  background: transparent;
  border: 0;
}
.lb-reqcard__code code {
  font-family: var(--lb-font-mono);
  font-size: 12.5px;
  line-height: 1.65;
  color: #eaedf2; /* surface-2 */
  background: transparent;
  border: 0;
  padding: 0;
  white-space: pre;
}
.lb-respcard__title {
  font-family: var(--lb-font-mono);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--lb-color-fg-subtle);
}
.lb-respcard__meta {
  font-family: var(--lb-font-mono);
  font-size: 0.7rem;
  color: var(--lb-color-fg-subtle);
}
.lb-respcard__body {
  padding: 0.75rem 1rem;
  overflow-x: auto;
}
/* The cloned .redoc-json keeps Redoc's markup; re-key it for the dark card.
   These need the body:has() prefix — the light-rail token overrides carry
   an id inside :has() and would otherwise outrank these. */
body:has(#redoc-container) .lb-respcard .redoc-json,
body:has(#redoc-container) .lb-respcard .redoc-json code {
  background: transparent !important;
  border: 0 !important;
  color: #eaedf2 !important;
  font-family: var(--lb-font-mono) !important;
  font-size: 12.5px !important;
  padding: 0;
}
body:has(#redoc-container) .lb-respcard .redoc-json * {
  cursor: default !important; /* clone is static — collapse buttons are dead */
}
body:has(#redoc-container) .lb-respcard .redoc-json ul {
  list-style: none; /* disc markers are dead affordances in the clone */
  padding-left: 1.1rem;
}
body:has(#redoc-container) .lb-respcard .redoc-json code .token.property {
  color: #eaedf2 !important;
}
body:has(#redoc-container) .lb-respcard .redoc-json code .token.string {
  color: var(--lb-color-brand-200) !important;
}
body:has(#redoc-container) .lb-respcard .redoc-json code .token.number {
  color: var(--lb-color-brand-500) !important;
}
body:has(#redoc-container) .lb-respcard .redoc-json code .token.boolean,
body:has(#redoc-container) .lb-respcard .redoc-json code .token.null,
body:has(#redoc-container) .lb-respcard .redoc-json code .token.keyword {
  color: var(--lb-color-warning-600) !important;
}
body:has(#redoc-container) .lb-respcard .redoc-json code .token.operator {
  color: var(--lb-color-fg-subtle) !important;
}
