/* rmc-scrollbar.css — the one shared, token-only scrollbar stylesheet.
 *
 * Audit: audit/scrollbars_pass1.md (sections 7.1-7.4, 8, 9). Precedent:
 * static/css/rmc-section-nav.css, the first component this codebase gave a
 * single, token-only owner file instead of letting N stylesheets repaint it
 * independently.
 *
 * SCOPE: PAINT (thumb/track colour, hover/active, corner, the arrow caps --
 * on by default since 2026-10-19 -- forced-colors, reduced motion), the page scroller's gutter, and two
 * opt-in scroll utilities. It never re-selects WHICH element is the page
 * scroller -- that ownership contract stays where it already lives (audit
 * section 1.6 finding 2).
 *
 * TOKENS ONLY: every colour resolves through an existing design-tokens.css
 * custom property, already defined for all four token sets (light/dark x
 * cool/warm-neutral). No new theme block is declared here -- audit section 4.
 *
 * CHROMIUM >=121 LAYERING (audit section 7.1, corrected):
 *   `scrollbar-color`/`scrollbar-width` and `::-webkit-scrollbar*` both draw a
 *   scrollbar, and an engine that supports the standard properties stops
 *   painting the pseudo-elements ON THE SAME ELEMENT. So the two cannot be
 *   declared together on one element without the rich pill being thrown away.
 *   This file therefore:
 *     - paints the pill with `::-webkit-scrollbar*` only, and never sets
 *       `scrollbar-color`/`scrollbar-width` on the same element; and
 *     - declares the standard properties only inside
 *       `@supports not selector(::-webkit-scrollbar)`, i.e. Firefox, which is
 *       the one engine family that cannot render the pseudo-elements at all.
 *   Chromium, Edge and Safari take the pill; Firefox takes the thin standard
 *   bar. Neither branch is dead code and neither double-paints.
 *
 * CONTRAST: the resting thumb mixes the muted-text token at 62%, not the 32%
 * the audit drafted. 32% computes to 1.92:1 thumb-vs-track on the default
 * dark theme -- an invisible bar. 62% clears 3:1 on all four token sets.
 * Measured in a real browser, per shell and theme, in
 * ui_capture/scrollbars/.
 */

/* ---------------------------------------------------------------------------
 * 1. The pill -- webkit/blink engines (Chromium, Edge, Safari).
 *    `::-webkit-scrollbar*` ONLY. Nothing in this block may set
 *    `scrollbar-width` or `scrollbar-color`; see the layering note above.
 * ------------------------------------------------------------------------ */
*::-webkit-scrollbar {
  width: 11px;
  height: 11px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--admin-content-text-muted, var(--text-tertiary)) 62%, transparent);
  border-radius: 999px; /* pill */
  border: 2px solid transparent;
  background-clip: padding-box; /* the transparent border inset is what makes it read as a pill, not a full-bleed bar */
}
*::-webkit-scrollbar-thumb:hover {
  background: color-mix(in oklab, var(--admin-content-text-muted, var(--text-tertiary)) 82%, transparent);
  background-clip: padding-box;
}
/* "Currently dragging" affordance. --school-primary is a :root-only brand
 * colour that does NOT flip per theme, so it is mixed with --text-primary
 * (which does) rather than with `transparent`: brand-tinted ink, dark on a
 * light canvas and light on a dark one. */
*::-webkit-scrollbar-thumb:active {
  background: color-mix(in oklab, var(--school-primary, var(--text-primary)) 55%, var(--text-primary));
  background-clip: padding-box;
}
*::-webkit-scrollbar-corner {
  background: transparent;
}

/* Arrow caps: ON by default, on every scrollbar this stylesheet paints.
 *
 * Owner 2026-10-19: "the scroll arrows are on the sidebar but not everywhere we
 * have the vertical scroll bars". They were opt-in per element
 * (data-rmc-scrollbar-arrows="1") and NOTHING in the tree opted in, so the only
 * arrows anywhere were the floating overlay buttons
 * (static/js/rmc-scroll-arrows.js), which depend on a pane being discovered,
 * being the topmost thing at the button's position, and overflowing by more
 * than a few pixels. Those three conditions are why most bars had none.
 *
 * A scrollbar BUTTON needs none of that: it is part of the bar the engine is
 * already drawing, so every scroller gets one by construction -- and it sits in
 * the gutter rather than over content, which is what the owner asked for on
 * 2026-10-17 when the overlay landed a circle on top of the nav list.
 *
 * The glyph is a clip-path triangle in the same token as the thumb, not a
 * background-image: ::-webkit-scrollbar-button takes no children, and an SVG
 * data URI would have to carry a literal colour (which cannot follow the theme,
 * and which the off-token lint would rightly flag).
 *
 * SINGLE BUTTON PER END. Chromium draws four button slots -- decrement and
 * increment at BOTH ends -- so declaring `display: block` on the bare selector
 * puts a second, redundant pair in the middle of each end. The two
 * cross-pairings are switched off explicitly below.
 *
 * Opt a scroller out with data-rmc-scrollbar-arrows="0".
 */
