@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700&display=swap');

html {
    scroll-behavior: smooth;
    scroll-padding-top: 90px;
}

body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Improved text readability */
p {
    line-height: 1.6;
    margin-bottom: 1rem;
}

/* Better heading spacing */
h1, h2, h3, h4, h5, h6 {
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    line-height: 1.3;
}

h1:first-child,
h2:first-child,
h3:first-child {
    margin-top: 0;
}

/* Link styling */
a {
    transition: all 0.2s ease;
}

/* Better list spacing */
ul, ol {
    margin-bottom: 1rem;
    padding-left: 1.5rem;
}

li {
    margin-bottom: 0.5rem;
}

/* Blockquote styling */
blockquote {
    border-left: 4px solid var(--mantine-color-teal-5);
    padding-left: 1rem;
    margin-left: 0;
    margin-right: 0;
    font-style: italic;
    color: var(--mantine-color-dimmed);
}

input:invalid {
    outline: none !important;
}

#wrapper {
    padding: 10px;
    margin-left: 320px;
    margin-right: 320px;
}

:root[data-mantine-color-scheme="dark"] #dark-theme-icon {
    display: none;
}

:root[data-mantine-color-scheme="light"] #light-theme-icon {
    display: none;
}

.demo-container {
    display: flex;
    max-width: 100%;
    overflow: hidden;
}

.demo-preview {
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;
    justify-content: center;
}

.demo-controls {
    width: 250px;
    padding: 20px;
    gap: 10px;
}

.demo-control {
    margin: 10px;
}

@media only screen and (max-width: 750px) {
    .demo-container {
        flex-direction: column;
    }

    .demo-controls {
        width: 100%;
    }
}

.dmc-bar {
    background-image: linear-gradient(to right, yellow, orange);
}

.dmc-thumb {
    border-color: orange;
    height: 20px;
    width: 20px;
    background-color: white;
}

.mantine-Table-th {
    font-size: 15px;
    font-weight: 500;
}

.dmc-indicator {
  width: 12px;
  height: 4px;
  transition: width 250ms ease;

  &[data-active] {
    width: 40px;
  }
}

.dmc-control {
  &[data-inactive] {
    opacity: 0;
    cursor: default;
  }
}

.dmc-controls {
  transition: opacity 150ms ease;
  opacity: 0;
}

.dmc-root {
  &:hover {
    .dmc-controls {
      opacity: 1;
    }
  }
}



.dmc-slider-track {
  &::before {
    background-color: light-dark(var(--mantine-color-blue-1), var(--mantine-color-dark-3));
  }
}

.dmc-slider-mark {
  width: 6px;
  height: 6px;
  border-radius: 6px;
  transform: translateX(-3px) translateY(-2px);
  border-color: light-dark(var(--mantine-color-blue-1), var(--mantine-color-dark-3));

  &[data-filled] {
    border-color: var(--mantine-color-blue-6);
  }
}

.dmc-slider-markLabel {
  font-size: var(--mantine-font-size-sm);
  color: var(--mantine-color-green-5);
  margin-bottom: 5px;
  margin-top: 0;
}

.dmc-slider-thumb {
  height: 16px;
  width: 16px;
  background-color: var(--mantine-color-green-5);
  border-width: 1px;
  box-shadow: var(--mantine-shadow-lg);
}

.navbar-link {
    padding: 0.5rem 1rem;
    border-radius: 0.25rem;
    transition: background 0.1s;
    color: inherit;
    display: inline-flex;
    gap: 0.5rem;

    &:hover {
        text-decoration: none;
        background: color-mix(in srgb, var(--mantine-color-gray-5), transparent 90%);
    }
}

/* Mobile drawer nav: full-width rows with a 44px touch target, per the
   iOS/Android minimum. The desktop navbar keeps the compact inline-flex look. */
.mobile-nav .navbar-link {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 44px;
    padding: 0.625rem 0.75rem;
    border-radius: 0.375rem;
    -webkit-tap-highlight-color: transparent;
}

.mobile-nav .navbar-link:active {
    background: color-mix(in srgb, var(--mantine-color-gray-5), transparent 80%);
}

