/* SPDX-License-Identifier: AGPL-3.0-only */
/* Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0 */

/* Hub feature CSS.

   Lives with the Hub feature module so the styling stays bundled with the
   Hub. Wired into the build via a single @import in studio/frontend/src/index.css.

   Format/status color tokens and shared picker controls resolve wherever those
   components render. Hub-only rule bodies are scoped to .hub-page or
   hub-prefixed classes. */

:root {
  --format-gguf: #60a5fa;
  --format-checkpoint: #f472b6;
  --format-adapter: #8b5cf6;
  --format-mlx: #f59e0b;
  --status-warning: #eab308;
  --status-danger: #ef4444;
  --status-success: #11b686;
  /* Fixed ink for text on --status-success. It cannot borrow
     --primary-foreground: a custom accent recolors that, while the success
     background stays put, so the pair would drift out of contrast. This is
     the ink Classic and Minimal dark already render there, at 7.46:1. */
  --status-success-foreground: #0d0d0d;
}

.dark {
  --format-gguf: #60a5fa;
  --format-checkpoint: #f472b6;
  --format-adapter: #a78bfa;
  --format-mlx: #fbbf24;
  --status-warning: #fbbf24;
  --status-danger: #ef4444;
  --status-success: #11b686;
  --status-success-foreground: #0d0d0d;
}

@theme inline {
  --color-format-gguf: var(--format-gguf);
  --color-format-checkpoint: var(--format-checkpoint);
  --color-format-adapter: var(--format-adapter);
  --color-format-mlx: var(--format-mlx);
  --color-status-warning: var(--status-warning);
  --color-status-danger: var(--status-danger);
  --color-status-success: var(--status-success);
  --color-status-success-foreground: var(--status-success-foreground);
}