*::-webkit-scrollbar-button {
  display: block;
  background-color: color-mix(in oklab, var(--admin-content-text-muted, var(--text-tertiary)) 62%, transparent);
  background-clip: padding-box;
  border: 2px solid transparent; /* same inset as the thumb, so cap and pill read as one bar */
  border-radius: 2px;
}
*::-webkit-scrollbar-button:start:increment,
*::-webkit-scrollbar-button:end:decrement,
[data-rmc-scrollbar-arrows="0"]::-webkit-scrollbar-button {
  display: none;
}
*::-webkit-scrollbar-button:vertical:decrement,
*::-webkit-scrollbar-button:vertical:increment {
  height: 11px;
}
*::-webkit-scrollbar-button:horizontal:decrement,
*::-webkit-scrollbar-button:horizontal:increment {
  width: 11px;
}
/* The triangle is behind @supports on purpose. A cap whose clip-path is ignored
   must still look deliberate, so the base rule above leaves a small inset
   square in the thumb's own colour -- the cap reads as the end of the bar
   either way, and only the glyph is lost. */
@supports (clip-path: polygon(0 0, 1px 0, 0 1px)) {
  *::-webkit-scrollbar-button:vertical:decrement {
    clip-path: polygon(50% 22%, 88% 72%, 12% 72%);
  }
  *::-webkit-scrollbar-button:vertical:increment {
    clip-path: polygon(12% 28%, 88% 28%, 50% 78%);
  }
  *::-webkit-scrollbar-button:horizontal:decrement {
    clip-path: polygon(22% 50%, 72% 12%, 72% 88%);
  }
  *::-webkit-scrollbar-button:horizontal:increment {
    clip-path: polygon(28% 12%, 78% 50%, 28% 88%);
  }
}
*::-webkit-scrollbar-button:hover {
  background-color: color-mix(in oklab, var(--admin-content-text-muted, var(--text-tertiary)) 82%, transparent);
}
*::-webkit-scrollbar-button:active {
  background-color: color-mix(in oklab, var(--school-primary, var(--text-primary)) 55%, var(--text-primary));
}

/* Denser thumb on a coarse (touch/stylus) pointer -- matches the 12-13px
 * precedent already set in rmc-app-shell.css and rmc-backoffice-scroll-10x.css
 * (audit sections 1.3, 2.2). */
@media (pointer: coarse) {
  *::-webkit-scrollbar {
    width: 13px;
    height: 13px;
  }
  *::-webkit-scrollbar-button:vertical:decrement,
  *::-webkit-scrollbar-button:vertical:increment {
    height: 13px;
  }
  *::-webkit-scrollbar-button:horizontal:decrement,
  *::-webkit-scrollbar-button:horizontal:increment {
    width: 13px;
  }
}

/* Reduced motion: only fade the thumb's hover/active change when the visitor
 * has expressed no preference against motion. */
@media (prefers-reduced-motion: no-preference) {
  *::-webkit-scrollbar-thumb {
    transition: background-color 120ms ease;
  }
}

/* ---------------------------------------------------------------------------
 * 2. The thin standard bar -- Firefox only.
 *    Guarded so these properties never land on an element that is also being
 *    painted by the pill above.
 * ------------------------------------------------------------------------ */
@supports not selector(::-webkit-scrollbar) {
  * {
    scrollbar-width: thin;
    scrollbar-color:
      color-mix(in oklab, var(--admin-content-text-muted, var(--text-tertiary)) 62%, transparent)
      transparent;
  }
}

/* ---------------------------------------------------------------------------
 * 3. Gutter -- reserved on the PAGE scroller of each shell only.
 *    Deliberately not on `*`: `scrollbar-gutter` is a layout property, and
 *    widening it to every overflow:auto box in the tree would shift the
 *    available width of all 74 sideways-scroll regions the audit inventories
 *    (section 3.1) by the bar's own width. The selectors below are exactly the
 *    page scrollers section 2 identified per shell. `scrollbar-gutter` is inert
 *    only on a box that is not a scroll container (overflow visible or clip).
 *    `overflow:hidden` -- or `overflow-x:hidden` alone, which computes
 *    overflow-y to auto -- IS one, and reserves the gutter even when nothing
 *    scrolls. So a selector listed here must be the real scroller in every
 *    mode it matches.
 * ------------------------------------------------------------------------ */
