/* ===== Custom overrides ===== */

/* --- 1. Code blocks: visible border in both light & dark, hover copy icon --- */
div.highlight {
  position: relative;
  border: 1px solid var(--sy-c-border);
  border-radius: 8px;
  overflow: hidden;
}
div.highlight pre {
  border-radius: 8px;
}
/* copy button is injected by custom.js; style it to appear on hover */
div.highlight .custom-copybtn {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 6px;
  border: 1px solid var(--sy-c-border);
  background: var(--sy-c-background);
  color: var(--sy-c-text);
  opacity: 0;
  cursor: pointer;
  transition: opacity 0.15s ease;
}
div.highlight:hover .custom-copybtn,
div.highlight .custom-copybtn:focus-visible {
  opacity: 1;
}
div.highlight .custom-copybtn:hover {
  background: var(--sy-c-hover, rgba(127,127,127,.15));
}
div.highlight .custom-copybtn svg {
  width: 1rem;
  height: 1rem;
}

/* --- 2. Search box trigger icon (top nav) --- */
.searchbox { position: relative; }
/* shibuya.css's ".searchbox kbd, .searchbox button" rule styles this button
   like a keyboard key (border + background box) — that's the square the
   user is seeing around the icon. Override it explicitly with a selector
   specific enough to win, and drop the box entirely. */
