/* Allow table cells to wrap rather than overflow horizontally. */
table.docutils td, table.docutils th {
    white-space: normal;
}

/* MicroPython "difference to CPython" admonition styling. */
.admonition-difference-to-cpython {
    border: 1px solid var(--sy-c-border, currentColor);
}
.admonition-difference-to-cpython .admonition-title {
    margin: 4px;
}

/* Slightly rounded corners on code blocks. */
.highlight {
    border-radius: 4px;
}

/* Spacing between the footer copyright lines. */
.sy-foot-copyright p {
    margin: 0 0 8px;
}
.sy-foot-copyright p:last-child {
    margin-bottom: 0;
}

/* Let the breadcrumb wrap on narrow screens instead of getting a horizontal
   scrollbar (Shibuya defaults to white-space:nowrap + overflow:auto). */
.sy-breadcrumbs ol {
    white-space: normal;
    flex-wrap: wrap;
    overflow: visible;
}
    /* ─── Landing-only styles ─── */
    :is(.openmv-landing, .omv-cards-page) {
      --omv-blue: #3f7fbf;
      --omv-blue-dark: #2c5e8a;
      --omv-blue-bg: rgba(63, 127, 191, 0.08);
      --omv-radius-sm: 6px;
      --omv-radius-md: 10px;
      --omv-radius-lg: 14px;
      --omv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
      --omv-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
      --omv-shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.10);
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 24px;
    }
    /* The Shibuya container already pads its own gutter on phones,
       so drop our 24 px side padding below the mobile breakpoint to
       avoid stacking two margins (iPhone Safari ends up with a
       very narrow column otherwise). */
    @media (max-width: 768px) {
      :is(.openmv-landing, .omv-cards-page) {
        padding: 0;
      }
    }
    html.dark :is(.openmv-landing, .omv-cards-page) {
      --omv-blue: #6aa6db;
      --omv-blue-dark: #8cbde6;
      --omv-blue-bg: rgba(106, 166, 219, 0.12);
      --omv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
      --omv-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
      --omv-shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.5);
    }

    /* Hide Shibuya's "yue" article styling on the landing for a wider canvas
       and trim the top/bottom chrome the layout adds (pt-12 + .yue padding). */
    body:has(.openmv-landing) .sy-content {
      max-width: 1280px;
      padding-top: 0;
    }
    body:has(.openmv-landing) .yue {
      padding-bottom: 0;
    }

    /* Bump the social icons inside the mobile burger drawer so the GitHub
       link doesn't render as a 16px icon next to a full-size search box. */
    @media (max-width: 1023px) {
      .sy-head-nav .sy-head-socials a { font-size: 24px; }
    }

    /* Widen the right-column TOC (Shibuya's default is w-64 = 256 px) so
       the "openmv/openmv-doc" GitHub widget label doesn't break mid-word.
       Also let the widget's link wrap on natural separators (the slash)
       as a belt-and-suspenders fix. */
    @media (min-width: 1280px) {
      .sy-rside { width: 18rem; }
    }
    .sy-rside .js-repo-stats,
    .sy-rside a {
      overflow-wrap: anywhere;
      word-break: normal;
    }

    /* Reset Shibuya's .yue heading margins inside the landing — we control all
       spacing via .omv-section padding and component margins.
       (.yue p margins are overridden by the component-specific p selectors below.) */
    :is(.openmv-landing, .omv-cards-page) h1,
    :is(.openmv-landing, .omv-cards-page) h2,
    :is(.openmv-landing, .omv-cards-page) h3,
    :is(.openmv-landing, .omv-cards-page) h4 {
      margin: 0;
    }

    /* Override Shibuya's .yue a link styling for landing anchors. Older Shibuya
       underlined via border-bottom (the class-scoped border overrides below);
       newer Shibuya uses text-decoration, which propagates into every line box
       of the composite card/step/button anchors -- kill it here. Same 0-1-1
       specificity as .yue a; custom.css loads after the theme, so it wins.
       Use specificity (:is(.openmv-landing, .omv-cards-page) + class) instead of !important. */
    :is(.openmv-landing, .omv-cards-page) a {
      font-weight: inherit;
      text-decoration: none;
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-step,
    :is(.openmv-landing, .omv-cards-page) a.omv-card,
    :is(.openmv-landing, .omv-cards-page) a.omv-link-card {
      border: 1px solid var(--sy-c-border);
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-step:hover,
    :is(.openmv-landing, .omv-cards-page) a.omv-card:hover,
    :is(.openmv-landing, .omv-cards-page) a.omv-link-card:hover {
      border-color: color-mix(in srgb, var(--omv-blue) 50%, var(--sy-c-border));
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-btn { border: 1px solid transparent; }
    :is(.openmv-landing, .omv-cards-page) a.omv-btn-secondary { border-color: rgba(255, 255, 255, 0.20); }
    :is(.openmv-landing, .omv-cards-page) a.omv-btn-secondary:hover { border-color: rgba(255, 255, 255, 0.30); }
    :is(.openmv-landing, .omv-cards-page) .omv-section-foot a { border-bottom: none; }

    /* ─── Hero — dark panel with autoplay video on the right + gradient fade ─── */
    .omv-hero {
      position: relative;
      overflow: hidden;
      border-radius: var(--omv-radius-lg);
      padding: 64px 56px 52px;
      margin: 24px 0 32px;
      background:
        linear-gradient(135deg, #061a2e 0%, #0e3556 45%, #1d4f7e 100%);
      color: #e6effa;
      isolation: isolate;
    }
    .omv-hero .hero-video {
      position: absolute;
      /* Video keeps its native aspect (no crop). Anchored to the right edge,
         fills the hero vertically. Tweak --hero-video-right to slide it
         (e.g., -80px to bleed off the right edge). */
      --hero-video-right: 0;
      --hero-video-top: 0;
      height: 100%;
      width: auto;
      top: var(--hero-video-top);
      right: var(--hero-video-right);
      margin: 0;          /* Shibuya's .yue video adds 2em top/bottom margin — kill it. */
      /* Fade the video's left edge into the hero gradient so there's no
         hard boundary between the video and the dark area on the left. */
      -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 25%);
              mask-image: linear-gradient(90deg, transparent 0%, black 25%);
      z-index: 0;
      pointer-events: none;
    }
    /* Subtle grid texture over the video. */
    .omv-hero::before {
      content: '';
      position: absolute;
      inset: 0;
      background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 30h60M30 0v60' stroke='%23ffffff' stroke-width='0.4' opacity='0.04'/%3E%3C/svg%3E");
      pointer-events: none;
      z-index: 1;
    }
    /* Left-to-right gradient fade — keeps the title and CTAs legible. */
    .omv-hero::after {
      content: '';
      position: absolute;
      inset: 0;
      background:
        linear-gradient(90deg,
          rgba(6, 26, 46, 0.95) 0%,
          rgba(6, 26, 46, 0.85) 30%,
          rgba(14, 53, 86, 0.55) 60%,
          rgba(14, 53, 86, 0) 100%),
        linear-gradient(180deg,
          rgba(6, 26, 46, 0) 65%,
          rgba(6, 26, 46, 0.35) 100%);
      pointer-events: none;
      z-index: 1;
    }
    /* These two rules are deliberately over-specified so they beat
       Shibuya's `.yue section>div` (margin-bottom: 2rem) and
       `.yue section:first-of-type h1` (margin-top: 3.4rem), which
       would otherwise add a 2rem gap under the wrapper and a 3.4rem
       gap above the headline. */
    .omv-hero > .omv-hero-inner { position: relative; z-index: 2; margin: 0; }
    .omv-hero > .omv-hero-inner > .omv-hero-inner-h1 { margin-top: 0; }
    @media (max-width: 600px) {
      .omv-hero .hero-video { display: none; }
    }
    .omv-hero-badge {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      padding: 5px 14px;
      border-radius: 999px;
      background: rgba(255, 255, 255, 0.08);
      border: 1px solid rgba(255, 255, 255, 0.18);
      color: #b9d4ed;
      font-size: 12px;
      font-weight: 500;
      letter-spacing: 0.2px;
      margin-bottom: 22px;
      backdrop-filter: blur(4px);
    }
    .omv-hero-badge .dot {
      width: 6px;
      height: 6px;
      border-radius: 50%;
      background: #6aa6db;
      box-shadow: 0 0 10px #6aa6db;
      animation: omv-pulse 2s ease-in-out infinite;
    }
    @keyframes omv-pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.4; }
    }
    .omv-hero h1 {
      font-size: 50px;
      font-weight: 700;
      line-height: 1.08;
      letter-spacing: -1.5px;
      color: #ffffff;
      margin: 0 0 18px;
      max-width: 720px;
    }
    .omv-hero h1 .accent { color: #7eb8e8; }
    .omv-hero p.lead {
      font-size: 18px;
      line-height: 1.65;
      color: #b9d4ed;
      max-width: 580px;
      margin: 0 0 32px;
    }
    .omv-hero-cta {
      display: flex;
      gap: 12px;
      flex-wrap: wrap;
    }
    .omv-btn {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      padding: 11px 22px;
      border-radius: var(--omv-radius-md);
      font-size: 14px;
      font-weight: 600;
      text-decoration: none;
      border: 1px solid transparent;
      transition: transform 0.15s, box-shadow 0.15s, background 0.15s, border-color 0.15s;
    }
    /* Bumped to :is(.openmv-landing, .omv-cards-page) prefix so we beat .yue a's link color (0,1,1). */
    :is(.openmv-landing, .omv-cards-page) .omv-btn-primary {
      background: #ffffff;
      color: #0e3556;
    }
    :is(.openmv-landing, .omv-cards-page) .omv-btn-primary:hover {
      background: #f4f7fb;
      color: #0e3556;
      border-bottom-width: 1px;
      transform: translateY(-1px);
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    }
    :is(.openmv-landing, .omv-cards-page) .omv-btn-secondary {
      background: rgba(255, 255, 255, 0.08);
      color: #ffffff;
      border-color: rgba(255, 255, 255, 0.20);
      backdrop-filter: blur(4px);
    }
    :is(.openmv-landing, .omv-cards-page) .omv-btn-secondary:hover {
      color: #ffffff;
      border-bottom-width: 1px;
      transform: translateY(-1px);
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    }
    .omv-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

    /* ─── Sections ─── */
    /* Sections only contribute padding above; component bottoms (cards,
       callouts, section-foot links) carry their own margins. */
    .omv-section { padding: 28px 0 0; }

    .omv-section-header {
      display: flex;
      align-items: baseline;
      gap: 12px;
      margin-bottom: 8px;
      flex-wrap: wrap;
    }
    .omv-section-tag {
      font-size: 11px;
      font-weight: 600;
      letter-spacing: 0.6px;
      text-transform: uppercase;
      color: var(--omv-blue);
      background: var(--omv-blue-bg);
      padding: 3px 10px;
      border-radius: 999px;
    }
    .omv-section h2 {
      font-size: 26px;
      font-weight: 700;
      letter-spacing: -0.4px;
      color: var(--sy-c-heading);
      margin: 0;
    }
    p.omv-section-desc {
      font-size: 15px;
      color: var(--sy-c-light);
      max-width: 920px;
      margin: 8px 0 28px;
      line-height: 1.55;
    }

    /* ─── Quick start steps ─── */
    .omv-steps {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 16px;
    }
    .omv-step {
      background: var(--sy-c-surface);
      border: 1px solid var(--sy-c-border);
      border-radius: var(--omv-radius-lg);
      padding: 24px;
      position: relative;
      overflow: hidden;
      transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
      text-decoration: none;
      color: inherit;
      display: block;
    }
    .omv-step:hover {
      transform: translateY(-2px);
      box-shadow: var(--omv-shadow-md);
      border-color: color-mix(in srgb, var(--omv-blue) 50%, var(--sy-c-border));
    }
    .omv-step-num {
      width: 30px; height: 30px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      font-size: 13px;
      font-weight: 700;
      border-radius: 50%;
      background: var(--omv-blue-bg);
      color: var(--omv-blue);
      margin-bottom: 14px;
    }
    .omv-step h3 {
      font-size: 16px;
      font-weight: 600;
      color: var(--sy-c-heading);
      margin: 0 0 6px;
    }
    .omv-step p {
      font-size: 13px;
      line-height: 1.55;
      color: var(--sy-c-light);
      margin: 0;
    }

    /* ─── Tabbed code section (split panel) ─── */
    .omv-code-card {
      background: var(--sy-c-surface);
      border: 1px solid var(--sy-c-border);
      border-radius: var(--omv-radius-lg);
      overflow: hidden;
      box-shadow: var(--omv-shadow-sm);
      display: flex;
      flex-direction: column;
    }
    .omv-code-card .tab-headers {
      display: flex;
      flex-wrap: wrap;
      gap: 0;
      padding: 0;
      border-bottom: 1px solid var(--sy-c-border);
      background: var(--sy-c-surface);
    }
    .omv-code-card .tab-btn {
      padding: 11px 16px;
      border: none;
      background: transparent;
      font: inherit;
      font-size: 13px;
      font-weight: 500;
      color: var(--sy-c-light);
      cursor: pointer;
      border-bottom: 2px solid transparent;
      margin-bottom: -1px;
      transition: color 0.15s, border-color 0.15s, background 0.15s;
      white-space: nowrap;
    }
    .omv-code-card .tab-btn:hover {
      color: var(--sy-c-text);
      background: color-mix(in srgb, var(--omv-blue) 6%, transparent);
    }
    .omv-code-card .tab-btn.active {
      color: var(--omv-blue);
      border-bottom-color: var(--omv-blue);
    }
    .omv-code-card .tab-bodies {
      display: block;
    }
    .omv-code-card .tab-body {
      display: none;
    }
    .omv-code-card .tab-body.active {
      display: grid;
      grid-template-columns: 1.2fr 1fr;
    }
    .omv-code-card .code-pane {
      overflow: hidden;
      display: flex;
    }
    .omv-code-card .code-pane .highlight {
      flex: 1;
      margin: 0;
      border-radius: 0;
      overflow-x: auto;
    }
    .omv-code-card .code-pane pre {
      margin: 0;
      padding: 22px 24px;
      font-size: 13px;
      line-height: 1.6;
      border: none;
    }
    .omv-code-card .desc-pane {
      padding: 24px 26px;
      border-left: 1px solid var(--sy-c-border);
    }
    .omv-code-card .desc-pane h3 {
      font-size: 17px;
      font-weight: 600;
      color: var(--sy-c-heading);
      margin: 0 0 10px;
    }
    .omv-code-card .desc-pane > p {
      font-size: 14px;
      color: var(--sy-c-light);
      line-height: 1.6;
      margin: 0 0 16px;
    }
    .omv-bullet {
      display: flex;
      align-items: flex-start;
      gap: 10px;
      margin-bottom: 12px;
    }
    .omv-bullet:last-child { margin-bottom: 0; }
    .omv-bullet .check {
      flex-shrink: 0;
      width: 20px; height: 20px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      background: var(--omv-blue-bg);
      color: var(--omv-blue);
      margin-top: 1px;
    }
    .omv-bullet .check svg { width: 11px; height: 11px; }
    .omv-bullet span {
      font-size: 13.5px;
      color: var(--sy-c-text);
      line-height: 1.5;
    }
    .omv-bullet code {
      background: var(--omv-blue-bg);
      color: var(--omv-blue);
      padding: 1px 5px;
      border-radius: 4px;
      font-size: 0.92em;
      font-family: var(--sy-f-mono);
    }

    /* ─── Card grids (boards, modules, links) ─── */
    .omv-grid {
      display: grid;
      gap: 14px;
    }
    .omv-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
    .omv-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
    .omv-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }

    .omv-card {
      background: var(--sy-c-surface);
      border: 1px solid var(--sy-c-border);
      border-radius: var(--omv-radius-md);
      padding: 18px 20px;
      text-decoration: none;
      color: inherit;
      transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
      display: block;
      overflow: hidden;
    }
    .omv-card:hover {
      transform: translateY(-2px);
      box-shadow: var(--omv-shadow-md);
      border-color: color-mix(in srgb, var(--omv-blue) 50%, var(--sy-c-border));
    }

    /* Board cards: image on top + body below */
    .omv-card.board { padding: 0; }
    .omv-card.board .board-thumb {
      aspect-ratio: 4 / 3;
      background:
        radial-gradient(ellipse at center, rgba(63, 127, 191, 0.06), transparent 70%),
        var(--sy-c-background);
      display: flex;
      align-items: center;
      justify-content: center;
      border-bottom: 1px solid var(--sy-c-border);
      overflow: hidden;
    }
    html.dark .omv-card.board .board-thumb {
      background:
        radial-gradient(ellipse at center, rgba(106, 166, 219, 0.08), transparent 70%),
        var(--sy-c-background);
    }
    .omv-card.board .board-thumb img {
      max-width: 88%;
      max-height: 88%;
      object-fit: contain;
      transition: transform 0.3s ease-out;
    }
    .omv-card.board:hover .board-thumb img {
      transform: scale(1.03);
    }
    .omv-card.board .board-body {
      padding: 16px 18px 18px;
    }
    .omv-card-icon {
      width: 38px; height: 38px;
      border-radius: var(--omv-radius-sm);
      background: var(--omv-blue-bg);
      color: var(--omv-blue);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 12px;
    }
    .omv-card-icon svg { width: 20px; height: 20px; }

    /* Color palette for module-card, feature-card, and link-card icons.
       Compound selectors so we beat the default .feat-icon and .icon rules (0,2,0). */
    .omv-card.icon-green  .omv-card-icon, .omv-feature-card.icon-green  .feat-icon, .omv-link-card.icon-green  .icon { background: rgba(20, 168, 126, 0.12); color: #0F8C68; }
    .omv-card.icon-blue   .omv-card-icon, .omv-feature-card.icon-blue   .feat-icon, .omv-link-card.icon-blue   .icon { background: rgba(37, 99, 235, 0.12);  color: #2563EB; }
    .omv-card.icon-purple .omv-card-icon, .omv-feature-card.icon-purple .feat-icon, .omv-link-card.icon-purple .icon { background: rgba(124, 58, 237, 0.12); color: #7C3AED; }
    .omv-card.icon-coral  .omv-card-icon, .omv-feature-card.icon-coral  .feat-icon, .omv-link-card.icon-coral  .icon { background: rgba(216, 90, 48, 0.12);  color: #D85A30; }
    .omv-card.icon-amber  .omv-card-icon, .omv-feature-card.icon-amber  .feat-icon, .omv-link-card.icon-amber  .icon { background: rgba(186, 117, 23, 0.14); color: #BA7517; }
    html.dark .omv-card.icon-green  .omv-card-icon, html.dark .omv-feature-card.icon-green  .feat-icon, html.dark .omv-link-card.icon-green  .icon { background: rgba(43, 194, 149, 0.16);  color: #5DD4AE; }
    html.dark .omv-card.icon-blue   .omv-card-icon, html.dark .omv-feature-card.icon-blue   .feat-icon, html.dark .omv-link-card.icon-blue   .icon { background: rgba(96, 165, 250, 0.18);  color: #93C5FD; }
    html.dark .omv-card.icon-purple .omv-card-icon, html.dark .omv-feature-card.icon-purple .feat-icon, html.dark .omv-link-card.icon-purple .icon { background: rgba(167, 139, 250, 0.18); color: #C4B5FD; }
    html.dark .omv-card.icon-coral  .omv-card-icon, html.dark .omv-feature-card.icon-coral  .feat-icon, html.dark .omv-link-card.icon-coral  .icon { background: rgba(251, 146, 60, 0.18);  color: #FDBA74; }
    html.dark .omv-card.icon-amber  .omv-card-icon, html.dark .omv-feature-card.icon-amber  .feat-icon, html.dark .omv-link-card.icon-amber  .icon { background: rgba(251, 191, 36, 0.18);  color: #FCD34D; }
    .omv-card h4 {
      font-size: 14px;
      font-weight: 600;
      color: var(--sy-c-heading);
      margin: 0 0 4px;
    }
    .omv-card.module h4 {
      font-family: var(--sy-f-mono);
      letter-spacing: -0.2px;
    }
    .omv-card p {
      font-size: 12.5px;
      color: var(--sy-c-light);
      line-height: 1.5;
      margin: 0;
    }
    .omv-card .tag {
      display: inline-block;
      font-size: 10px;
      font-weight: 700;
      letter-spacing: 0.5px;
      padding: 2px 7px;
      border-radius: 999px;
      margin-left: 6px;
      vertical-align: middle;
      text-transform: uppercase;
    }
    .omv-card .tag.new { background: var(--omv-blue-bg); color: var(--omv-blue); }
    .omv-card .tag.legacy { background: var(--sy-c-divider); color: var(--sy-c-light); }
    .omv-card .tag.unsupported { background: rgba(216, 90, 48, 0.14); color: #D85A30; }
    html.dark .omv-card .tag.unsupported { background: rgba(251, 146, 60, 0.18); color: #FDBA74; }
    .omv-card .tag.retired { background: rgba(186, 117, 23, 0.14); color: #BA7517; }
    html.dark .omv-card .tag.retired { background: rgba(251, 191, 36, 0.18); color: #FCD34D; }

    .omv-link-card {
      background: var(--sy-c-surface);
      border: 1px solid var(--sy-c-border);
      border-radius: var(--omv-radius-md);
      padding: 16px 18px;
      display: flex;
      align-items: center;
      gap: 14px;
      text-decoration: none;
      color: inherit;
      transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
    }
    .omv-link-card:hover {
      transform: translateY(-2px);
      border-color: color-mix(in srgb, var(--omv-blue) 50%, var(--sy-c-border));
      box-shadow: var(--omv-shadow-md);
    }
    .omv-link-card .icon {
      flex-shrink: 0;
      width: 36px; height: 36px;
      border-radius: var(--omv-radius-sm);
      background: var(--omv-blue-bg);
      color: var(--omv-blue);
      display: inline-flex;
      align-items: center;
      justify-content: center;
    }
    .omv-link-card .icon svg { width: 18px; height: 18px; }
    .omv-link-card h4 {
      font-size: 14px;
      font-weight: 600;
      color: var(--sy-c-heading);
      margin: 0 0 2px;
    }
    .omv-link-card p {
      font-size: 12px;
      color: var(--sy-c-light);
      margin: 0;
    }

    p.omv-section-foot {
      margin: 20px 0 0;
      font-size: 14px;
    }

    .omv-section-foot a {
      color: var(--omv-blue);
      text-decoration: none;
      font-weight: 500;
    }
    .omv-section-foot a:hover { text-decoration: underline; }

    /* ─── Callout ("New to OpenMV?") — clickable card, mockup green ─── */
    .omv-callout-card {
      --omv-green: #14A87E;
      --omv-green-dark: #0A6B50;
      --omv-green-bg: rgba(20, 168, 126, 0.08);
      background: var(--omv-green-bg);
      border-radius: var(--omv-radius-lg);
      padding: 22px 26px;
      display: flex;
      align-items: center;
      gap: 18px;
      margin: 32px 0 0;
      text-decoration: none;
      color: inherit;
      transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
    }
    html.dark .omv-callout-card {
      --omv-green: #2BC295;
      --omv-green-dark: #5DD4AE;
      --omv-green-bg: rgba(43, 194, 149, 0.10);
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-callout-card {
      border: 1px solid color-mix(in srgb, var(--omv-green) 30%, transparent);
    }
    .omv-callout-card:hover {
      transform: translateY(-2px);
      box-shadow: var(--omv-shadow-md);
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-callout-card:hover {
      border-color: color-mix(in srgb, var(--omv-green) 60%, transparent);
    }
    .omv-callout-card .callout-icon {
      flex-shrink: 0;
      width: 44px; height: 44px;
      border-radius: var(--omv-radius-md);
      background: color-mix(in srgb, var(--omv-green) 18%, transparent);
      color: var(--omv-green);
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .omv-callout-card .callout-icon svg { width: 22px; height: 22px; }
    .omv-callout-card .callout-body { flex: 1; }
    .omv-callout-card h3 {
      font-size: 15px;
      font-weight: 600;
      color: var(--omv-green-dark);
      margin: 0 0 3px;
    }
    html.dark .omv-callout-card h3 { color: var(--omv-green); }
    .omv-callout-card p {
      font-size: 13.5px;
      line-height: 1.55;
      color: var(--sy-c-text);
      margin: 0;
    }
    .omv-callout-card .callout-arrow {
      flex-shrink: 0;
      color: var(--omv-green);
      transition: transform 0.2s;
    }
    .omv-callout-card:hover .callout-arrow {
      transform: translateX(4px);
    }
    .omv-callout-card .callout-arrow svg { width: 20px; height: 20px; }

    /* ─── "What's new" strip (slim, under hero) ─── */
    .omv-whatsnew {
      display: flex;
      align-items: center;
      gap: 14px;
      margin: 18px 0 0;
      padding: 12px 20px;
      background: var(--omv-blue-bg);
      border-radius: var(--omv-radius-md);
      text-decoration: none;
      color: inherit;
      transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
    }
    .omv-whatsnew:hover {
      transform: translateY(-2px);
      box-shadow: var(--omv-shadow-md);
    }
    .omv-whatsnew .wn-tag {
      flex-shrink: 0;
      font-size: 11px;
      font-weight: 700;
      letter-spacing: 0.5px;
      text-transform: uppercase;
      padding: 3px 10px;
      border-radius: 999px;
      background: var(--omv-blue);
      color: #fff;
    }
    .omv-whatsnew .wn-text {
      flex: 1;
      font-size: 13.5px;
      color: var(--sy-c-text);
    }
    .omv-whatsnew .wn-text strong { color: var(--sy-c-heading); font-weight: 600; }
    .omv-whatsnew .wn-arrow {
      flex-shrink: 0;
      color: var(--omv-blue);
      display: flex;
      transition: transform 0.2s;
    }
    .omv-whatsnew:hover .wn-arrow { transform: translateX(4px); }
    .omv-whatsnew .wn-arrow svg { width: 18px; height: 18px; }
    @media (max-width: 640px) {
      .omv-whatsnew { flex-wrap: wrap; gap: 8px 12px; }
    }
    /* Override Shibuya's .yue a link-underline border (specificity, not !important). */
    :is(.openmv-landing, .omv-cards-page) a.omv-whatsnew {
      border: 1px solid color-mix(in srgb, var(--omv-blue) 30%, transparent);
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-whatsnew:hover {
      border-color: color-mix(in srgb, var(--omv-blue) 60%, transparent);
    }

    /* ─── Hover-reveal "Explore →" arrow on module + board cards ─── */
    .omv-card .card-arrow {
      margin-top: 12px;
      font-size: 12px;
      font-weight: 500;
      color: var(--omv-blue);
      display: flex;
      align-items: center;
      gap: 4px;
      opacity: 0;
      transform: translateX(-4px);
      transition: opacity 0.2s, transform 0.2s;
    }
    .omv-card:hover .card-arrow {
      opacity: 1;
      transform: translateX(0);
    }
    .omv-card.board .board-body .card-arrow { margin-top: 10px; }

    /* ─── Feature cards ("More resources") ─── */
    .omv-feature-card {
      background: var(--sy-c-surface);
      border: 1px solid var(--sy-c-border);
      border-radius: var(--omv-radius-lg);
      padding: 26px 24px;
      transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
      text-decoration: none;
      color: inherit;
      display: block;
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-feature-card { border: 1px solid var(--sy-c-border); }
    .omv-feature-card:hover {
      transform: translateY(-2px);
      box-shadow: var(--omv-shadow-md);
      border-color: color-mix(in srgb, var(--omv-blue) 50%, var(--sy-c-border));
    }
    :is(.openmv-landing, .omv-cards-page) a.omv-feature-card:hover {
      border-color: color-mix(in srgb, var(--omv-blue) 50%, var(--sy-c-border));
    }
    .omv-feature-card .feat-icon {
      width: 44px; height: 44px;
      border-radius: var(--omv-radius-md);
      background: var(--omv-blue-bg);
      color: var(--omv-blue);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 16px;
    }
    .omv-feature-card .feat-icon svg { width: 22px; height: 22px; }
    .omv-feature-card h3 {
      font-size: 16px;
      font-weight: 600;
      color: var(--sy-c-heading);
      margin: 0 0 6px;
    }
    .omv-feature-card p {
      font-size: 13px;
      color: var(--sy-c-light);
      line-height: 1.55;
      margin: 0;
    }

    /* ─── Responsive ─── */
    @media (max-width: 960px) {
      .omv-grid.cols-4 { grid-template-columns: repeat(2, 1fr); }
      .omv-grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
      .omv-steps { grid-template-columns: 1fr; }
      /* Stack code on top, description below — code-card grid is on .tab-body.active. */
      .omv-code-card .tab-body.active { grid-template-columns: 1fr; }
      .omv-code-card .desc-pane { border-left: none; border-top: 1px solid var(--sy-c-border); }
      .omv-hero h1 { font-size: 34px; }
    }
    @media (max-width: 600px) {
      .omv-grid.cols-4, .omv-grid.cols-3, .omv-grid.cols-2 { grid-template-columns: 1fr; }
      .omv-section { padding: 28px 0 0; }
      /* Mobile hero — restore horizontal padding, shrink the headline so it doesn't run to the edge. */
      .omv-hero { padding: 36px 22px 40px; }
      .omv-hero h1 { font-size: 28px; letter-spacing: -0.8px; }
      .omv-hero p.lead { font-size: 15px; margin-bottom: 22px; }
      /* Stack the hero CTAs vertically on mobile so each one is full-width and tappable. */
      .omv-hero-cta { flex-direction: column; align-items: stretch; gap: 10px; }
      .omv-btn { padding: 11px 16px; font-size: 14px; justify-content: center; }
      /* Tighten the code pane padding so the snippet doesn't overflow horizontally. */
      .omv-code-card .code-pane pre { padding: 16px 14px; font-size: 12px; line-height: 1.55; }
      .omv-code-card .desc-pane { padding: 18px 18px 20px; }
      /* Tab labels wrap freely instead of overflowing on small screens. */
      .omv-code-card .tab-btn { padding: 9px 12px; font-size: 12px; white-space: normal; }
    }

/* ─── Changelog version index (index page dropdowns + per-major sub-pages) ─── */
details.changelog-major {
    border: 1px solid var(--sy-c-border);
    border-radius: 6px;
    margin: 0.5rem 0;
    padding: 0 0.75rem;
}
details.changelog-major > summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 1.1rem;
    padding: 0.6rem 0;
    list-style-position: inside;
}
details.changelog-major[open] > summary {
    border-bottom: 1px solid var(--sy-c-border);
    margin-bottom: 0.5rem;
}
.changelog-major .count,
.changelog-count {
    font-weight: 400;
    font-size: 0.85rem;
    opacity: 0.7;
}
/* Always 5 equal columns; the number of rows grows to fit the list.
   Items flow newest-first left→right, then wrap to the next row. */
ul.changelog-versions {
    list-style: none;
    padding-left: 0;
    margin: 0 0 0.75rem 0;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 0.3rem 1.25rem;
}
/* Narrow screens: drop the fixed 5 columns to a wrapping flow so long
   version strings (e.g. v3.5.0-beta.3) don't get crushed. */
@media (max-width: 640px) {
    ul.changelog-versions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.3rem 1.25rem;
    }
    ul.changelog-versions li {
        flex: 0 0 5.5rem;
    }
}
ul.changelog-versions li {
    margin: 0;
}
/* Product selector on the top-level changelog landing page:
   whole-card links replicating the home-page .omv-card look. */
.changelog-products {
    margin: 1rem 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem;
}
.yue a.changelog-product-card,
a.changelog-product-card {
    background: var(--sy-c-surface);
    border: 1px solid var(--sy-c-border);
    border-bottom: 1px solid var(--sy-c-border);
    border-radius: 10px;
    padding: 18px 20px;
    text-decoration: none;
    color: inherit;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
    display: block;
    overflow: hidden;
}
.yue a.changelog-product-card:hover,
a.changelog-product-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    border-color: color-mix(in srgb, #3f7fbf 50%, var(--sy-c-border));
    border-bottom-color: color-mix(in srgb, #3f7fbf 50%, var(--sy-c-border));
}
html.dark .yue a.changelog-product-card:hover,
html.dark a.changelog-product-card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    border-color: color-mix(in srgb, #6aa6db 50%, var(--sy-c-border));
    border-bottom-color: color-mix(in srgb, #6aa6db 50%, var(--sy-c-border));
}
.yue .changelog-product-card h4,
.changelog-product-card h4 {
    font-size: 14px;
    font-weight: 600;
    color: var(--sy-c-heading);
    margin: 0 0 4px;
}
.yue .changelog-product-card p,
.changelog-product-card p {
    font-size: 12.5px;
    color: var(--sy-c-light);
    line-height: 1.5;
    margin: 0;
}
.changelog-product-card .card-icon {
    width: 38px;
    height: 38px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 12px;
}
.changelog-product-card .card-icon svg {
    width: 20px;
    height: 20px;
}
.changelog-product-card.icon-green .card-icon {
    background: rgba(20, 168, 126, 0.12);
    color: #0F8C68;
}
.changelog-product-card.icon-blue .card-icon {
    background: rgba(37, 99, 235, 0.12);
    color: #2563EB;
}
html.dark .changelog-product-card.icon-green .card-icon {
    background: rgba(43, 194, 149, 0.16);
    color: #5DD4AE;
}
html.dark .changelog-product-card.icon-blue .card-icon {
    background: rgba(96, 165, 250, 0.18);
    color: #93C5FD;
}
.changelog-product-card.icon-purple .card-icon {
    background: rgba(124, 58, 237, 0.12);
    color: #7C3AED;
}
.changelog-product-card.icon-amber .card-icon {
    background: rgba(186, 117, 23, 0.14);
    color: #BA7517;
}
html.dark .changelog-product-card.icon-purple .card-icon {
    background: rgba(167, 139, 250, 0.18);
    color: #C4B5FD;
}
html.dark .changelog-product-card.icon-amber .card-icon {
    background: rgba(251, 191, 36, 0.18);
    color: #FCD34D;
}
.changelog-product-card.icon-coral .card-icon {
    background: rgba(216, 90, 48, 0.12);
    color: #D85A30;
}
html.dark .changelog-product-card.icon-coral .card-icon {
    background: rgba(251, 146, 60, 0.18);
    color: #FDBA74;
}
.changelog-product-card .card-arrow {
    margin-top: 12px;
    font-size: 12px;
    font-weight: 500;
    color: #3f7fbf;
    display: flex;
    align-items: center;
    gap: 4px;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity 0.2s, transform 0.2s;
}
html.dark .changelog-product-card .card-arrow {
    color: #6aa6db;
}
a.changelog-product-card:hover .card-arrow {
    opacity: 1;
    transform: translateX(0);
}

/* Quick-start "Where to go next" cards. Content-body card pattern
   modelled on the changelog product cards (hardcoded colours,
   .yue-prefixed to beat the theme's link styling), but in a
   responsive multi-column grid. */
.next-steps {
    display: grid;
    gap: 0.75rem;
    margin: 1.25rem 0;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.yue a.next-step-card,
a.next-step-card {
    background: var(--sy-c-surface);
    border: 1px solid var(--sy-c-border);
    border-radius: 10px;
    padding: 18px 20px;
    text-decoration: none;
    color: inherit;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
    display: block;
    overflow: hidden;
}
.yue a.next-step-card:hover,
a.next-step-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    border-color: color-mix(in srgb, #3f7fbf 50%, var(--sy-c-border));
}
html.dark .yue a.next-step-card:hover,
html.dark a.next-step-card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    border-color: color-mix(in srgb, #6aa6db 50%, var(--sy-c-border));
}
.yue .next-step-card h4,
.next-step-card h4 {
    font-size: 14px;
    font-weight: 600;
    color: var(--sy-c-heading);
    margin: 0 0 4px;
}
.yue .next-step-card p,
.next-step-card p {
    font-size: 12.5px;
    color: var(--sy-c-light);
    line-height: 1.5;
    margin: 0;
}
.next-step-card .card-icon {
    width: 38px;
    height: 38px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 12px;
}
.next-step-card .card-icon svg {
    width: 20px;
    height: 20px;
}
.next-step-card.icon-green  .card-icon { background: rgba(20, 168, 126, 0.12); color: #0F8C68; }
.next-step-card.icon-blue   .card-icon { background: rgba(37, 99, 235, 0.12);  color: #2563EB; }
.next-step-card.icon-purple .card-icon { background: rgba(124, 58, 237, 0.12); color: #7C3AED; }
.next-step-card.icon-amber  .card-icon { background: rgba(186, 117, 23, 0.14); color: #BA7517; }
.next-step-card.icon-coral  .card-icon { background: rgba(216, 90, 48, 0.12);  color: #D85A30; }
html.dark .next-step-card.icon-green  .card-icon { background: rgba(43, 194, 149, 0.16);  color: #5DD4AE; }
html.dark .next-step-card.icon-blue   .card-icon { background: rgba(96, 165, 250, 0.18);  color: #93C5FD; }
html.dark .next-step-card.icon-purple .card-icon { background: rgba(167, 139, 250, 0.18); color: #C4B5FD; }
html.dark .next-step-card.icon-amber  .card-icon { background: rgba(251, 191, 36, 0.18);  color: #FCD34D; }
html.dark .next-step-card.icon-coral  .card-icon { background: rgba(251, 146, 60, 0.18);  color: #FDBA74; }
.next-step-card .card-arrow {
    margin-top: 12px;
    font-size: 12px;
    font-weight: 500;
    color: #3f7fbf;
    display: flex;
    align-items: center;
    gap: 4px;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity 0.2s, transform 0.2s;
}
html.dark .next-step-card .card-arrow {
    color: #6aa6db;
}
a.next-step-card:hover .card-arrow {
    opacity: 1;
    transform: translateX(0);
}

/* Framed screenshot / photo / video: a 2px rounded border in the
   theme's own colour so raster media reads as a deliberate, contained
   panel rather than butting against the column edge. SVG diagrams are
   deliberately left unframed. Adapts to light/dark. */
.framed img,
img.framed,
.framed video,
video.framed,
.framed-embed {
    box-sizing: border-box;
    border: 1px solid var(--sy-c-border);
    border-radius: 10px;
}
.framed-embed {
    overflow: hidden;
}

/* Controls-less looping demo videos pop out into an enlarged lightbox on
   click (static/video-lightbox.js) -- the column shows them far below native
   resolution. The cursor is the affordance; click anywhere or Esc dismisses. */
video:not([controls]) {
    cursor: zoom-in;
}
.video-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.75);
    cursor: zoom-out;
    opacity: 0;
    transition: opacity 0.15s ease-out;
}
.video-lightbox.open {
    opacity: 1;
}
.video-lightbox video {
    width: min(1720px, 94vw);
    max-height: 94vh;
    height: auto;
    border-radius: 10px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.6);
    cursor: zoom-out;
}

/* sphinxcontrib-video wraps the <video> in a figure that defaults to
   "align-left" (floated), and emits <video width="100%"> -- which browsers
   honour on <img> but NOT on <video>, so the video falls back to its intrinsic
   size and the following text wraps beside the float. Force the video figure to
   a full-width, non-floated block so text flows below it. */
.sphinx-contrib-video-container.align-left,
.sphinx-contrib-video-container {
    float: none;
    display: block;
    width: 100%;
    margin: 1.5rem 0;
}
.sphinx-contrib-video-container video,
video.framed {
    display: block;
    width: 100%;
    height: auto;
    margin: 0;
}

/* Sidebar: the theme absolutely-positions the expand/collapse chevron
   at the right edge of each entry, so long titles run underneath it.
   Reserve a thin column for the chevron on rows that have one. */
.globaltoc li:has(> button) > a {
    display: block;
    padding-right: 1.6rem;
}

/* ─── Wrapping top navbar ─────────────────────────────────────────────
   The theme keeps the navbar on one line and horizontally scrolls it when
   the links overflow. Translated menu labels (e.g. French) are much wider
   than the English ones and made the bar scroll/clip. Let it wrap to
   multiple lines instead, and let the header grow to fit. English and other
   short languages still fit on one line, so this is a no-op for them.
   navbar-height.js keeps --sy-s-offset-top in sync with the taller header so
   the sticky sidebar / breadcrumbs stay aligned. */
.sy-head,
.sy-head-inner {
    height: auto;
    min-height: var(--sy-s-navbar-height);
}
.sy-head-links {
    flex-wrap: wrap;
    overflow: visible;
    white-space: normal;
    row-gap: 0.1rem;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
}
/* Links no longer need to be full navbar-height tall once they can wrap. */
.sy-head-links .link {
    height: auto;
}
/* Keep the logo at its natural size: it is a flex item, so a wider wrapping
   nav would otherwise shrink it and the global img{max-width:100%} rule would
   squash the logo horizontally. */
.sy-head-brand {
    flex-shrink: 0;
}
.sy-head-brand img {
    max-width: none;
    width: auto;
}

/* Mobile burger menu: the theme puts 2rem (32px) of top padding above the
   search/socials/translations block, leaving a big gap under the section
   links. Tighten it to a normal section break (keep some separation). */
@media (max-width: 767px) {
    .sy-head-extra {
        padding-top: 0.75rem;
    }
}

/* ─── RTL (Arabic, Hebrew) ───────────────────────────────────────────
   The Shibuya theme mirrors its own chrome from <html dir="rtl">, but the
   custom home-page components above use physical left/right properties.
   Mirror just those for RTL builds; additive so the LTR rules are untouched.
   Arrow glyphs ("Explore →") live inside the translated strings, so the
   bidi algorithm already places them at the visual-inline-end — only the
   reveal/nudge transforms need their direction flipped. */
[dir="rtl"] .omv-code-card .desc-pane {
    border-left: none;
    border-right: 1px solid var(--sy-c-border);
}
[dir="rtl"] .omv-card .tag {
    margin-left: 0;
    margin-right: 6px;
}
[dir="rtl"] .omv-card .card-arrow { transform: translateX(4px); }
[dir="rtl"] .omv-card:hover .card-arrow { transform: translateX(0); }
[dir="rtl"] .omv-whatsnew:hover .wn-arrow { transform: translateX(-4px); }
[dir="rtl"] .changelog-product-card .card-arrow,
[dir="rtl"] .next-step-card .card-arrow { transform: translateX(4px); }
[dir="rtl"] a.changelog-product-card:hover .card-arrow,
[dir="rtl"] a.next-step-card:hover .card-arrow { transform: translateX(0); }

/* Legacy (CMUcam) pages: lay a group of images out as a single centered row,
   shrinking them as needed so they all fit on one line (never stacking). */
.legacy-center > p {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: flex-start;
  gap: 10px;
  margin: 1rem 0;
}
.legacy-center > p img { min-width: 0; max-width: 100%; height: auto; }

/* Even-height row: for groups whose source thumbnails differ in intrinsic
   size, line them up on a common height instead of showing them at natural
   size. Wraps on narrow screens. */
.legacy-center.legacy-even > p { flex-wrap: wrap; }
.legacy-center.legacy-even > p img { height: 150px; width: auto; max-width: 100%; }
/* Larger even-height variant for rows whose source images are full-size. */
.legacy-center.legacy-even-lg > p { flex-wrap: wrap; }
.legacy-center.legacy-even-lg > p img { height: 300px; width: auto; max-width: 100%; }

/* Present only to get a full-size image collected so a thumbnail can link to it. */
img.legacy-collect-only { display: none; }

/* Responsive 16:9 wrapper for embedded (YouTube) videos on legacy pages. */
.legacy-yt { position: relative; width: 100%; max-width: 720px; margin: 1rem auto; aspect-ratio: 16 / 9; }
.legacy-yt iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Captioned 2x2 quad box for legacy gallery groups (never a single column). */
.legacy-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px 16px; margin: 1rem 0; }
.legacy-grid figure { margin: 0; text-align: center; }
.legacy-grid figure img { max-width: 100%; height: auto; }
.legacy-grid figcaption { margin-top: 4px; font-weight: bold; }
/* Prose variant: descriptive sentence captions read better unbolded. */
.legacy-grid.legacy-grid-prose figcaption { font-weight: normal; }

/* Give raster media across the legacy (CMUcam) pages the same rounded,
   contained frame as the .framed treatment used elsewhere. The .legacy-pages
   class is set by static/legacy-frame.js on any /legacy/ URL, so no
   per-directive tagging is needed. */
html.legacy-pages article.yue img:not(.legacy-collect-only),
html.legacy-pages article.yue video {
    box-sizing: border-box;
    border: 1px solid var(--sy-c-border);
    border-radius: 10px;
}
html.legacy-pages .legacy-yt {
    border-radius: 10px;
    overflow: hidden;
}
/* Thumbnail -> full-size images are wrapped in a link; suppress the theme's
   link underline that would otherwise draw a line under the image. Direct
   images get the .image-reference class; substitution images (rows) are a
   bare .reference inside a .legacy-center container. */
html.legacy-pages article.yue a.image-reference,
html.legacy-pages .legacy-center a {
    border-bottom: none;
    text-decoration: none;
    background-image: none;
}
/* The intro page's board-style camera cards carry transparent-background
   product photos with their own treatment -- leave those unframed. */
html.legacy-pages .omv-card img {
    border: none;
    border-radius: 0;
}
/* Pages flagged by legacy-frame.js opt out of the frame entirely (board
   photos, header image rows). Keeps the link-underline suppression above.
   The :not() matches the framing rule's specificity so source order wins. */
html.legacy-noframe article.yue img:not(.legacy-collect-only),
html.legacy-noframe article.yue video {
    border: none;
    border-radius: 0;
}
/* Per-image opt-out (e.g. diagrams) via :class: legacy-unframed on the figure. */
html.legacy-pages article.yue img.legacy-unframed {
    border: none;
    border-radius: 0;
}

/* Download-role links should read as normal prose links, not monospace code. */
a.reference.download code,
a.reference.download code .pre {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
}