/* NOT on `html`. Measured: on every canvas-mode shell (tenant v3, operator,
 * /admin/, the immersive auth pages) `html`/`body` are overflow:hidden, and
 * `scrollbar-gutter` takes effect on a hidden box too -- so `html { stable }`
 * shrank the initial containing block by 11px and left a dead strip down the
 * right of the window that nothing painted, on three of the four shells. The
 * document only ever scrolls on public/marketing, where a long page shows the
 * bar anyway.
 *
 * NOT on `.rmc-app-shell__canvas`, for the same reason: every canvas-mode shell pins
 * it `overflow:hidden` (the canvas-body or #cp-main-content is the scroller inside it),
 * so a stable gutter there was a dead 9-11px strip between the page scrollbar and the
 * copilot rail on /super/ and both /admin/ shells -- measured, never a live bar. */
.portal-main-col,
.rmc-app-shell__canvas-body,
#cp-main-content,
#main-content {
  scrollbar-gutter: stable;
}

/* ---------------------------------------------------------------------------
 * 4. Inner-pane utility -- opt in only where a pane actually scrolls on its
 *    own (sidebar nav, drawer, modal, dropdown, chat, code).
 * ------------------------------------------------------------------------ */
.rmc-scroll-y {
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior-y: contain; /* don't chain scroll into the page behind a drawer/modal */
}

/* ---------------------------------------------------------------------------
 * 5. Horizontal-strip utility: a visible bar plus a trailing-edge fade.
 *    Replaces the "scrolls, but the bar is hidden" pattern the audit found in
 *    five components (section 3.3, section 6.2).
 * ------------------------------------------------------------------------ */
.rmc-scroll-x {
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  /* Trailing-edge hint that there is more to scroll. This is the CSS-only
   * half: it always shows. A small JS assist that sets data-rmc-scroll-end="1"
   * at the end of the strip (and data-rmc-scroll-fits="1" when it does not
   * overflow at all) is the follow-up the audit describes in §7.4; the two
   * attributes below are the contract it will drive.
   *
   * NOTE for adopters: mask-image establishes a containing block, so do NOT
   * put this class on a scroller with position:sticky children -- a table
   * wrapper with a pinned Actions column will lose the pin. Chip and tab
   * strips are what it is for. */
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 2.5rem), transparent 100%);
          mask-image: linear-gradient(to right, black calc(100% - 2.5rem), transparent 100%);
}
.rmc-scroll-x[data-rmc-scroll-end="1"],
.rmc-scroll-x[data-rmc-scroll-fits="1"] {
  -webkit-mask-image: none;
          mask-image: none;
}
/* RTL: fade the leading (left) edge instead -- the direction with more content
 * to reveal is still "forward" in reading order. Speculative: no template in
 * this tree sets dir="rtl" today (audit section 10.1 point 8). */
[dir="rtl"] .rmc-scroll-x {
  -webkit-mask-image: linear-gradient(to left, black calc(100% - 2.5rem), transparent 100%);
          mask-image: linear-gradient(to left, black calc(100% - 2.5rem), transparent 100%);
}

/* ---------------------------------------------------------------------------
 * 6. forced-colors: defer to the OS palette, don't fight it.
 *    ButtonText/Canvas are CSS system colour keywords, not literals, so they
 *    are outside the off-token lint's hex/rgb matcher (audit section 5.1).
 * ------------------------------------------------------------------------ */
@media (forced-colors: active) {
  *::-webkit-scrollbar-thumb,
  *::-webkit-scrollbar-thumb:hover,
  *::-webkit-scrollbar-thumb:active,
  *::-webkit-scrollbar-button,
  *::-webkit-scrollbar-button:hover,
  *::-webkit-scrollbar-button:active {
    background: ButtonText;
    border-color: Canvas;
  }
  *::-webkit-scrollbar-track {
    background: Canvas;
  }
  .rmc-scroll-x,
  [dir="rtl"] .rmc-scroll-x {
    -webkit-mask-image: none;
            mask-image: none;
  }
}
@supports not selector(::-webkit-scrollbar) {
  @media (forced-colors: active) {
    * {
      scrollbar-color: ButtonText Canvas;
    }
  }
}