form.searchbox button.search-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  margin: 0 !important;
  cursor: pointer;
  color: var(--sy-c-text) !important;
  padding: 0.25rem;
  opacity: 1 !important;
}
form.searchbox button.search-icon-btn:hover { color: var(--sy-c-link, #3b82f6) !important; }
form.searchbox button.search-icon-btn i { width: 1.1rem; height: 1.1rem; display: block; }

/* The search page (search.html) wraps its button in form.searchform instead,
   which shibuya.css also boxes via "form input[name=q] + button". Same fix. */
form.searchform button.search-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  margin: 0 !important;
  cursor: pointer;
  color: var(--sy-c-text) !important;
  padding: 0.25rem;
  opacity: 1 !important;
  position: static !important;
}
form.searchform button.search-icon-btn:hover { color: var(--sy-c-link, #3b82f6) !important; }
form.searchform button.search-icon-btn i { width: 1.1rem; height: 1.1rem; display: block; }

/* The theme's icon font (.i-lucide) never defined a "search" glyph, so
   .i-lucide.search rendered as a plain filled square (an empty CSS mask).
   Register the missing lucide "search" icon and wire it up. */
:root {
  --lucide-search-url: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
}
.i-lucide.search { --icon-url: var(--lucide-search-url); }

/* --- 3. Back-to-top: bottom-right, bigger, icon-only, visible in all modes --- */
.back-to-top {
  left: auto !important;
  right: 1.5rem !important;
  bottom: 1.5rem !important;
  transform: none !important;
  width: 3.25rem;
  height: 3.25rem;
  padding: 0 !important;
  border-radius: 50% !important;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--sy-c-accent, #3b82f6) !important;
  color: #fff !important;
  border: 1px solid var(--sy-c-border);
  box-shadow: 0 4px 12px rgba(0,0,0,.25) !important;
}
.back-to-top[data-visible="true"] { display: flex !important; }
.back-to-top span { display: none; } /* hide "Back to top" text */
.back-to-top svg,
.back-to-top i {
  width: 1.4rem;
  height: 1.4rem;
}
.back-to-top:hover {
  background: var(--sy-c-accent-hover, #2563eb) !important;
}

/* --- 4. Bigger, more tappable prev/next buttons --- */
.navigation { gap: 1rem; }
.navigation a {
  padding: 0.9rem 1.25rem;
  border: 1px solid var(--sy-c-border);
  border-radius: 10px;
  width: 100%;
  min-height: 3rem;
  transition: background 0.15s, border-color 0.15s;
}
.navigation a:hover {
  background: var(--sy-c-hover, rgba(127,127,127,.08));
  border-color: var(--sy-c-accent, #3b82f6);
}
.navigation .page-info > span { font-size: 0.75rem; }
.navigation-next a, .navigation-prev a { font-size: 1rem; font-weight: 600; }

/* Ghost variant: borderless/transparent until hovered, matches .yue table.ghost.
   Stays fully transparent by default in both themes; the hover fill is a
   touch darker in light mode, since rgba(127,127,127,.08) reads as barely
   there against a white background. */
.navigation-next a.ghost, .navigation-prev a.ghost {
  background: transparent;
  border-color: transparent;
}
.navigation-next a.ghost:hover, .navigation-prev a.ghost:hover {
  background: var(--sy-c-hover, rgba(127,127,127,.08));
  border-color: transparent;
}
html.light .navigation-next a.ghost:hover,
html.light .navigation-prev a.ghost:hover {
  background: rgba(0, 0, 0, 0.07);
}

/* --- 5. Search results page: clickable-looking cards --- */
#search-results ul.search > li {
  position: relative;
  border: 1px solid var(--sy-c-border);
  border-radius: 10px;
  padding: 0.9rem 2.5rem 0.9rem 1.1rem;
  margin-bottom: 0.75rem;
  transition: background 0.15s, border-color 0.15s;
}
#search-results ul.search > li:hover {
  background: var(--sy-c-hover, rgba(127,127,127,.08));
  border-color: var(--sy-c-accent, #3b82f6);
}
#search-results ul.search > li a {
  font-weight: 600;
  font-size: 1.05rem;
  text-decoration: none;
  display: block;
  margin-bottom: 0.25rem;
  color: var(--sy-c-text);
}
#search-results ul.search > li a:hover { text-decoration: underline; }
#search-results ul.search > li span {
  color: var(--sy-c-light);
  font-size: 0.9rem;
  line-height: 1.5;
}
/* Right chevron that appears on hover of each result card */
#search-results ul.search > li::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 1rem;
  width: 1rem;
  height: 1rem;
  transform: translateY(-50%) translateX(-4px);
  background-color: var(--sy-c-light);
  -webkit-mask: var(--lucide-chevron-right-url) no-repeat;
  mask: var(--lucide-chevron-right-url) no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
#search-results ul.search > li:hover::after {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  background-color: var(--sy-c-accent, #3b82f6);
}
.searchform {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.searchform input[type="text"] {
  flex: 1;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--sy-c-border);
  border-radius: 8px;
}
.searchform .search-icon-btn {
  background: var(--sy-c-accent, #3b82f6);
  color: #fff;
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
}
.searchform .search-icon-btn:hover { background: var(--sy-c-accent-hover, #2563eb); }

/* --- 5a. Vertical separator between the left sidebar and the main content. --- */
#lside {
  border-right: 1px solid var(--sy-c-divider);
}
@media (min-width: 768px) {
  #lside {
    width: var(--lside-width, 18rem);
    max-width: 30rem;
    opacity: 1;
    transition: width 0.28s cubic-bezier(0.4, 0, 0.2, 1),
      opacity 0.2s ease, padding 0.28s ease, border-color 0.2s ease;
  }
  /* Dragging the resize handle should snap instantly, not glide - only
     animate width/opacity changes that come from the toggle button. */
  body.is-resizing-lside #lside {
    transition: none;
  }
}

/* --- 5a-2. Draggable resize handle for the left sidebar (desktop only).
   Sits on the border between #lside and the main content; dragging it
   updates the --lside-width custom property (see custom.js). Dragging
   past the minimum snaps the sidebar closed instead of shrinking further,
   matching the behavior of the explicit collapse button below. --- */
.js-lside-resize {
  display: none;
  flex-shrink: 0;
  position: relative;
  width: 10px;
  margin-left: -5px;
  margin-right: -5px;
  cursor: col-resize;
  z-index: 20;
  touch-action: none;
}
.js-lside-resize::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  background: transparent;
  transition: background-color 0.12s ease;
}
.js-lside-resize:hover::after,
.js-lside-resize.is-dragging::after {
  background: var(--sy-c-accent, #3b82f6);
}
@media (min-width: 768px) {
  .js-lside-resize {
    display: block;
  }
  html.sidebar-collapsed .js-lside-resize {
    display: none;
  }
}
body.is-resizing-lside {
  cursor: col-resize !important;
  user-select: none;
}
body.is-resizing-lside * {
  user-select: none;
}

/* --- 5b. Collapsible left sidebar (desktop). The toggle button lives in
   the breadcrumb bar (injected by custom.js) next to the existing mobile
   menu button, and only shows at md+ since the mobile hamburger already
   collapses the sidebar off-canvas below that. Collapsed state is stored
   in localStorage and applied via a class on <html> before first paint. --- */
.js-lside-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  min-width: 2rem;
  min-height: 2rem;
  padding: 0;
  border: 1px solid var(--sy-c-border, currentColor);
  border-radius: 6px;
  background-color: var(--sy-c-surface, transparent);
  color: var(--sy-c-text, currentColor);
  opacity: 1;
  visibility: visible;
  flex-shrink: 0;
}
.js-lside-toggle:hover {
  background-color: var(--sy-c-surface, rgba(127, 127, 127, 0.12));
}
.js-lside-toggle-icon,
.js-lside-toggle i {
  display: block;
  width: 16px;
  height: 16px;
  color: inherit;
}
.js-lside-toggle i,
.js-lside-toggle-icon {
  transition: transform 0.2s ease;
}
html.sidebar-collapsed .js-lside-toggle i,
html.sidebar-collapsed .js-lside-toggle-icon {
  transform: rotate(180deg);
}
@media (min-width: 768px) {
  .js-lside-toggle {
    display: inline-flex;
  }
  html.sidebar-collapsed #lside {
    width: 0;
    min-width: 0;
    max-width: 0;
    opacity: 0;
    padding: 0;
    border-color: transparent;
    pointer-events: none;
    overflow: hidden;
  }
  .sy-main {
    transition: width 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  }
  html.sidebar-collapsed .sy-main {
    width: 100%;
  }
}
@media (min-width: 1280px) {
  html.sidebar-collapsed .sy-main {
    width: calc(100% - 16rem);
    max-width: none;
  }
}
/* No first-paint flash: the inline <head> script adds
   .sidebar-collapsed before render, so nothing here needs to animate on
   initial load - only on the toggle click itself (custom.js adds this
   class after the click so the very first frame isn't animated either). */
