9f8d33c8b2b6bc61f6d02d781c4e02836f7099f9
max
  Fri Aug 21 02:05:42 2026 -0700
hgSession: new opt-in JavaScript "My Sessions" page; share gbModern.css with hgBlat. refs #38157

Applies the hgBlat facelift strategy (#37996) to hgSession: an opt-in,
client-rendered "My Sessions" page gated by the sessionNewPage /
sessionNewPageBanner hg.conf flags (mirroring blatNewForm / blatNewFormBanner),
with a banner linking between the classic and new pages so neither is a one-way
door. sessionNewPage also flips the site default.

hgSession.c stays the data/action backend: it emits the session list and page
config as an inline JSON global (hgSessionData) into an empty #sessionApp
container, and the new hgSession.js builds the UI - a save-current-view card
(name + optional description + "only I can load it"; empty name saves under a
random share_ name), a "most recently saved session" one-click Update, a
searchable/sortable/paged DataTable of sessions (assembly + position, created
with last-used on hover, views, a lock icon on private sessions), inline Share
(copy link / email / gallery), Edit (rename + description + private), Overwrite
and Delete, and a bulk Select -> Delete-all-selected mode.  The mutating actions
POST to new JSON endpoints (hgS_doDeleteJson / doShareJson / doGalleryJson /
doOverwriteJson / doDescribeJson) that run the same SQL as the classic full-page
handlers and return JSON, so the table updates in place; loads, file up/downloads
and custom-track backup stay as ordinary form submits/links.  The Advanced panel
keeps feature parity with the classic page (load another user's session, load
from URL/file, save to file, back up custom tracks, reset), minus the login/
change-password links that now live in the top menu.

Shared UCSC house-style components (design tokens, .gbPill, .gbCard, .gbStrip,
.gbSection, .gbShareBox, .gbBanner, the .gbModal* dialog and a .gbTable) are
factored into a new gbModern.css.  hgBlat is migrated onto it: its generic
.blat* classes are renamed to the shared .gb* names in hgBlat.css / hgBlat.js
and the #blatResults / #blatFormBox containers get class="gbApp"; verified
pixel-clean against the previous search form and results pages, including the
rename modal.  hgSession.css holds only session-specific layout.

diff --git src/hg/htdocs/style/makefile src/hg/htdocs/style/makefile
index 84cc736a001..3924540ca89 100644
--- src/hg/htdocs/style/makefile
+++ src/hg/htdocs/style/makefile
@@ -1,65 +1,66 @@
 kentSrc = ../../..
 include ../../../inc/common.mk
 
 # recursive target to do install to DEST, with extra excludes EXCL.
 
 ifeq (${FIND},)
     INSIDEGIT := $(shell git rev-parse --is-inside-work-tree 2>/dev/null)
     ifeq (${INSIDEGIT},true)
        FIND = gitFiles
     else
        FIND = find
     endif
 endif
 
 CSS_FILES=HGStyle.css assemblySearch.css autocomplete.css blueStyle.css \
     dataTables-1.10.12.min.css dataTables-1.13.6.min.css dataTables-2.2.2.min.css \
     dataTables.buttons-3.2.2.min.css dataTables.select-1.7.0.min.css \
     dataTables.select-3.0.0.min.css \
     encodeProject.css facetedComposite.css facets.css floretStyle.css gar.css \
     hgHubConnect.css hgMyData.css jquery-ui.css jquery.contextmenu.css \
     jquery.ui.autocomplete.css jquery.ui.colorPicker.css \
     jquery.treetable.css jquery.treetable.theme.default.css \
     jstree-3.3.7.min.css \
     jWest.css jWest.afterNiceMenu.css liftRequest.css mouseOver.css \
     theme-modern.css ui.dropdownchecklist.css nice_menu.css \
     encodeDataMatrix.css encodeDataSummary.css userAccounts.css \
     encode3.css encode3Ucsc.css bootstrap.min.css \
     gbStatic.css gb.css gbAfterMenu.css hgGtexTrackSettings.css hgBlat.css \
+    gbModern.css hgSession.css \
     spectrum.min.css font-awesome.min.css \
     theme-classic.css theme-dark.css theme-modern.css \
     bootstrap-3-3-7.min.css shepherd.css \
     reveal-5.1.0.css reveal-white-5.1.0.css
 
 user:
 	if test -d ${DOCUMENTROOT}-${USER}; then \
 	    ${MAKE} doInstall DEST=${DOCUMENTROOT}-${USER}/style; \
 	fi
 
 alpha:
 	${GITUP}
 	${MAKE} doInstall DEST=${DOCUMENTROOT}/style
 
 beta:
 	${GITUP} 
 	${MAKE} doInstall DEST=${DOCUMENTROOT}-beta/style extra=-forceVersionNumbers
 
 clean:
 
 compile:
 
 # Run rsync. Care is taken to preserve times and modes on files.  rsync is
 # smart about recreating files under the current users so that times and
 # permissions may be modified.  However, problems happen when a directory
 # is not owned by the current users.  These options attemp to work around it.
 # use care in changing
 rsyncOpts = --whole-file --times --recursive --omit-dir-times --relative --cvs-exclude --exclude='makefile' --exclude='cpAndLinkToResourceFiles.pl' --exclude='style/*'
 
 install:
 	${MAKE} doInstall DEST=${DOCUMENTROOT}/style
 
 doInstall:
 	@mkdir -p ${DEST}/
 	../../utils/cpAndLinkToResourceFiles.pl ${extra} -destDir=${DEST} -versionFile=../../inc/versionInfo.h ${CSS_FILES}
 	umask 002; rsync ${rsyncOpts} `$(FIND) images` ${DEST}
 	umask 002; rsync ${rsyncOpts} jstree-default ${DEST}