@layer base {
  /* Shared measure for every centered Hub column (top bar, catalog, detail,
     settings). Container-relative, so the column tracks the width actually
     available instead of pinning to 1100px and leaving wide empty gutters.
     The floor keeps the old measure on ~1280px laptops, the cap stops rows
     stretching on ultrawides, and `max-width` never forces overflow, so the
     floor stays safe on narrow viewports. */
  .hub-page {
    --hub-measure: clamp(1100px, 94%, 1760px);
    /* Split mode's detail pane: tighter, the master list takes the left. */
    --hub-measure-compact: clamp(860px, 94%, 1180px);
    /* Model card readme. Fills the column, capped so prose stays readable. */
    --hub-readme-measure: 1400px;
  }

  /* Filled-control surface — Hub search, Hub filter triggers, picker
	   search bars. Borderless soft fill matching the .hub-tab-toggle pills:
	     - Resting: 5% bg, no border
	     - Hover / open: 8% bg
	     - Focus: keyboard-only (:focus-visible) so a mouse click never
	       leaves the control looking "selected"; the open dropdown stays
	       lit via [data-state="open"].
	   `!important` is required because these controls also carry shadcn
	   Input utilities (bg-input/30, border, focus ring) that live in the
	   utilities layer and would otherwise win over this base layer. */
  .field-soft {
    background-color: color-mix(in srgb, var(--foreground) 5%, transparent) !important;
    border: 0;
    box-shadow: none;
    transition: background-color 160ms ease;
  }

  .field-soft:hover,
  .field-soft[data-state="open"] {
    background-color: color-mix(in srgb, var(--foreground) 8%, transparent) !important;
  }

  .field-soft:focus-visible {
    background-color: color-mix(in srgb, var(--foreground) 8%, transparent) !important;
    outline: none;
  }

  .dark .field-soft {
    background-color: color-mix(in srgb, var(--foreground) 5%, transparent) !important;
  }

  .dark .field-soft:hover,
  .dark .field-soft[data-state="open"] {
    background-color: color-mix(in srgb, var(--foreground) 9%, transparent) !important;
  }

  .dark .field-soft:focus-visible {
    background-color: #1c1c1c !important;
  }

  /* The Hub search field is `type="search"` (so the browser won't offer saved
     passwords on it). Suppress the native WebKit clear button / decoration so
     the field keeps its custom trailing ⌘K hint and spinner. */
  .field-soft[type="search"]::-webkit-search-cancel-button,
  .field-soft[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
    appearance: none;
  }

  .hub-page .hub-canvas {
    background-color: var(--background);
  }

  html.dark .hub-page .hub-canvas {
    background-color: var(--background);
  }

  .hub-page .hub-detail-bar {
    background-color: var(--background);
  }

  .hub-page .hub-detail-bar::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: 40px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 240ms ease;
    background: linear-gradient(
      to bottom,
      var(--background),
      color-mix(in srgb, var(--background) 55%, transparent) 48%,
      transparent
    );
  }

  .hub-page .hub-scroll-fade {
    pointer-events: none;
    opacity: 0;
    transition: opacity 240ms ease;
    /* Thin solid band right under the search bar, then fade quickly so the
       white area stays slim. */
    background: linear-gradient(
      to bottom,
      var(--background),
      var(--background) 8%,
      color-mix(in srgb, var(--background) 55%, transparent) 38%,
      transparent
    );
  }

  .hub-page .hub-detail-bar[data-scrolled="true"]::after,
  .hub-page .hub-scroll-fade[data-scrolled="true"] {
    opacity: 1;
  }

  .hub-page .hub-carousel-fade {
    pointer-events: none;
    position: absolute;
    z-index: 5;
    width: 44px;
    opacity: 0;
    transition: opacity 240ms ease;
  }

  .hub-page .hub-carousel-fade[data-visible="true"] {
    opacity: 1;
  }

  .hub-page .hub-carousel-fade-left {
    /* -8px matches the scroller's -mx-2 bleed so the opaque edge sits on the
       clip edge and no card peeks out beside the fade. */
    left: -8px;
    background: linear-gradient(
      to right,
      var(--background),
      color-mix(in srgb, var(--background) 55%, transparent) 48%,
      transparent
    );
  }

  .hub-page .hub-carousel-fade-right {
    /* Mirror of fade-left: offset by the -mx-2 bleed to reach the clip edge. */
    right: -8px;
    background: linear-gradient(
      to left,
      var(--background),
      color-mix(in srgb, var(--background) 55%, transparent) 48%,
      transparent
    );
  }

  .hub-page .hub-model-card {
    --hub-card-border-accent: var(--foreground);
    --hub-card-edge-mix: 2.2%;
    --hub-card-inner-accent: var(--background);
    --hub-card-inner-mix: 12%;
    --hub-card-inner-opacity: 0.14;
    --hub-card-corner-mix: 8.5%;
    --hub-card-corner-opacity: 0.48;
    --hub-card-hover-edge-mix: 5.5%;
    --hub-card-edge: color-mix(
      in srgb,
      var(--hub-card-border-accent) var(--hub-card-edge-mix),
      transparent
    );
    --hub-card-inner-edge: color-mix(
      in srgb,
      var(--hub-card-inner-accent) var(--hub-card-inner-mix),
      transparent
    );
    --hub-card-corner-edge: color-mix(
      in srgb,
      var(--hub-card-border-accent) var(--hub-card-corner-mix),
      transparent
    );
    --hub-card-hover-edge: color-mix(
      in srgb,
      var(--hub-card-border-accent) var(--hub-card-hover-edge-mix),
      transparent
    );
    position: relative;
    overflow: hidden;
    border-radius: 18px;
    background-color: color-mix(in srgb, var(--foreground) 2.5%, transparent);
    border: 1px solid transparent;
    box-shadow: none;
    transition: background-color 160ms ease, border-color 160ms ease;
  }

  .hub-page .hub-model-card::after {
    position: absolute;
    border-radius: inherit;
    content: "";
    pointer-events: none;
    z-index: 2;
  }

  .hub-page .hub-model-card::after {
    inset: 0;
    border: 1px solid var(--hub-card-corner-edge);
    opacity: 0;
    -webkit-mask:
      linear-gradient(
        90deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      top left / 48% 44px no-repeat,
      linear-gradient(
        180deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      top left / 44px 160px no-repeat,
      linear-gradient(
        270deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      bottom right / 48% 44px no-repeat,
      linear-gradient(
        0deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      bottom right / 44px 160px no-repeat;
    mask:
      linear-gradient(
        90deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      top left / 48% 44px no-repeat,
      linear-gradient(
        180deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      top left / 44px 160px no-repeat,
      linear-gradient(
        270deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      bottom right / 48% 44px no-repeat,
      linear-gradient(
        0deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      bottom right / 44px 160px no-repeat;
  }

  .hub-page .hub-model-card:hover {
    background-color: color-mix(in srgb, var(--foreground) 4.5%, transparent);
    border-color: transparent;
  }

  html.dark .hub-page .hub-model-card {
    --hub-card-border-accent: var(--foreground);
    --hub-card-edge-mix: 2.8%;
    --hub-card-inner-accent: var(--foreground);
    --hub-card-inner-mix: 2.5%;
    --hub-card-inner-opacity: 0.22;
    --hub-card-corner-mix: 9.5%;
    --hub-card-hover-edge-mix: 6%;
    background-color: color-mix(in srgb, var(--foreground) 7%, transparent);
    border-color: transparent;
  }

  html.dark .hub-page .hub-model-card:hover {
    background-color: #202020;
    border-color: transparent;
  }

  .hub-page .hub-model-card-art {
    --hub-model-card-accent: var(
      --hub-card-art-accent,
      var(--hub-card-border-accent)
    );
    --hub-model-card-art-base: var(--background);
    position: relative;
    background: radial-gradient(
        115% 90% at 18% 8%,
        color-mix(in srgb, var(--hub-model-card-accent) 20%, transparent),
        transparent 58%
      ),
      radial-gradient(
        90% 80% at 86% 18%,
        color-mix(in srgb, var(--hub-model-card-accent) 14%, transparent),
        transparent 60%
      ),
      linear-gradient(
        160deg,
        color-mix(
            in srgb,
            var(--hub-model-card-accent) 10%,
            var(--hub-model-card-art-base)
          )
          0%,
        color-mix(
            in srgb,
            var(--hub-model-card-accent) 18%,
            var(--hub-model-card-art-base)
          )
          52%,
        color-mix(
            in srgb,
            var(--hub-model-card-accent) 11%,
            var(--hub-model-card-art-base)
          )
          100%
      );
  }

  .hub-page .hub-model-card-art::after {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    background: linear-gradient(
        90deg,
        var(--hub-card-inner-edge),
        transparent 72%
      )
      top left / 58% 1px no-repeat,
      linear-gradient(270deg, var(--hub-card-inner-edge), transparent 72%) top
      right / 42% 1px no-repeat;
    content: "";
    opacity: 0;
    pointer-events: none;
  }

  html.dark .hub-page .hub-model-card-art {
    background: linear-gradient(
      160deg,
      color-mix(in srgb, var(--hub-model-card-accent) 76%, #0b0b0d) 0%,
      color-mix(in srgb, var(--hub-model-card-accent) 92%, #0b0b0d) 52%,
      color-mix(in srgb, var(--hub-model-card-accent) 70%, #0b0b0d) 100%
    );
  }

  .hub-page .hub-trending-card {
    /* Flat neutral surface shared by the featured, trending and fine-tune
       cards: a clean elevated body, no border, no colour, no gradient. Dark
       defaults here; the html:not(.dark) block recolours for the light theme
       and adds the (light-only) drop shadow. */
    --hub-trending-surface: color-mix(in srgb, var(--foreground) 7%, var(--background));
    --hub-trending-surface-hover: color-mix(in srgb, var(--foreground) 10%, var(--background));
    --hub-trending-title-ink: rgb(255 255 255 / 0.94);
    --hub-trending-muted-ink: rgb(255 255 255 / 0.68);
    isolation: isolate;
    border: 0;
    border-radius: 18px;
    background-color: var(--hub-trending-surface);
    box-shadow: none;
    transition: background-color 160ms ease;
  }

  html:not(.dark) .hub-page .hub-trending-card {
    --hub-trending-surface: var(--card);
    --hub-trending-surface-hover: var(--card);
    --hub-trending-title-ink: var(--foreground);
    --hub-trending-muted-ink: var(--muted-foreground);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
    transition:
      box-shadow 200ms ease,
      background-color 160ms ease;
  }

  html:not(.dark) .hub-page .hub-model-card.hub-trending-card {
    transition:
      box-shadow 200ms ease,
      transform 200ms ease,
      background-color 160ms ease;
  }

  html:not(.dark) .hub-page .hub-model-card.hub-trending-card:hover {
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
    transform: translateY(-2px);
  }

  .hub-page .hub-trending-card > * {
    position: relative;
    z-index: 1;
  }

  .hub-page .hub-trending-card:hover {
    background-color: var(--hub-trending-surface-hover);
  }

  .hub-page .hub-trending-card::after {
    opacity: 0;
  }

  /* Dark spotlight cards keep their avatars frameless; the light theme lets the
     smooth hairline show so white-background logos read cleanly against the
     pale surface instead of blending into it. */
  html.dark .hub-page .hub-trending-card .hub-avatar-tile::after {
    opacity: 0;
  }

  .hub-page .hub-trending-card .hub-model-card-art,
  html.dark .hub-page .hub-trending-card .hub-model-card-art {
    background: transparent;
  }

  .hub-page .hub-trending-card .hub-model-card-art::after {
    opacity: 0;
  }

  .hub-page .hub-trending-title {
    color: var(--hub-trending-title-ink);
  }

  .hub-page .hub-trending-owner,
  .hub-page .hub-trending-stats .text-muted-foreground\/75 {
    color: var(--hub-trending-muted-ink);
  }

  /* Dark theme paints the size chip with a translucent white fill against the
     dark surface; in the light theme it falls through to the base .hub-chip
     style, which is already theme-aware. */
  html.dark .hub-page .hub-trending-card .hub-chip {
    background-color: rgb(255 255 255 / 0.12);
    color: rgb(255 255 255 / 0.82);
  }

  .hub-page .hub-focused-heading {
    font-size: calc(1.125rem * var(--ui-font-scale, 1));
    font-weight: 600;
    letter-spacing: 0;
    color: var(--foreground);
  }

  html:not(.dark) .hub-page {
    background-color: var(--background);
  }

  html:not(.dark) .hub-page .border-b,
  html:not(.dark) .hub-page .border-r,
  html:not(.dark) .hub-page .border-t.border-border {
    border-color: color-mix(in srgb, var(--foreground) 6%, transparent);
  }

  html:not(.dark) .hub-page .hub-side-surface {
    background-color: var(--background);
  }

  html:not(.dark) .hub-page .hub-tag-soft,
  html:not(.dark) .hub-page .hub-tag-meta {
    background-color: transparent;
    transition: background-color 160ms ease, border-color 160ms ease;
  }

  html:not(.dark) .hub-page .hub-tag-soft:hover,
  html:not(.dark) .hub-page .hub-tag-meta:hover {
    background-color: color-mix(in srgb, var(--foreground) 4%, transparent);
  }

  html.dark .hub-page {
    background-color: var(--background);
  }

  html.dark .hub-page [class*="bg-card"],
  html.dark .hub-page [class*="bg-background"] {
    background-color: var(--popover);
  }

  html.dark .hub-page .border-b,
  html.dark .hub-page .border-r,
  html.dark .hub-page .border-t.border-border {
    border-color: color-mix(in srgb, var(--foreground) 5%, transparent);
  }

  html.dark .hub-page .hub-side-surface {
    background-color: transparent;
  }

  html.dark .hub-page .hub-tag-soft,
  html.dark .hub-page .hub-tag-meta {
    background-color: transparent;
    transition: background-color 160ms ease, border-color 160ms ease;
  }

  html.dark .hub-page .hub-tag-soft {
    color: var(--muted-foreground);
  }

  html.dark .hub-page .hub-tag-meta {
    color: var(--muted-foreground);
  }

  html.dark .hub-page .hub-tag-soft:hover,
  html.dark .hub-page .hub-tag-meta:hover {
    background-color: color-mix(in srgb, var(--foreground) 4%, transparent);
  }

  /* List rows share the cards' flat neutral surface: no border, no gradient,
     and a wide spread shadow that is present only in the light theme (dark gets
     the flat surface with no shadow). The shadow paints freely past the content
     column; the scroll pane (not the column) bounds it. */
  .hub-page .hub-result-row {
    border: 0;
    border-radius: 14px;
    background-color: var(--card);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
    transition:
      background-color 160ms ease,
      box-shadow 180ms ease,
      transform 180ms ease;
  }

  .hub-page .hub-result-row.hub-result-card {
    border-radius: 16px;
  }

  .hub-page .hub-result-row:hover {
    background-color: var(--card);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
  }

  html:not(.dark) .hub-page .hub-result-row:hover {
    transform: translateY(-1px);
  }

  html.dark .hub-page .hub-result-row {
    background-color: color-mix(in srgb, var(--foreground) 7%, var(--background));
    box-shadow: none;
  }

  html.dark .hub-page .hub-result-row:hover {
    background-color: color-mix(in srgb, var(--foreground) 10%, var(--background));
    box-shadow: none;
  }

  /* On-device rows reuse the result-row card but carry selection/active state:
     a neutral tint for the inspected row and a success tint with a matching
     success edge for the model currently loaded. Discover rows never set these
     attributes. */
  .hub-page .hub-result-row[data-selected="true"] {
    background-color: color-mix(in srgb, var(--foreground) 5%, var(--card));
  }

  .hub-page .hub-result-row[data-active="true"] {
    background-color: color-mix(in srgb, var(--status-success) 7%, var(--card));
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16),
      inset 2px 0 0 0 var(--status-success);
  }

  html.dark .hub-page .hub-result-row[data-selected="true"] {
    background-color: color-mix(in srgb, var(--foreground) 11%, var(--background));
    box-shadow: none;
  }

  html.dark .hub-page .hub-result-row[data-active="true"] {
    background-color: color-mix(in srgb, var(--status-success) 14%, var(--background));
    box-shadow: inset 2px 0 0 0 var(--status-success);
  }

  /* Recent-searches suggestion panel. The surface comes from
     .menu-soft-surface; these rules add the row + control hover affordances
     using the same neutral foreground mixes as the option menus and list
     rows, so it reads as part of the same family. */
  .hub-page .hub-recent-item {
    transition: background-color 120ms ease;
  }

  .hub-page .hub-recent-item:hover {
    background-color: color-mix(in srgb, var(--foreground) 6%, transparent);
  }

  html.dark .hub-page .hub-recent-item:hover {
    background-color: color-mix(in srgb, var(--foreground) 8%, transparent);
  }

  .hub-page .hub-recent-clear:hover,
  .hub-page .hub-recent-remove:hover {
    background-color: color-mix(in srgb, var(--foreground) 10%, transparent);
  }

  .hub-menu-instant {
    animation: none !important;
    transition: none !important;
    transform: none !important;
    --tw-translate-x: 0px !important;
    --tw-translate-y: 0px !important;
    --tw-scale-x: 1 !important;
    --tw-scale-y: 1 !important;
    translate: 0 0 !important;
    user-select: none;
    -webkit-user-select: none;
    will-change: auto !important;
  }

  .hub-menu-instant.menu-soft-surface {
    --menu-soft-blur: 18px;
    --menu-soft-spread: -8px;
  }

  .hub-menu-instant [data-slot="select-item"]:focus,
  .hub-menu-instant [data-slot="select-item"][data-highlighted],
  .hub-menu-instant [role="option"][data-highlighted] {
    background-color: color-mix(in srgb, var(--foreground) 6%, transparent);
    color: var(--foreground);
  }

  html.dark .hub-menu-instant [data-slot="select-item"]:focus,
  html.dark .hub-menu-instant [data-slot="select-item"][data-highlighted],
  html.dark .hub-menu-instant [role="option"][data-highlighted] {
    background-color: color-mix(in srgb, var(--foreground) 8%, transparent);
    color: var(--foreground);
  }

  html.dark .hub-menu-instant {
    background-color: #2e2f31 !important;
  }

  .hub-menu-instant *,
  .hub-menu-instant *::before,
  .hub-menu-instant *::after,
  .hub-menu-trigger,
  .hub-menu-trigger * {
    animation: none !important;
    transition: none !important;
    user-select: none;
    -webkit-user-select: none;
  }

  /* Canonical segmented-control look. Un-scoped from .hub-page so every
     segmented toggle in the app (Hub Discover/On Device, Models/Datasets,
     Unsloth/All, Recent/Name/Size, plus Settings + Train tabs) shares one
     design: a soft track with a white, softly-shadowed sliding pill. */
  html:not(.dark) .hub-tab-toggle {
    background-color: color-mix(in srgb, var(--foreground) 5%, transparent);
    border: 0;
    box-shadow: none;
  }

  html.dark .hub-tab-toggle {
    background-color: color-mix(in srgb, var(--foreground) 4.5%, transparent);
    border: 0;
    box-shadow: none;
  }

  html:not(.dark) .hub-tab-toggle-pill {
    background-color: var(--background);
    border: 0;
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
  }

  html:not(.dark) .hub-tab-toggle-pill:hover {
    background-color: #f3f3f3;
  }

  html.dark .hub-tab-toggle-pill {
    background-color: color-mix(in srgb, var(--foreground) 10%, transparent);
    border: 0;
    box-shadow: none;
  }

  html.dark .hub-tab-toggle-pill:hover {
    background-color: color-mix(in srgb, var(--foreground) 18%, transparent);
  }

  html:not(.dark) .hub-page .catalog-row {
    background-color: transparent;
    border-color: transparent;
    box-shadow: none;
    transition: background-color 160ms ease;
  }

  html:not(.dark) .hub-page .catalog-row:hover {
    background-color: color-mix(in srgb, var(--foreground) 3.5%, transparent);
  }

  html:not(.dark) .hub-page .catalog-row[data-selected="true"] {
    background-color: color-mix(in srgb, var(--foreground) 6%, transparent);
  }

  /* Currently-loaded checkpoint: a brand-green left stripe plus a faint
	   green wash, orthogonal to the neutral selected tint so a row that is
	   both loaded and selected still reads as loaded. */
  html:not(.dark) .hub-page .catalog-row[data-active="true"] {
    background-color: color-mix(in srgb, var(--status-success) 7%, transparent);
    box-shadow: inset 2px 0 0 0 var(--status-success);
  }

  html.dark .hub-page .catalog-row {
    background-color: transparent;
    border-color: transparent;
    box-shadow: none;
    transition: background-color 160ms ease;
  }

  html.dark .hub-page .catalog-row:hover {
    background-color: color-mix(in srgb, var(--foreground) 3.5%, transparent);
  }

  html.dark .hub-page .catalog-row[data-selected="true"] {
    background-color: color-mix(in srgb, var(--foreground) 7%, transparent);
  }

  html.dark .hub-page .catalog-row[data-active="true"] {
    background-color: color-mix(in srgb, var(--status-success) 12%, transparent);
    box-shadow: inset 2px 0 0 0 var(--status-success);
  }
}

@layer utilities {
  .hub-tag-soft,
  .hub-tag-meta {
    @apply min-h-[26px] rounded-full bg-muted/70 ring-1 ring-inset;
    --tw-ring-color: color-mix(in srgb, var(--foreground) 3.5%, transparent);
  }

  .dark .hub-tag-soft,
  .dark .hub-tag-meta {
    @apply bg-white/[0.05] ring-white/[0.035];
  }
  .hub-download-card {
    @apply flex w-full flex-col gap-2 rounded-[22px] p-2;
    background-color: color-mix(in srgb, var(--foreground) 3%, transparent);
    border: 1px solid color-mix(in srgb, var(--foreground) 5.5%, transparent);
    box-shadow: none;
  }

  .hub-download-card:not(:has(> :nth-child(2))) {
    border-radius: 9999px;
  }

  .dark .hub-download-card {
    background-color: color-mix(in srgb, var(--foreground) 3.5%, transparent);
    border: 1px solid color-mix(in srgb, var(--foreground) 5.5%, transparent);
    box-shadow: none;
  }

  .hub-download-panel {
    border-radius: 20px;
    background-color: var(--popover);
    border: 1px solid color-mix(in srgb, var(--foreground) 6%, transparent);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
  }

  .dark .hub-download-panel {
    border-color: color-mix(in srgb, var(--foreground) 8%, transparent);
    box-shadow: none;
  }

  .hub-download-fab {
    position: relative;
    display: inline-flex;
    width: 2.75rem;
    height: 2.75rem;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    color: var(--muted-foreground);
    background-color: var(--popover);
    border: 1px solid color-mix(in srgb, var(--foreground) 6%, transparent);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
    transition: color 150ms ease, background-color 150ms ease, box-shadow 150ms
      ease, transform 150ms ease;
  }

  .hub-download-fab:hover {
    color: var(--foreground);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
  }

  .dark .hub-download-fab {
    border-color: color-mix(in srgb, var(--foreground) 8%, transparent);
    box-shadow: none;
  }

  .dark .hub-download-fab:hover {
    box-shadow: none;
  }

  .hub-download-fab-badge {
    position: absolute;
    top: -3px;
    right: -3px;
    display: inline-flex;
    width: 1.125rem;
    min-width: 1.125rem;
    height: 1.125rem;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    padding-inline: 0;
    background-color: var(--status-success);
    color: var(--status-success-foreground);
    font-size: calc(0.65625rem * var(--ui-font-scale, 1));
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    border: 2px solid var(--popover);
  }

  .hub-page .hub-carousel {
    scrollbar-width: none !important;
    -ms-overflow-style: none !important;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }

  .hub-page .hub-carousel::-webkit-scrollbar {
    display: none !important;
    width: 0 !important;
    height: 0 !important;
  }

  .hub-page .hub-carousel-arrow {
    background-color: color-mix(in srgb, var(--background) 80%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid color-mix(in srgb, var(--foreground) 4%, transparent);
    color: var(--foreground);
    box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
    transition: opacity 160ms ease, background-color 160ms ease, border-color
      160ms ease;
  }

  .hub-page .hub-carousel-arrow:hover {
    background-color: var(--background);
    border-color: color-mix(in srgb, var(--foreground) 8%, transparent);
  }
}

@layer base {
  .hub-avatar-tile {
    /* Frame colour for the hairline drawn by ::after. Light theme keeps it a
       soft, low-contrast value that cleanly frames white logo tiles; the
       .dark override below lifts it against the dark surfaces. */
    --hub-avatar-corner-edge: color-mix(
      in srgb,
      var(--foreground) 12%,
      transparent
    );
    position: relative;
    box-shadow: none;
  }

  .hub-avatar-tile::after {
    position: absolute;
    inset: 0;
    border: 1px solid var(--hub-avatar-corner-edge);
    border-radius: inherit;
    content: "";
    opacity: 0.92;
    pointer-events: none;
    -webkit-mask:
      linear-gradient(
        90deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      top left / 82% 34% no-repeat,
      linear-gradient(
        180deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      top left / 34% 82% no-repeat,
      linear-gradient(
        270deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      bottom right / 82% 34% no-repeat,
      linear-gradient(
        0deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      bottom right / 34% 82% no-repeat;
    mask:
      linear-gradient(
        90deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      top left / 82% 34% no-repeat,
      linear-gradient(
        180deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      top left / 34% 82% no-repeat,
      linear-gradient(
        270deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      bottom right / 82% 34% no-repeat,
      linear-gradient(
        0deg,
        #000 0 38%,
        rgb(0 0 0 / 72%) 68%,
        transparent 100%
      )
      bottom right / 34% 82% no-repeat;
  }

  /* Light theme renders the frame as a single smooth hairline. The corner-mask
     "bracket" treatment (kept for the dark surfaces below) stair-steps along
     the rounded corners on light backgrounds and reads as pixelated, so it is
     dropped here in favour of a clean, anti-aliased full-perimeter ring. */
  html:not(.dark) .hub-avatar-tile::after {
    -webkit-mask: none;
    mask: none;
  }

  .dark .hub-avatar-tile {
    --hub-avatar-corner-edge: color-mix(
      in srgb,
      var(--foreground) 58%,
      transparent
    );
  }

  /* Verified badge: solid badge shape with a check-shaped hole punched
	   through, so whatever sits behind shows through the check. The badge
	   fill follows currentColor (so `text-primary` makes it Unsloth green;
	   any text-* utility recolors it). Use as: `<span class="hub-verified-badge
	   size-4 text-primary" />`. */
  .hub-verified-badge {
    display: inline-block;
    background-color: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><defs><mask id='c'><rect width='24' height='24' fill='white'/><path d='m8.75 12.5 2.5 2.5 4.25-5.25' stroke='black' stroke-width='1.85' stroke-linecap='round' stroke-linejoin='round' fill='none'/></mask></defs><path d='M8.603 3.799A4.49 4.49 0 0 1 12 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 0 1 3.498 1.307 4.491 4.491 0 0 1 1.307 3.497A4.49 4.49 0 0 1 21.75 12a4.49 4.49 0 0 1-1.549 3.397 4.491 4.491 0 0 1-1.307 3.497 4.491 4.491 0 0 1-3.497 1.307A4.49 4.49 0 0 1 12 21.75a4.49 4.49 0 0 1-3.397-1.549 4.49 4.49 0 0 1-3.498-1.306 4.491 4.491 0 0 1-1.307-3.498A4.49 4.49 0 0 1 2.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 0 1 1.307-3.497 4.49 4.49 0 0 1 3.497-1.307Z' fill='white' mask='url(%23c)'/></svg>")
      center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><defs><mask id='c'><rect width='24' height='24' fill='white'/><path d='m8.75 12.5 2.5 2.5 4.25-5.25' stroke='black' stroke-width='1.85' stroke-linecap='round' stroke-linejoin='round' fill='none'/></mask></defs><path d='M8.603 3.799A4.49 4.49 0 0 1 12 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 0 1 3.498 1.307 4.491 4.491 0 0 1 1.307 3.497A4.49 4.49 0 0 1 21.75 12a4.49 4.49 0 0 1-1.549 3.397 4.491 4.491 0 0 1-1.307 3.497 4.491 4.491 0 0 1-3.497 1.307A4.49 4.49 0 0 1 12 21.75a4.49 4.49 0 0 1-3.397-1.549 4.49 4.49 0 0 1-3.498-1.306 4.491 4.491 0 0 1-1.307-3.498A4.49 4.49 0 0 1 2.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 0 1 1.307-3.497 4.49 4.49 0 0 1 3.497-1.307Z' fill='white' mask='url(%23c)'/></svg>")
      center / contain no-repeat;
  }

  @keyframes hub-loading-sweep {
    0% {
      opacity: 0;
      transform: translate3d(-120%, 0, 0);
    }

    16% {
      opacity: 0.92;
    }

    78% {
      opacity: 0.92;
    }

    100% {
      opacity: 0;
      transform: translate3d(520%, 0, 0);
    }
  }

  .hub-loading-bar {
    pointer-events: none;
    position: relative;
    overflow: hidden;
    width: 100%;
    height: 3px;
  }

  .hub-loading-bar::after {
    content: "";
    display: none;
    position: absolute;
    inset-block: 0;
    left: 0;
    width: 36%;
    background: linear-gradient(
      90deg,
      transparent,
      color-mix(in srgb, var(--foreground) 20%, transparent),
      color-mix(in srgb, var(--foreground) 58%, transparent),
      color-mix(in srgb, var(--foreground) 20%, transparent),
      transparent
    );
    will-change: opacity, transform;
  }

  html.dark .hub-loading-bar::after {
    background: linear-gradient(
      90deg,
      transparent,
      color-mix(in srgb, var(--foreground) 22%, transparent),
      color-mix(in srgb, var(--foreground) 60%, transparent),
      color-mix(in srgb, var(--foreground) 22%, transparent),
      transparent
    );
  }

  .hub-loading-bar[data-active="true"]::after {
    display: block;
    animation: hub-loading-sweep 3s cubic-bezier(0.22, 0.72, 0.18, 1) infinite;
  }

  @media (prefers-reduced-motion: reduce) {
    .hub-loading-bar[data-active="true"]::after {
      animation-duration: 3s !important;
      animation-iteration-count: infinite !important;
    }
  }

  /* README markdown can be thousands of nodes. Keep its paint/layout work
	   scoped so unrelated overlays, like the sidebar account menu, do less
	   route-wide recalculation while the Hub is open. */
  .hub-readme-prose {
    content-visibility: auto;
    contain-intrinsic-size: auto 640px;
  }

  .hub-readme-prose > * {
    content-visibility: auto;
    contain-intrinsic-size: auto 140px;
  }

  .hub-readme-prose > hr:first-child {
    display: none;
  }

  .hub-readme-prose :is(p, div):has(> a:nth-of-type(2) > img) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
  }

  .hub-readme-prose :is(p, div):has(> a:nth-of-type(2) > img) > br {
    display: none;
  }

  .hub-readme-prose :is(p, div):has(> a:nth-of-type(2) > img) > a {
    display: inline-flex;
    align-items: center;
  }

  .hub-readme-prose :is(p, div):has(> a:nth-of-type(2) > img) img {
    margin-block: 0;
  }

  /* Inspector action pills (Download / Run / Train / Cancel) for the hub
	   inspector card. Centralized so all three sections (GGUF, safetensors,
	   datasets) stay in lock-step on type scale, padding, hover surface, and
	   the 16px icon size — mirrors the pattern used for `.sidebar-nav-btn`.
	   Width and disabled tint are layered inline by callers (some buttons
	   are w-24 in a pair, some are w-28 standalone). Raw CSS rather than
	   @apply so the cascade is explicit and predictable. */
  .hub-action-btn {
    display: inline-flex;
    height: 2.25rem;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    white-space: nowrap;
    border-radius: 9999px;
    background-color: transparent;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    font-size: calc(0.8125rem * var(--ui-font-scale, 1));
    font-weight: 500;
    line-height: calc(1.125rem * var(--ui-font-scale, 1));
    letter-spacing: -0.025em;
    color: var(--foreground);
    transition: color 150ms, background-color 150ms;
  }

  .hub-action-btn:hover:not(:disabled) {
    background-color: color-mix(in srgb, var(--foreground) 4%, transparent);
  }

  .dark .hub-action-btn:hover:not(:disabled) {
    background-color: color-mix(in srgb, var(--foreground) 5%, transparent);
  }

  .hub-action-btn:disabled {
    cursor: not-allowed;
  }

  /* Every glyph inside a hub action button — explicit icon, spinner, or
	   embedded SVG — locks to 16px so swapping icons or replacing the
	   spinner can't drift the layout. */
  .hub-action-btn svg {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
  }

  /* Primary "Run" action — confirms loading/running a model. Pill shape
	   (rounded-full) so it reads as the unmistakable CTA in a row of
	   ghost actions and matches the live-model status-success token used
	   elsewhere in the app. Same h-9 geometry, 13px
	   medium type, tracking-tight, and 16px icon slot as .hub-action-btn
	   so the height aligns with adjacent ghost buttons. */
  .hub-run-action-btn {
    display: inline-flex;
    height: 2.25rem;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    white-space: nowrap;
    border-radius: 9999px;
    background-color: var(--status-success);
    padding-left: 1rem;
    padding-right: 1rem;
    font-size: calc(0.8125rem * var(--ui-font-scale, 1));
    font-weight: 600;
    line-height: calc(1.125rem * var(--ui-font-scale, 1));
    letter-spacing: -0.025em;
    color: var(--status-success-foreground);
    transition: background-color 150ms, transform 150ms;
    box-shadow: inset 0 1px 0
      color-mix(in srgb, var(--status-success-foreground) 18%, transparent),
      0 1px 2px color-mix(in srgb, var(--status-success) 22%, transparent);
  }

  .hub-run-action-btn:hover:not(:disabled) {
    background-color: color-mix(in srgb, var(--status-success) 88%, black);
  }

  .hub-run-action-btn:active:not(:disabled) {
    transform: scale(0.98);
  }

  .hub-run-action-btn:disabled {
    cursor: not-allowed;
    opacity: 0.5;
  }

  .hub-run-action-btn svg {
    width: 0.9rem;
    height: 0.9rem;
    flex-shrink: 0;
  }

  /* Spinner-default / cancel-on-hover swap inside `.hub-action-btn`.
	   Two glyphs occupy the same 16×16 slot; the button's :hover toggles
	   their opacities so the percentage label beside them never shifts. */
  .hub-cta-indicator {
    position: relative;
    display: inline-flex;
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
  }

  /* Hover-revealed inline action overlay (used for the row-end trash on
	   downloaded models and datasets in the inspector). Wrapper 28×28 with a
	   16px glyph — same icon size as `.hub-action-btn` so the destructive
	   affordance reads consistently with the primary actions. Relies on a
	   `.group/dl` ancestor for the hover scope (the Hub download row). */
  .hub-row-action {
    position: absolute;
    right: 0.25rem;
    top: 50%;
    display: inline-flex;
    width: 1.75rem;
    height: 1.75rem;
    transform: translateY(-50%);
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    color: var(--muted-foreground);
    opacity: 0;
    cursor: pointer;
    transition: opacity 150ms, color 150ms;
  }

  .group\/dl:hover .hub-row-action,
  .hub-row-action:focus-visible {
    opacity: 1;
  }

  .hub-row-action:hover {
    color: rgb(225 29 72);
  }

  .dark .hub-row-action:hover {
    color: rgb(251 113 133);
  }

  .hub-row-action svg {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
  }
}

@layer base {
  .hub-page .field-trigger.field-filter {
    color: var(--muted-foreground);
    font-weight: 400;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
    line-height: calc(1.25rem * var(--ui-font-scale, 1));
  }

  .hub-page .field-trigger.field-filter:hover {
    color: var(--foreground);
  }

  .hub-page .hub-stat-pill {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.4rem;
    height: 2rem;
    padding-inline: 0.7rem;
    border-radius: 9999px;
    border: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
    background-color: color-mix(in srgb, var(--foreground) 2.5%, transparent);
    font-size: calc(0.75rem * var(--ui-font-scale, 1));
    line-height: 1;
    color: var(--muted-foreground);
    white-space: nowrap;
  }

  html.dark .hub-page .hub-stat-pill {
    background-color: color-mix(in srgb, var(--foreground) 4%, transparent);
  }

  .hub-page .hub-stat-pill-value {
    font-weight: 600;
    color: var(--foreground);
    font-variant-numeric: tabular-nums;
  }

  .hub-page .hub-hero {
    --hub-hero-fill: color-mix(in srgb, var(--foreground) 3.2%, transparent);
    --hub-card-border-accent: var(--foreground);
    --hub-card-edge-mix: 2.2%;
    --hub-card-inner-accent: var(--background);
    --hub-card-inner-mix: 12%;
    --hub-card-inner-opacity: 0.14;
    --hub-card-corner-mix: 8.5%;
    --hub-card-corner-opacity: 0.48;
    --hub-hero-edge: color-mix(
      in srgb,
      var(--hub-card-border-accent) var(--hub-card-edge-mix),
      transparent
    );
    --hub-hero-inner-edge: color-mix(
      in srgb,
      var(--hub-card-inner-accent) var(--hub-card-inner-mix),
      transparent
    );
    --hub-hero-corner-edge: color-mix(
      in srgb,
      var(--hub-card-border-accent) var(--hub-card-corner-mix),
      transparent
    );
    position: relative;
    overflow: hidden;
    border-radius: 24px;
    border: 1px solid transparent;
    background-color: var(--hub-hero-fill);
  }

  .hub-page .hub-hero::before,
  .hub-page .hub-hero::after {
    position: absolute;
    border-radius: inherit;
    content: "";
    pointer-events: none;
  }

  .hub-page .hub-hero::before {
    inset: 1px;
    border: 1px solid var(--hub-hero-inner-edge);
    opacity: 0;
  }

  .hub-page .hub-hero::after {
    inset: 0;
    border: 1px solid var(--hub-hero-corner-edge);
    opacity: 0;
    -webkit-mask:
      linear-gradient(
        90deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      top left / 48% 44px no-repeat,
      linear-gradient(
        180deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      top left / 44px 160px no-repeat,
      linear-gradient(
        270deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      bottom right / 48% 44px no-repeat,
      linear-gradient(
        0deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      bottom right / 44px 160px no-repeat;
    mask:
      linear-gradient(
        90deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      top left / 48% 44px no-repeat,
      linear-gradient(
        180deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      top left / 44px 160px no-repeat,
      linear-gradient(
        270deg,
        #000 0 76px,
        rgb(0 0 0 / 94%) 34%,
        rgb(0 0 0 / 58%) 76%,
        transparent 100%
      )
      bottom right / 48% 44px no-repeat,
      linear-gradient(
        0deg,
        #000 0 54px,
        rgb(0 0 0 / 68%) 86px,
        transparent 140px
      )
      bottom right / 44px 160px no-repeat;
  }

  html.dark .hub-page .hub-hero {
    --hub-hero-fill: #1c1c1c;
    --hub-card-border-accent: var(--foreground);
    --hub-card-edge-mix: 2.8%;
    --hub-card-inner-accent: var(--foreground);
    --hub-card-inner-mix: 2.5%;
    --hub-card-inner-opacity: 0.22;
    --hub-card-corner-mix: 9.5%;
  }

  .hub-page .hub-hero-panel {
    border-radius: 18px;
    border: 1px solid transparent;
    background-color: color-mix(in srgb, var(--background) 72%, transparent);
  }

  html.dark .hub-page .hub-hero-panel {
    border-color: transparent;
    background-color: #202020;
  }

  .hub-page .hub-hero-orb {
    position: absolute;
    border-radius: 9999px;
    background-color: color-mix(in srgb, var(--foreground) 4.5%, transparent);
    opacity: 0.42;
  }

  .hub-page .hub-hero-orb-accent {
    background-color: color-mix(in srgb, var(--foreground) 8%, transparent);
    opacity: 0.34;
  }

  .hub-page .hub-section-chevron {
    transition: color 150ms ease, transform 150ms ease;
  }

  .hub-page .hub-section-chevron:hover {
    color: var(--foreground);
  }

  .hub-page .hub-section-title:hover .hub-section-chevron {
    color: var(--foreground);
    transform: translateX(2px);
  }

  @media (prefers-reduced-motion: reduce) {
    .hub-page .hub-section-chevron {
      transition: none;
    }

    .hub-page .hub-section-title:hover .hub-section-chevron {
      transform: none;
    }
  }
}

@layer utilities {
  .hub-chip {
    @apply inline-flex items-center gap-1 rounded-full px-2 py-[3px] text-ui-11 font-medium leading-none;
    background-color: color-mix(in srgb, var(--foreground) 5%, transparent);
    color: var(--muted-foreground);
  }

  .dark .hub-chip {
    background-color: color-mix(in srgb, var(--foreground) 7%, transparent);
  }

  .hub-meta-tag {
    @apply inline-flex h-[18px] shrink-0 items-center gap-1 rounded-full px-2 text-ui-11 font-medium leading-none;
    background-color: color-mix(in srgb, var(--foreground) 5%, transparent);
    color: var(--muted-foreground);
  }

  .dark .hub-meta-tag {
    background-color: color-mix(in srgb, var(--foreground) 7.5%, transparent);
  }
}

html:not(.dark) .hub-page [data-hub-scroll="true"] {
  scrollbar-color: oklch(0.5 0 0 / 0.22) transparent;
}

html.dark .hub-page [data-hub-scroll="true"] {
  scrollbar-color: oklch(0.55 0 0 / 0.16) transparent;
}

html:not(.dark) .hub-page [data-hub-scroll="true"]::-webkit-scrollbar-thumb {
  background: oklch(0.5 0 0 / 0.22);
}

html.dark .hub-page [data-hub-scroll="true"]::-webkit-scrollbar-thumb {
  background: oklch(0.55 0 0 / 0.16);
}

/* While a modal dialog is open (delete confirmation, transport-mode swap, the
   folder manager) Radix locks the background: it sets body[data-scroll-locked]
   and body { pointer-events: none }. A few Hub affordances (the cached-size
   chip, the row delete button) opt back into pointer events with
   `pointer-events-auto` so they can sit above the row's full-bleed click
   overlay. That opt-in must NOT survive an open modal, or hovering the
   background fires their tooltips behind the dialog. Re-disable only those
   opt-ins while the scroll lock is active; everything else is already blocked
   by the body-level rule, and the dialog's own portaled content never carries
   this class. */
body[data-scroll-locked] .hub-modal-pe-guard {
  pointer-events: none !important;
}