html:not(.js-lside-ready) #lside,
html:not(.js-lside-ready) .sy-main {
  transition: none !important;
}

/* --- 6. Trim excess space above the content (breadcrumb bar + top padding) --- */
.sy-breadcrumbs {
  padding-top: 0.4rem;
  padding-bottom: 0;
  min-height: auto;
}
/* --- 6a. The theme hides the entire breadcrumb bar (and with it, the
   sidebar collapse/resize toggle button that lives inside it) at
   min-width:1280px, assuming wide screens don't need it. Since our
   toggle button lives there, force the bar to stay visible at every
   width so the button is always reachable, not just when the viewport
   happens to be narrowed (e.g. with DevTools open). --- */
@media (min-width: 1280px) {
  .sy-breadcrumbs {
    display: block;
  }
}
/* --- 6b. Breadcrumb styling: small blue book icon + small blue text
   (link, current-page label, and the "/" separator all match), sitting
   right above the header. The gap is closed from the breadcrumb bar's
   own spacing (its bottom padding/margin), not by shrinking the
   header's own top padding, so the header itself doesn't move. --- */
.sy-breadcrumbs-inner {
  border-bottom: none;
  padding-top: 0.3rem;
  padding-bottom: 0;
  margin-bottom: -0.6rem;
}
.breadcrumb-icon {
  color: var(--sy-c-link);
  flex-shrink: 0;
  margin-right: 0.4rem;
}
.sy-breadcrumbs ol {
  font-size: 0.78rem;
}
.sy-breadcrumbs ol a,
.sy-breadcrumbs ol strong,
.sy-breadcrumbs ol span,
.sy-breadcrumbs ol a + span {
  color: var(--sy-c-link);
}
.sy-breadcrumbs ol a:hover {
  color: var(--sy-c-link-hover);
}

/* --- 6c. The "Copy page" button is absolutely positioned over the
   header at lg+ widths (top-8 = 2rem), which assumed the header sat
   2rem below its positioning context. Now that the breadcrumb/header
   gap is closed from the breadcrumb side rather than by shrinking the
   header's own padding, the header still starts at its normal offset,
   so the button's top offset is left as-is; this rule only trims it
   down slightly so it lines up with the header's cap-height instead of
   floating above it. --- */
