/* static/css/scroll.css -- Unified Scroll & Scrollbar System (BL-SCROLL-SYSTEM-EXTRACT)
 *
 * Canonical source: docs/canonical/UNIFIED_SCROLL_AND_SCROLLBAR_SYSTEM_SPECIFICATION.md
 * Raw CSS by design (sec 4.1) -- NOT Tailwind utilities (sidesteps the frozen-Tailwind
 * rebuild trap, the BL-BI lesson). Loaded on EVERY page via base.html.j2 (route a),
 * SRI-pinned like every other linked CSS.
 *
 * Token-only (sec 3.3): all colors are design-system var(--*), never raw hex, never
 * a style= attribute. The scrollbar role tokens:
 *   - thumb  var(--scroll-thumb)  -- dedicated dark-biased role, contrast-floored (sec 3.2)
 *   - track  var(--canvas-1)
 *   - hover  var(--accent-0)
 *
 * De-dup: the global scrollbar aesthetic + scrollbar-gutter + .workspace--fill were
 * LIFTED here out of workspace.css (which only workspace pages loaded). The wired
 * surface instances of sec 2.3 / sec 2.4 (.workspace__derivation flex-pin; the
 * derivation-aside :has() 35vw margin) stay in their own files until migrated per
 * sec 5 -- the generic utilities below are their systematized form.
 */

/* ===========================================================================
 * sec 3 -- dark-biased scrollbar aesthetic + sec 2.5 stable gutter, SCOPED to
 * the actual scroll owners. NOT bare-global and NOT on html for the gutter: a
 * root-level gutter reservation plus a bare ::-webkit-scrollbar (which forces
 * classic, layout-consuming scrollbars onto every nested element) collapsed the
 * workspace cockpit to half width. Scoping keeps the dark aesthetic on the pages
 * that actually scroll (fixing the prior orphaning) without restructuring the
 * nested cockpit containers.
 * =========================================================================== */

/* sec 2.5 -- stable gutter on the REAL scroll owners ONLY (never html/body). */
.page-scroll,
.workspace__primary,
.workspace__derivation {
  scrollbar-gutter: stable;
}

/* sec 3 (Firefox) -- thumb/track on the document + plain-page wrapper + panes. */
html,
body,
.page-scroll,
.workspace__primary,
.workspace__derivation {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) var(--canvas-1);
}

/* sec 3 (WebKit/Blink) -- same owner list, SCOPED (never bare). 8px matches the
 * proven pre-extract cockpit pane width; sharp corners (<=2px, sec 3.3). */
html::-webkit-scrollbar,
body::-webkit-scrollbar,
.page-scroll::-webkit-scrollbar,
.workspace__primary::-webkit-scrollbar,
.workspace__derivation::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track,
.page-scroll::-webkit-scrollbar-track,
.workspace__primary::-webkit-scrollbar-track,
.workspace__derivation::-webkit-scrollbar-track {
  background: var(--canvas-1);
}
html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb,
.page-scroll::-webkit-scrollbar-thumb,
.workspace__primary::-webkit-scrollbar-thumb,
.workspace__derivation::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 2px;
}
html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover,
.page-scroll::-webkit-scrollbar-thumb:hover,
.workspace__primary::-webkit-scrollbar-thumb:hover,
.workspace__derivation::-webkit-scrollbar-thumb:hover {
  background: var(--accent-0);
}

/* ===========================================================================
 * sec 2 -- structural pattern classes (documented opt-in utilities)
 * =========================================================================== */

/* sec 2.1 -- no nested vertical trap: wide inner elements (tables, code blocks,
 * horizontal card rows) scroll sideways only and never capture vertical drag.
 * sec 1 made into a utility; the immediate fix for the upload schema table. */
.scroll-x-only {
  overflow-x: auto;
  overflow-y: visible;
}

/* sec 2.2 -- workspace height model: the container fills its flex-determined
 * definite height (body h-screen + main flex-1 min-h-0) so the primary column
 * scrolls internally while the dock stays pinned. No calc(), no nav/footer
 * subtrahend -- the flex chain supplies the height. Ported from workspace.css. */
.workspace--fill {
  height: 100%;
}

/* sec 2.3 -- panel pin: scrollable content above fixed actions becomes a flex
 * column (pinned header, scrolling middle, pinned footer), so action buttons
 * never scroll out of view and the redundant inner "dumb" scrollbar is gone.
 * Generic utility; the wired derivation instance stays in derivation_panel.css. */
.panel--pinned {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.panel--pinned__header,
.panel--pinned__footer {
  flex-shrink: 0;
}
.panel--pinned__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* sec 2.4 -- panel-open margin: when an aside opens beside the page-scroll
 * column, reserve a right margin so the page scrollbar is not left covered (and
 * capturing drag). Generic utility keyed on a .aside-open marker; the wired
 * derivation-aside instance (its own selector + 35vw) stays in
 * derivation_panel.css until migrated. Margin/breakpoint are tunable per surface
 * (sec 2.4); the :has() pattern is fixed. */
@media (min-width: 600px) {
  .page-scroll:has(.aside-open) {
    margin-right: 35vw;
  }
}

/* RULING-THE-SCROLL-CONTAINER-IS-THE-CONTAINING-BLOCK (D423): a page-scroll
   container is the containing block for its absolute descendants (sr-only
   file inputs among them), so an absolute element can never extend the
   document past the h-screen shell and browser-initiated scrolls (focus,
   find-in-page, anchor) have no viewport overflow to scroll. */
.page-scroll { position: relative; }

/* 4ds NOTE PRT-S (1): not in print. The print view (#gsip-print-view, position absolute) sits inside the
   scroller; as its containing block the 693px scroller kept the view in one box and the PDF printed one page
   (Inputs 7 of 56). In print the containing block is the page, and the view paginates. */
@media print {
  .page-scroll { position: static; }
}

/* ===========================================================================
 * D125 amendment (MODEL_TABS sec 3.2): the global footer stays on ONE line
 * (at most 41px) at every width from 960 up. At 960 it wrapped to 69px and
 * took the view band to 397px, under the 400px floor. Here, not in
 * base.html.j2: that template is blob-pinned, and every page loads this file.
 * Step 1, spacing only: tighter gaps between the footer's two groups, the
 * freshness segments and the links.
 * =========================================================================== */
@media (min-width: 960px) {
  .app-content > footer { column-gap: 0.5rem; }
  .app-content > footer .data-freshness { column-gap: 0.375rem; }
  .app-content > footer .footer-links { column-gap: 0.75rem; }
}

/* Step 2 (spacing alone still wrapped at 960): the footer never wraps; the
 * freshness group shrinks and ends in an ellipsis, its full text kept in its
 * title attribute (data_freshness.html.j2). The Terms, Privacy Policy and
 * Security links never shrink, so they are never cut. The group becomes a
 * block (an ellipsis needs one), so its segments are spaced by margin. */
@media (min-width: 960px) {
  .app-content > footer { flex-wrap: nowrap; }
  .app-content > footer .data-freshness {
    display: block;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  .app-content > footer .data-freshness > * + * { margin-left: 0.375rem; }
  .app-content > footer .footer-links { flex-shrink: 0; }
}