/* Markdown tables scroll in their own box instead of dragging the page
   sideways on phones. A <table> is min-content sized: with overflow
   visible it refuses to shrink below its widest row and pushes the whole
   document wide, so every paragraph on the page can be swiped off-screen
   (a fork measured 105px of horizontal drag at 414px from one prop
   table). This is GitHub's markdown recipe: content-width, capped at the
   container, scrollable past it — a no-op for tables that already fit.
   Element+class selector so it outranks Mantine's own width rule
   regardless of stylesheet load order.

   TWO selectors, and the second is this site's own finding. markdown2dash
   derives each class from the renderer that emitted it
   (`create_class_name`, src/utils.py: "m2d-" + the method name), so a
   markdown table is `m2d-table` but the `.. kwargs::` directive's output
   is `m2d-block-kwargs`. The template's single-selector version is
   therefore a NO-OP on exactly this site's widest content: /api is 13
   generated prop tables, all of them m2d-block-kwargs, and not one of
   them is an m2d-table. Measured against the real layout tree, not
   assumed. The same gap exists upstream — the kwargs directive is the
   boilerplate's — so this belongs back in the template. */
table.m2d-table,
table.m2d-block-kwargs {
    display: block;
    width: max-content;
    max-width: 100%;
    overflow-x: auto;
}

/* NEVER style Mantine's hashed m_* classes — they are private internals,
   version-coupled by construction. A rule that stops matching after a
   dependency bump fails silently; one that starts matching applies
   geometry to the wrong component. Three fossils from the dmc-docs fork
   era lived here until 2026-08-22, each audited against the INSTALLED
   DMC 2.8 bundle before deletion:

     m_46b77525  Input.Wrapper's root (still live in 2.8, where Mantine
                 gives it only `line-height`). The rule here added an
                 !important top margin to EVERY input wrapper in every
                 docs example — including both props playgrounds.
     m_5caae85b  ZERO occurrences in the 2.8 bundle. Dead: it matched
                 nothing, and had not for at least two minor versions.
     m_9cdde9a   AppShell's `aside` (confirmed via the bundle's own class
                 map, aside:"m_9cdde9a"). Four of its five declarations
                 were a verbatim restatement of Mantine's own rule for
                 that class — inset-inline-end, width, transform,
                 z-index — around ONE intentful pixel, the TOC's
                 breathing gap, rescued onto the static selector below.

   Hashes are named here WITHOUT the leading dot on purpose: the guard
   test strips comments before matching, but `grep '\.m_'` over assets/
   should find live selectors only, never this tombstone.
   tests/test_css_hygiene.py fails on any hashed selector; style the
   static mantine-<Component>-<part> classes, like the rule below, or use
   the DMC Styles API. */

/* Rank the AppShell sections: the aside under the header, always.
   The Clerk avatar dropdown renders INSIDE the header, so no z-index on the
   menu itself (it ships with 10000 inline) can lift it above anything that
   outranks the header's own stacking context — and Mantine gives the aside
   calc(shell + 1), later in the DOM, so the open menu painted underneath
   the Table of Contents.

   Overriding --app-shell-aside-z-index on the shell root does NOT work:
   Mantine stamps that variable INLINE on the <aside> element itself, and an
   element's own inline declaration beats anything inherited. The inline
   style only carries the variable though — the z-index PROPERTY comes from
   the stylesheet — so overriding the property on the section wins. Static
   selector per the DMC Styles API guidance (never the hashed m_* classes).
   10 keeps the aside above page content and below every piece of chrome. */
aside.mantine-AppShell-aside {
    z-index: 10 !important;
    /* Rescued from the retired m_9cdde9a fossil: the one intentful pixel
       in that copied block was this breathing gap between the header line
       and the top of the Table of Contents. The other four declarations
       it carried were Mantine's own, restated. */
    margin-top: 15px;
}

:root[data-mantine-color-scheme="dark"] {
    --mantine-color-anchor: #74c0fc !important;
    --mantine-color-dark-light: rgba(63, 63, 70, 0.15);
    --mantine-color-dark-light-hover: rgba(63, 63, 70, 0.2);
    --mantine-color-dark-outline-hover: rgba(113, 113, 122, 0.05);
}

img[alt=logo] { width: 100%; }

/* Theme-aware code blocks */
:root[data-mantine-color-scheme="light"] pre,
:root[data-mantine-color-scheme="light"] code {
    background-color: #f8f9fa;
    color: #1a1b1e;
}

:root[data-mantine-color-scheme="dark"] pre,
:root[data-mantine-color-scheme="dark"] code {
    background-color: #1a1b1e;
    color: #c1c2c5;
}

/* Inline code */
:root[data-mantine-color-scheme="light"] code {
    background-color: #f1f3f5;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 0.9em;
}

:root[data-mantine-color-scheme="dark"] code {
    background-color: #25262b;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 0.9em;
}