@media (min-width: 64rem) {
  .copy-page-wrapper.lg\:absolute {
    top: 2.1rem;
  }
}


/* --- 7. Small spacing between top-level sidebar entries ---
   Note: on the *current* page, Sphinx nests the active branch inside an
   extra <ul class="current"> (so every toctree-l1 item ends up a
   grandchild of .globaltoc's outer <ul>, one level deeper than on other
   pages, where they're a direct child). A "> ul > li" child-combinator
   selector only ever matches the direct-child (non-current) case, which
   is why the gap under "Start here" only ever showed up on the current
   page. Use a descendant selector so it matches at either nesting depth,
   and always apply the top margin (no ":first-child" exception) so the
   gap is identical on every page. */
.globaltoc > ul li.toctree-l1 {
  margin-top: 0.35rem;
}

/* --- 7c. Make each sidebar link clickable across its full row, not just
   the text itself. Sphinx renders these as plain inline <a> tags, so the
   hit target was only as wide as the glyphs; block-level + full-width
   anchors give a much bigger, easier-to-click area (and a hover highlight
   confirms the whole row is live). --- */
.globaltoc li {
  position: relative;
}
.globaltoc li > a {
  display: block;
  width: 100%;
  padding: 0.15rem 0.4rem;
  margin: -0.15rem -0.4rem;
  border-radius: 6px;
  transition: background-color 0.12s ease;
}
.globaltoc li > a:hover {
  background: var(--sy-c-hover, rgba(127, 127, 127, 0.08));
}

/* --- 7b. Hide the expand/collapse chevron and nested sub-item list on
   each of the 5 top-level ("toctree-l1") sidebar entries. Those
   sub-headings are already shown, per-page, in the right-hand "On this
   page" panel, so surfacing them again here behind a dropdown is
   redundant — keep the left sidebar to the 5 flat top-level links. --- */
.globaltoc li.toctree-l1 > button {
  display: none;
}
.globaltoc li.toctree-l1 > ul {
  display: none !important;
}

/* --- 8. Card titles across the site: an SVG icon above the label instead
   of plain text. Used for the ACID cards, the data-model cards, the
   database-vs-DBMS cards, and the locking/MVCC cards. --- */
.acid-card-title,
.card-icon-title {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}
.acid-icon,
.card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  flex-shrink: 0;
  /* black in light mode, white in dark mode */
  color: var(--sy-c-background-contrast);
}
.acid-icon svg,
.card-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
}
.acid-word,
.card-icon-label {
  font-size: 1.05rem;
}


/* --- 10. "Copy page" dropdown: closes on item click (see custom.js), a
   real drop-down animation, a bigger/cleaner external-link arrow, and a
   gray-by-default trigger pill that stays neutral on hover. --- */

/* Trigger pill: muted gray by default, plain dark text on hover (no glow) */
#copy-page-trigger {
  color: var(--gray-a11);
  transition: color 0.15s ease, border-color 0.15s ease;
}
#copy-page-trigger button {
  color: inherit;
  background-color: transparent !important;
}
#copy-page-trigger:hover,
#copy-page-trigger:focus-within {
  color: var(--sy-c-text);
}
#copy-page-trigger button:hover {
  background-color: var(--sy-c-surface) !important;
}

/* Dropdown panel: proper open/close animation instead of an instant
   display:none/block toggle */
#copy-page-content {
  transform-origin: top right;
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
  min-width: 260px;
}
#copy-page-content[aria-hidden="true"] {
  display: block;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-6px) scale(0.96);
}
#copy-page-content[aria-hidden="false"] {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
}

/* Two-line menu items: icon, title + description, arrow on the right.
   Hover is a *subtle* background highlight (no solid color block) — the
   title already reads bright against the dark theme; hover just brightens
   the description to match it and lightens the row background a touch. */
#copy-page-content {
  min-width: 300px;
}
#copy-page-content button[role="menuitem"],
#copy-page-content a[role="menuitem"] {
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.55rem 0.6rem;
  width: 100%;
  white-space: normal;
  text-align: left;
  color: var(--sy-c-text);
  border-radius: 0.4rem;
  transition: background-color 0.12s ease;
}
#copy-page-content .menu-item-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
  text-align: left;
}
#copy-page-content .menu-item-title {
  color: var(--sy-c-text);
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1.3;
  white-space: nowrap;
  transition: color 0.12s ease;
}
#copy-page-content .menu-item-desc {
  color: var(--sy-c-light);
  font-weight: 400;
  font-size: 0.78rem;
  line-height: 1.35;
  white-space: nowrap;
  transition: color 0.12s ease;
}
#copy-page-content button[role="menuitem"]:hover,
#copy-page-content a[role="menuitem"]:hover {
  background: var(--gray-a3);
}
#copy-page-content button[role="menuitem"]:hover .menu-item-desc,
#copy-page-content a[role="menuitem"]:hover .menu-item-desc {
  color: var(--sy-c-text);
}
#copy-page-content button[role="menuitem"]:hover .iconify-icon,
#copy-page-content a[role="menuitem"]:hover iconify-icon {
  border-color: var(--gray-a6);
}

/* Bigger, more prominent icon boxes and glyphs (was 28px / .825rem) */
#copy-page-content .iconify-icon,
#copy-page-content iconify-icon {
  width: 34px;
  height: 34px;
  font-size: 1.15rem;
  flex-shrink: 0;
}
#copy-page-content .iconify-icon .i-lucide {
  width: 1.15rem;
  height: 1.15rem;
}

/* Bigger, clearer "open externally" arrow (was a tiny external-link glyph
   that looked like a smudge at 0.625em) */
:root {
  --lucide-arrow-up-right-url: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M7 17 17 7M7 7h10v10'/%3E%3C/svg%3E");
}
#copy-page-content a {
  position: relative;
  padding-right: 1.8rem;
}
#copy-page-content a:after {
  content: "";
  -webkit-mask: var(--lucide-arrow-up-right-url) no-repeat;
  mask: var(--lucide-arrow-up-right-url) no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  background-color: var(--gray-a10);
  width: 0.95rem;
  height: 0.95rem;
  margin-left: 0;
  position: absolute;
  right: 0.6rem;
  top: 0.7rem;
  transition: background-color 0.12s ease;
}
#copy-page-content a:hover:after {
  background-color: var(--sy-c-text);
}


/* --- 9. Database + cloud icon on the docs home page --- */
.db-cloud-icon-wrap {
  display: flex;
  justify-content: center;
  margin: 2rem 0 2.5rem;
}
.db-cloud-icon {
  width: 220px;
  height: 220px;
  color: var(--sy-c-text);
}

/* --- 14. All admonition types (note, warning, tip, danger, hint,
   important, attention, caution, error, seealso, todo) redesigned as
   plain, fully-rounded pill-cards — icon + text, one flat muted
   background, no colored left border, no separate title bar — instead
   of Shibuya's default left-border-plus-dot style. Each type keeps its
   own hue via the theme's existing --color-2 (tint bg) / --color-4
   (text) variables, so light/dark both adapt automatically. Icon is
   28px and vertically centered on the full card. */
:root {
  --lucide-info-url: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E");
}

.admonition {
  display: grid;
  grid-template-columns: 28px 1fr;
  column-gap: 0.75rem;
  row-gap: 0.35rem;
  border: none;
  border-left: none;
  border-radius: 14px;
  padding: 1rem 1.25rem;
  background-color: var(--color-2);
  color: var(--color-4);
  position: relative;
}

.admonition:before,
.admonition:after {
  content: none;
}