/* Code blocks */
:root[data-mantine-color-scheme="light"] pre {
    background-color: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 16px;
    overflow-x: auto;
}

:root[data-mantine-color-scheme="dark"] pre {
    background-color: #1a1b1e;
    border: 1px solid #373a40;
    border-radius: 8px;
    padding: 16px;
    overflow-x: auto;
}

/* Code inside pre blocks */
:root[data-mantine-color-scheme="light"] pre code {
    background-color: transparent;
    padding: 0;
    color: #1a1b1e;
}

:root[data-mantine-color-scheme="dark"] pre code {
    background-color: transparent;
    padding: 0;
    color: #c1c2c5;
}

/* Sun icon rotation animations - direction based on scroll */
@keyframes rotate-sun-clockwise {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

@keyframes rotate-sun-counter-clockwise {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(-360deg);
    }
}

/* Clockwise rotation (scroll down) */
#light-theme-icon.rotating-down,
#light-theme-icon.rotating-down svg,
#light-theme-icon.rotating-down iconify-icon {
    animation: rotate-sun-clockwise 1.2s ease-out infinite;
    display: inline-block;
}

/* Counter-clockwise rotation (scroll up) */
#light-theme-icon.rotating-up,
#light-theme-icon.rotating-up svg,
#light-theme-icon.rotating-up iconify-icon {
    animation: rotate-sun-counter-clockwise 1.2s ease-out infinite;
    display: inline-block;
}

/* Smooth transition when stopping */
#light-theme-icon,
#light-theme-icon svg,
#light-theme-icon iconify-icon {
    transition: transform 0.3s ease-out;
    display: inline-block;
}

/* Typewriter cursor animation for Dash Docs title */
@keyframes blink-cursor {
    0%, 49% {
        opacity: 1;
    }
    50%, 100% {
        opacity: 0;
    }
}

/* Add blinking cursor while typing */
#dash-docs-title.typing::after {
    content: '▋';
    animation: blink-cursor 1s step-end infinite;
    margin-left: 2px;
    color: #03c7e5;
}

/* AG Grid Dark Mode Support */
/* Override AG Grid theme colors for dark mode */
:root[data-mantine-color-scheme="dark"] .ag-theme-alpine {
    /* Core background colors */
    --ag-background-color: #1a1b1e;
    --ag-foreground-color: #c1c2c5;
    --ag-border-color: #373a40;
    --ag-secondary-border-color: #2c2e33;

    /* Header colors */
    --ag-header-background-color: #25262b;
    --ag-header-foreground-color: #c1c2c5;

    /* Row colors */
    --ag-odd-row-background-color: #1a1b1e;
    --ag-row-hover-color: #25262b;
    --ag-selected-row-background-color: #373a40;

    /* Control panel (filters, pagination) */
    --ag-control-panel-background-color: #25262b;

    /* Input colors */
    --ag-input-border-color: #373a40;
    --ag-input-disabled-border-color: #2c2e33;
    --ag-input-disabled-background-color: #25262b;

    /* Pagination and widgets */
    --ag-disabled-foreground-color: #5c5f66;
    --ag-chip-background-color: #373a40;

    /* Hover and focus states */
    --ag-row-border-color: #2c2e33;
    --ag-cell-horizontal-border: solid #2c2e33;

    /* Filter colors */
    --ag-input-focus-border-color: #5c5f66;

    /* Icons */
    color-scheme: dark;
}

/* Light mode adjustments (ensure proper contrast) */
:root[data-mantine-color-scheme="light"] .ag-theme-alpine {
    --ag-background-color: #ffffff;
    --ag-foreground-color: #1a1b1e;
    --ag-border-color: #dee2e6;
    --ag-header-background-color: #f8f9fa;
    --ag-row-hover-color: #f1f3f5;
}