.admonition::before {
  content: "";
  grid-column: 1;
  grid-row: 1 / -1;      /* span every row of content (title + all body paragraphs) */
  align-self: center;     /* center against that full spanned height = whole card */
  justify-self: center;
  margin-left: 6px;       /* shift right, as in your reference image */
  width: 28px;
  height: 28px;
  background-color: currentColor;
  -webkit-mask: var(--icon-url) no-repeat;
  mask: var(--icon-url) no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

.admonition > p.admonition-title {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  padding: 0;
  color: inherit;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: none;
}
/* Icon/color tweaks so warning and note match the approved reference
   look (amber triangle-alert / neutral gray info-circle) rather than
   the theme's default orange-zap / blue-calendar pairing. */
.admonition.warning {
  --icon-url: var(--lucide-alert-url);
  --color-2: var(--amber-a3);
  --color-4: var(--amber-a11);
}
.admonition.note {
  --icon-url: var(--lucide-info-url);
  --color-2: var(--gray-a3);
  --color-4: var(--gray-a11);
}

.admonition > p:not(.admonition-title) {
  grid-column: 2;
  grid-row: 2;
  margin: 0;
  color: inherit;
}
.admonition strong,
.admonition em {
  color: inherit;
}
html.dark {
  --code-block-background: var(--gray-a5);
  --code-block-caption-background: var(--gray-a6);
  --code-block-highlight: var(--gray-a6);
  --yue-c-code-background: var(--gray-a5);
}

/* --- 13. Inline `code` spans: double-clicking anywhere inside now selects
   the whole snippet instead of just one word. --- */
.yue li > code,
.yue p > code {
  -webkit-user-select: all;
  -moz-user-select: all;
  user-select: all;
}

/* --- 15. Content tables redesigned as dark dashboard-style cards, with
   pill/badge treatment for short categorical values (injected by
   custom.js), matching the reference dashboard-table look: muted
   uppercase header row, flat rows (no zebra striping) separated by
   hairlines, a soft hover highlight per row, and a bold first column. --- */
.yue .table-wrapper {
  border: 1px solid var(--sy-c-border);
  background: var(--gray-a2);
  overflow: hidden;
  margin: 1.5rem 0;
}
.yue table.docutils {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  font-size: 0.9rem;
}
.yue table.docutils td,
.yue table.docutils th {
  border-left: none;
  border-right: none;
}
.yue table.docutils colgroup,
.yue table.docutils col {
  border: none;
}
.yue table.docutils thead tr {
  background: transparent;
}
.yue table.docutils thead th {
  background: var(--gray-a3);
  color: var(--sy-c-light);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: left;
  padding: 0.75rem 1.1rem;
  border-bottom: 1px solid var(--sy-c-border);
  white-space: nowrap;
}
.yue table.docutils tbody tr.row-odd,
.yue table.docutils tbody tr.row-even {
  background: transparent;
}
.yue table.docutils tbody tr {
  transition: background-color 0.12s ease;
}
.yue table.docutils tbody tr:hover {
  background: var(--gray-a3);
}
.yue table.docutils tbody td {
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--sy-c-border);
  vertical-align: top;
  color: var(--sy-c-text);
}
.yue table.docutils tbody tr:last-child td {
  border-bottom: none;
}
.yue table.docutils tbody td:first-child {
  font-weight: 600;
  white-space: nowrap;
}
.yue table.docutils td p,
.yue table.docutils th p {
  margin: 0;
}

/* Pill badges for short categorical cell values, injected by custom.js */
.table-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}
.table-badge-green { background: var(--green-a3); color: var(--green-a11); }
.table-badge-blue { background: var(--blue-a3); color: var(--blue-a11); }
.table-badge-amber { background: var(--amber-a3); color: var(--amber-a11); }
.table-badge-purple { background: var(--purple-a3); color: var(--purple-a11); }
.table-badge-pink { background: var(--pink-a3); color: var(--pink-a11); }
.table-badge-teal { background: var(--teal-a3); color: var(--teal-a11); }
.table-badge-indigo { background: var(--indigo-a3); color: var(--indigo-a11); }

/* Data-model column on the reference-systems table: icon + label instead
   of a color-coded pill, reusing the same glyphs as the data-models cards */
.table-model {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--sy-c-text);
}
.table-model svg {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  color: var(--sy-c-light);
}

/* 11. Radius normalization pass: consistent rounded corners
   site-wide (code blocks, admonitions, tables, cards, buttons, search box,
   nav pills, dropdowns, badges, images, etc.) */