/* Custom AG Grid Cell Styling - Light Mode */
:root[data-mantine-color-scheme="light"] .ag-theme-alpine .timestamp-cell {
    font-family: monospace;
    font-size: 14px;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .bot-type-cell {
    font-weight: 500;
    padding: 4px 8px;
    border-radius: 4px;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .bot-training {
    background-color: #ffe0e0;
    color: #c92a2a;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .bot-search {
    background-color: #d0ebff;
    color: #1971c2;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .bot-traditional {
    background-color: #d3f9d8;
    color: #2f9e44;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .bot-unknown {
    background-color: #f1f3f5;
    color: #868e96;
    font-weight: 400;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .page-cell {
    font-family: monospace;
    font-size: 12px;
    background-color: #f8f9fa;
    padding: 4px 6px;
    border-radius: 4px;
}

:root[data-mantine-color-scheme="light"] .ag-theme-alpine .user-agent-cell {
    font-size: 12px;
    color: #868e96;
}

/* Custom AG Grid Cell Styling - Dark Mode */
:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .timestamp-cell {
    font-family: monospace;
    font-size: 14px;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .bot-type-cell {
    font-weight: 500;
    padding: 4px 8px;
    border-radius: 4px;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .bot-training {
    background-color: #5c1414;
    color: #ffa8a8;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .bot-search {
    background-color: #1c3d5a;
    color: #74c0fc;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .bot-traditional {
    background-color: #1b4332;
    color: #8ce99a;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .bot-unknown {
    background-color: #373a40;
    color: #909296;
    font-weight: 400;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .page-cell {
    font-family: monospace;
    font-size: 12px;
    background-color: #25262b;
    padding: 4px 6px;
    border-radius: 4px;
}

:root[data-mantine-color-scheme="dark"] .ag-theme-alpine .user-agent-cell {
    font-size: 12px;
    color: #909296;
}


/* ------------------------------------------------------------------
   Mobile fit (sync item 16, the visual pass). Ported from the template
   at 1.6.39. A code block inside a List item, a Blockquote or a
   Timeline body cannot shrink below its intrinsic width and drags the
   whole document wide; the fix is one stylesheet rule for every
   container a code block can sit in, never a per-page override.
   Public Mantine class names only — never the hashed .m_* internals
   (tests/test_css_hygiene.py fails on those).
   ------------------------------------------------------------------ */
/* Code blocks scroll inside their own box, wherever they sit (1.6.39;
   owner-observed on /backend-comparison at phone width). CodeHighlight's
   <pre> already scrolls, but a flex parent with the default min-width:auto
   — Mantine's List item wrapper, a Blockquote, a Stack — refuses to shrink
   below the code's intrinsic width and drags the whole document wide
   (measured: a 959px document in a 200px viewport, widest element the
   List itemWrapper around the "Replace @server.before_request" block).
   Public Mantine class names only — never the hashed .m_* internals. */
.mantine-List-itemWrapper,
.mantine-List-itemLabel,
.mantine-List-item,
.mantine-Blockquote-root,
.mantine-Timeline-itemBody,
.mantine-CodeHighlight-root,
.mantine-CodeHighlightTabs-root {
    min-width: 0;
    max-width: 100%;
}
/* The wrapper is inline-flex and the label a block child: without
   min-width:0 on the LABEL too, it grows to the code's width (measured
   887px inside a 287px wrapper on /backend-comparison at 391px). */
.mantine-List-itemWrapper {
    width: 100%;
}
.mantine-List-itemLabel {
    flex: 1 1 auto;
}
/* Timeline bullets (/changelog): a Text in a no-wrap Group grows to its
   longest unbreakable token — a 60-character test name in a code span —
   and leaves its card (a 549px document at 391px). Same rule as the
   component sets inline; here so the stylesheet alone holds the line. */
.mantine-Timeline-root .mantine-Text-root,
.mantine-Timeline-root .mantine-Code-root {
    min-width: 0;
    overflow-wrap: anywhere;
}
/* Inline code in prose: a long unbreakable token (`app.server.before_request`
   chains, dotted module paths) is the last thing that can push a page past
   the viewport once blocks and tables scroll in their own boxes — measured:
   a 353px codespan, a 425px document at 391px on /backend-comparison.
   Block code (CodeHighlight) keeps pre formatting; this is inline only. */
code.m2d-codespan,
.mantine-Code-root:not(.mantine-CodeHighlight-code) {
    overflow-wrap: anywhere;
    white-space: normal;
}
.mantine-CodeHighlight-root pre,
.mantine-CodeHighlightTabs-root pre,
.mantine-AppShell-main pre {
    overflow-x: auto;
    max-width: 100%;
}


/* Skip link (sync item 18, adopted from muischeduler): the first tab stop,
   off-screen until keyboard focus, then pinned top-left above the header.
   This site's sidebar carries ~45 tab stops before the prose begins, which
   is the whole reason the link exists. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 9999;
    background: var(--mantine-primary-color-filled);
    color: var(--mantine-color-white);
    padding: 8px 14px;
    border-radius: 0 0 8px 0;
    font-weight: 600;
    text-decoration: none;
}
.skip-link:focus {
    left: 0;
}