div.highlight,
div.highlight pre,
.navigation a,
#search-results ul.search > li,
.searchform input[type="text"],
.searchform .search-icon-btn,
.admonition,
div.versionadded, div.versionchanged, div.versionremoved, div.deprecated,
pre.literal-block,
.yue .table-wrapper,
.yue .jupyter_container,
.container.image-1, .container.video-1,
.container.image-2, .container.video-2,
#copy-page-trigger,
#copy-page-content,
#copy-page-content .iconify-icon,
#copy-page-content iconify-icon,
#copy-page-content button[role="menuitem"],
#copy-page-content a[role="menuitem"],
.sy-head-links .link>ul,
.nav-versions-choices, .nav-languages-choices,
.repo-stats,
.demo,
.demo-code .highlight>pre,
.searchbox input,
#docsearch .DocSearch-Button,
.sy-deprecated,
.acid-badge,
dt.sig,
.sphinx-sponsors_avatar {
  border-radius: 16px !important;
}
/* Smaller controls get a slightly smaller but still soft radius */
div.highlight .custom-copybtn,
.code-block-caption,
.yue li > code, .yue p > code,
.sd-badge,
.sd-btn,
.container.buttons a,
#carbonads,
.bsa-cta,
.yue a.bsa-container,
.yue a.bsa-ad-via {
  border-radius: 10px !important;
}
/* Elements that had no radius at all (sharp squares by default) */
.sd-card,
.sd-card-img-overlay,
.sd-card-img, .sd-card-img-top, .sd-card-img-bottom,
.yue .sidebar,
#ethical-ad-placement .ethical-sidebar {
  border-radius: 16px !important;
}
.search-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 32px 0 16px;
  flex-wrap: wrap;
  font-size: 0.9rem;
}
.search-pagination-pages {
  display: flex;
  align-items: center;
  gap: 4px;
}
.search-pagination-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  padding: 0 10px;
  border: none;
  background: transparent;
  color: var(--sy-c-text);
  font-size: 0.9rem;
  font-weight: 500;
  border-radius: 9999px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.search-pagination-pages .search-pagination-btn {
  padding: 0;
}
.search-pagination-btn:hover:not(.is-disabled):not(.is-active) {
  background: var(--sy-c-hover, rgba(127, 127, 127, 0.15));
}
.search-pagination-btn.is-active {
  background: var(--sy-c-accent, #3b82f6);
  color: #fff;
}
.search-pagination-btn.is-disabled {
  color: var(--sy-c-light, #9ca3af);
  cursor: default;
  opacity: 0.6;
}
/* Per-page keyword matches: each match on a page its own jump-to-text
   sub-result, nested under the page's title link inside the result card. */
#search-results ul.search > li {
  padding-bottom: 0.5rem;
}
#search-results ul.search-result-matches {
  margin: 0.25rem 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--sy-c-border);
  padding-top: 0.5rem;
}
#search-results ul.search-result-matches > li {
  margin: 0;
  padding: 0;
}
#search-results ul.search-result-matches > li + li {
  margin-top: 0.35rem;
}
#search-results ul.search-result-matches > li > a {
  position: relative;
  display: block;
  font-weight: 400;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--sy-c-light);
  text-decoration: none;
  padding: 0.35rem 1.75rem 0.35rem 0.85rem;
  border-radius: 8px;
  border-left: 2px solid var(--sy-c-border);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
#search-results ul.search-result-matches > li > a:hover {
  background: var(--sy-c-hover, rgba(127,127,127,.08));
  border-left-color: var(--sy-c-accent, #3b82f6);
  color: var(--sy-c-text);
  text-decoration: none;
}
#search-results ul.search-result-matches > li > a::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0.6rem;
  width: 0.85rem;
  height: 0.85rem;
  transform: translateY(-50%) translateX(-4px);
  background-color: var(--sy-c-light);
  -webkit-mask: var(--lucide-chevron-right-url) no-repeat;
  mask: var(--lucide-chevron-right-url) no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
#search-results ul.search-result-matches > li > a:hover::after {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  background-color: var(--sy-c-accent, #3b82f6);
}
/* keyword highlighted within the excerpt */
#search-results ul.search-result-matches .highlighted {
  color: var(--sy-c-text);
  font-weight: 600;
  background: transparent;
}
/* Manual scroll-to-text fallback highlight, applied by custom.js when a
   page loads with a #...:~:text=... fragment. Styled to resemble the
   native ::target-text highlight browsers show for Text Fragments. */
mark.custom-text-fragment-highlight {
  background: var(--amber-a5, rgba(251, 191, 36, .45));
  color: inherit;
  border-radius: 3px;
  padding: 0.05em 0.1em;
  box-shadow: 0 0 0 2px var(--amber-a5, rgba(251, 191, 36, .45));
}
.search-pagination-ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  color: var(--sy-c-light, #9ca3af);
}
/* --- 16. General motion pass: card hover, page fade-in, back-to-top,
   and a skeleton-loader utility used by custom.js (search page + any
   slow-loading region). Kept subtle and short (150-300ms) so it reads as
   polish, not as something the user has to wait through. --- */

/* Cards (sd-card, admonitions, table rows already have hover transitions
   above; this adds the missing base transition so sphinx-design's own
   `.sd-card-hover:hover { transform: scale(1.01) }` eases in instead of
   snapping) */
.sd-card {
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

/* Back-to-top button: fade/scale in instead of an instant display swap */
.back-to-top {
  opacity: 0;
  transform: translateY(6px) scale(0.92);
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
}
.back-to-top[data-visible="true"] {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* Page content: a quick, subtle fade/rise on load so navigating between
   pages doesn't feel like a hard cut. Guarded by prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  main.sy-content {
    animation: sy-page-in 0.28s ease both;
  }
}
@keyframes sy-page-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Sidebar link active-state and hover already transition (see rule 7c
   above); add the same easing to the right-hand "On this page" links and
   the top nav dropdown chevron for consistency. */
.localtoc > ul li > a {
  transition: color 0.15s ease;
}
.sy-head-links .link i.chevron-down {
  transition: transform 0.2s ease;
}
.sy-head-links .link:hover i.chevron-down {
  transform: rotate(180deg);
}

/* --- 16a. Skeleton loader utility. Used by custom.js to show placeholder
   rows in #search-results while the search index loads/queries, and
   available generally as `.skeleton-line` for any other slow region. --- */
.skeleton-line {
  height: 1em;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    var(--gray-a3) 25%,
    var(--gray-a4) 37%,
    var(--gray-a3) 63%
  );
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-line {
    animation: none;
    background: var(--gray-a3);
  }
}
@keyframes skeleton-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* While #search-results carries this class, only the skeleton itself is
   shown - Sphinx's real "Searching..." heading, status text, and result
   list are already in the DOM (rendering takes time, not display) but
   stay hidden until custom.js removes the class after the minimum
   skeleton window has elapsed. */
#search-results.is-skeletal > *:not(.search-skeleton) {
  display: none;
}
.search-error {
  color: var(--sy-c-light);
  padding: 1.5rem 0;
  font-size: 0.95rem;
}
.search-skeleton {
  padding-top: 0.5rem;
}

/* Feedback when a search is submitted with an empty/whitespace-only query
   (blocked in custom.js): a quick shake on the input, plus an inline
   message explaining what to actually do, instead of silently doing
   nothing. Positioned absolutely under the input so it never shifts
   surrounding layout (the header's search box has no spare room). */
@keyframes input-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}
.input-shake {
  animation: input-shake 0.4s ease;
  border-color: var(--red-a8, #dc3545) !important;
}
@media (prefers-reduced-motion: reduce) {
  .input-shake {
    animation: none;
  }
}
.search-empty-hint {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  align-items: flex-start;
  gap: 0.35rem;
  background: transparent;
  color: var(--red-a11, #dc3545);
  border: none;
  border-radius: 0;
  padding: 0;
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.35;
  pointer-events: none;
  animation: search-hint-in 0.15s ease;
}
.search-empty-hint-icon {
  flex: none;
  width: 0.95rem;
  height: 0.95rem;
  margin-top: 0.15em;
  color: var(--red-a11, #dc3545);
}
@keyframes search-hint-in {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .search-empty-hint {
    animation: none;
  }
}
.search-skeleton-card {
  border: 1px solid var(--sy-c-border);
  border-radius: 10px;
  padding: 0.9rem 1.1rem;
  margin-bottom: 0.75rem;
}
.search-skeleton-card .skeleton-line + .skeleton-line {
  margin-top: 0.6rem;
}
.search-skeleton-card .skeleton-line:nth-child(1) { width: 45%; height: 1.1em; }
.search-skeleton-card .skeleton-line:nth-child(2) { width: 92%; }
.search-skeleton-card .skeleton-line:nth-child(3) { width: 78%; }