diff --git a/generic_assets/css/c-news--list.css b/generic_assets/css/c-news--list.css new file mode 100644 index 00000000..2540157e --- /dev/null +++ b/generic_assets/css/c-news--list.css @@ -0,0 +1,240 @@ +/* TODO: When integrated into Core-Styles, import these */ +/* @tacc/core-styles/src/lib/_imports/tools/x-article-link.css */ +/* @tacc/core-styles/src/lib/_imports/tools/x-truncate.css */ +/* _imports/tools/media-queries.css */ + + + + + +/* List */ + +/* To support rendering list as a grid */ +.c-news--list.as-grid { + display: grid; + grid-template-columns: repeat( auto-fit, minmax(350px, 1fr) ); + column-gap: var(--global-space--pattern-pad); +} +/* So page title spans all columns */ +.c-news--list.as-grid > .c-news__name { + grid-column: 1 / -1; +} + + + + + +/* Item */ + + + +/* Item (Structure) */ + +/* For basic layout */ +.c-news--list article { + display: grid; + + border-bottom: var(--global-border-width--normal) solid var(--global-color-primary--dark); + margin-bottom: var(--article-buffer); + padding-bottom: var(--article-buffer); +} +.c-news--list .c-news__header { grid-area: head } +.c-news--list .c-news__visual { grid-area: media } +.c-news--list .c-news__abstract { grid-area: desc } + +/* For conditional layouts */ +.c-news--list:not(.has-media) article { + --grid-item-areas: + 'head' + 'desc'; + + --list-item-areas: + 'head' + 'desc'; + /* Do not manage what is irrelevant in this layout */ + --list-item-columns: none; +} +.c-news--list.has-media article { + --grid-item-areas: + 'media' + 'head' + 'desc'; + + --list-item-areas: + 'media head' + 'media desc'; + /* To shrinkwrap media and flexible text content */ + --list-item-columns: minmax(0, max-content) 1fr; + + column-gap: 50px; /* for horz. space between image and content */ +} + +/* For layout options */ +.x-news-grid-item { + grid-template-areas: var(--grid-item-areas); + /* To prevent content from overflowing cell */ + grid-template-columns: minmax(0, 1fr); + /* To prevent vertical stretch of rows */ + grid-auto-rows: min-content; +} +.x-news-list-item { + grid-template-areas: var(--list-item-areas); + grid-template-columns: var(--list-item-columns); + /* To let 'desc' take remaining space (removes gap between head and desc) */ + grid-template-rows: min-content 1fr; +} +@media (width < 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--list article { + /* TODO: When in Core, use @extend */ + /* @extend .x-news-grid-item; */ + grid-template-areas: var(--grid-item-areas); + /* To prevent content from overflowing cell */ + grid-template-columns: minmax(0, 1fr); + /* To prevent vertical stretch of rows */ + grid-auto-rows: min-content; + } +} +@media (width >= 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--list:not(.as-grid) article { + /* TODO: When in Core, use @extend */ + /* @extend .x-news-list-item; */ + grid-template-areas: var(--list-item-areas); + grid-template-columns: var(--list-item-columns); + /* To let 'desc' take remaining space (removes gap between head and desc) */ + grid-template-rows: min-content 1fr; + } + .c-news--list.as-grid article { + /* TODO: When in Core, use @extend */ + /* @extend .x-news-grid-item; */ + grid-template-areas: var(--grid-item-areas); + /* To prevent content from overflowing cell */ + grid-template-columns: minmax(0, 1fr); + /* To prevent vertical stretch of rows */ + grid-auto-rows: min-content; + } +} + + + + + + +/* Header */ + + + +/* Header (Structure) */ + +.c-news--list .c-news__header { + margin-bottom: 5px; +} + + + +/* Header - Title */ + +.c-news--list .c-news__title { + margin-bottom: unset; /* overwrite Core-Styles headings--cms.css */ +} +.c-news--list .c-news__subtitle { + display: none; +} + +/* To style a pill (e.g. "Update" pill in a title) */ +.c-news--list .c-pill:not(:first-child) { + margin-left: 0.5ch; +} + + + +/* Header - Metadata (Skin) */ + +.c-news--list .c-news__data li { + line-height: unset; /* overwrite html-elements.css */ +} + +.c-news--list .c-news__attr { + color: var(--global-color-primary--dark); +} +.c-news--list .c-news__attr a { + color: inherit; +} + + + + + +/* Visual */ + +.c-news--list .c-news__media:empty { + display: none; +} + +/* To support vertical article layouts */ +/* FAQ: In simple layouts, the media element is the grid cell */ +/* FAQ: In complex layouts, the media element is within the grid cell */ +.x-news-grid-item-media-cell { + margin-bottom: 15px; /* to add space between image and content */ +} +.x-blog-grid-item-media-element-in-cell { + max-width: 100%; /* to prevent overflow if column is narrower than image */ + height: auto; /* to preserve ratio if width is reduced (by max-width: 100%) */ +} +@media (width < 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--list .c-news__media { + /* TODO: When in Core, use @extend */ + /* @extend .x-blog-grid-item-media-cell; */ + margin-bottom: 15px; /* to add space between image and content */ + & img { + /* TODO: When in Core, use @extend */ + /* @extend .x-blog-grid-item-media-element-in-cell; */ + max-width: 100%; /* to prevent overflow if column is narrower than image */ + height: auto; /* to preserve ratio if width is reduced (by max-width: 100%) */ + } + } +} +@media (width >= 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--list.as-grid .c-news__media { + /* TODO: When in Core, use @extend */ + /* @extend .x-blog-grid-item-media-cell; */ + margin-bottom: 15px; /* to add space between image and content */ + & img { + /* TODO: When in Core, use @extend */ + /* @extend .x-blog-grid-item-media-element-in-cell; */ + max-width: 100%; /* to prevent overflow if column is narrower than image */ + height: auto; /* to preserve ratio if width is reduced (by max-width: 100%) */ + } + } +} + + + + + +/* Content */ + +.c-news--list .c-news__abstract { + /* TODO: When in Core, use @extend */ + /* @extend %x-truncate--many-lines; */ + --lines: 2; + + display: -webkit-box; + -webkit-box-orient: vertical; + + overflow: hidden; + -webkit-line-clamp: var(--lines); + + --lines: 4; + + line-height: 1.5; + color: var(--global-color-primary--dark); +} +.c-news--list .c-news__abstract p:last-child { + margin-bottom: 0 /* overwrite core-styles.cms */ +} + +/* To undo inline content styles */ +/* FAQ: In case author pasted such markup from another source */ +.c-news--list .c-news__abstract [style] { + all: revert !important; /* force undo all inline styles */ +} diff --git a/generic_assets/css/c-news--read.css b/generic_assets/css/c-news--read.css new file mode 100644 index 00000000..a840366c --- /dev/null +++ b/generic_assets/css/c-news--read.css @@ -0,0 +1,171 @@ +/* TODO: When integrated into Core-Styles, import these */ +/* @tacc/core-styles/src/lib/_imports/objects/o-offset-content.css */ +/* @tacc/core-styles/src/lib/_imports/tools/x-figure.css */ +/* @tacc/core-styles/src/lib/_imports/tools/x-blockquote.css */ + + + + + +/* Root */ + +.c-news--read article { + --header-buffer: calc( var(--global-space--grid-gap) / 2 ); + + max-width: 775px; + margin-inline: auto; +} + + + + + +/* Header (Structure) */ + +.c-news--read .c-news__header { + grid-template-areas: + 'head head' + 'subh subh' + 'cats link' + 'tags tags' + 'attr attr'; +} +.c-news--read .c-news__title, +.c-news--read .c-news__subtitle { + margin-bottom: var(--header-buffer); +} +.c-news--read .c-news__title { + font-size: var(--global-font-size--xxx-large); + + border-bottom: var(--global-border-width--normal) solid var(--global-color-primary--dark); +} +.c-news--read .c-news__subtitle { + font-weight: normal; + font-size: var(--global-font-size--large); +} + + + + + +/* Media & Content */ + +.c-news--read .c-news__media, +.c-news--read .c-news__content { + --news-read-media-buffer: 45px; + + margin-block: var(--news-read-media-buffer) 60px; +} + +/* To undo inline content styles */ +/* FAQ: In case author pasted such markup from another source */ +.c-news--read .c-news__content [style]:not( + [data-style="admin"], /* HACK: So CMS admin can override this */ +) { + all: revert !important; /* force undo all inline styles */ +} + + + +/* Media & Content - Media */ + +/* To mimic Bootstrap `.img-fluid` */ +.c-news--read img.c-news__media /* WARNING: Untested */, +.c-news--read .c-news__media img { + max-width: 100%; + height: auto; +} +/* To support vertical layouts at narrow viewports */ +@media (width < 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--read .c-news__media { + display: grid; + justify-content: center; + margin-bottom: var(--news-read-media-buffer); + } +} +/* To support horizontal layouts at wide viewports */ +@media (width >= 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--read .c-news__media { + float: left; + margin-right: var(--news-read-media-buffer); + } +} + +/* To prevent footer on right side of page */ +/* FAQ: Because of `.c-news--read .c-news__media`'s `float: left` */ +.c-news--read .c-news__media + .c-news__content::after { + /* from Bootstrap `clearfix` */ + display: block; + content: ""; + clear: both; +} + + + +/* Media & Content - Content */ + +/* FAQ: Read page CAN have abstract */ +/* https://github.com/TACC/Core-CMS/pull/594 */ +.c-news--read .c-news__abstract, +.c-news--read .c-news__content { + font-size: var(--global-font-size--medium); + line-height: 2; +} +/* Add space between all list items */ +/* FAQ: Use case is list items with as much text as a paragraph */ +.c-news--read .c-news__abstract li + li, +.c-news--read .c-news__content li + li { + margin-top: 0.5em; +} + +/* To reduce space between "Original Message" and its content */ +.c-update__header + .c-news__content { + margin-top: unset; /* ovewrite c-news--read.css */ +} + + + +/* Media & Content - Alignment */ +/* FAQ: The .align-... classes come from Bootstrap Picture */ +/* FAQ: The .blockquote.text-... classes come from Bootstrap Blockquote */ + +.c-news--read .c-news__content .align-left { + /* TODO: When in Core, use @extend */ + /* @extend .o-offset-content--left; */ + /* NOTE: Ignore in TUP-CMS, cuz c-news only for User Updates (no images) */ +} +.c-news--read .c-news__content .align-right { + /* TODO: When in Core, use @extend */ + /* @extend .o-offset-content--right; */ + /* NOTE: Ignore in TUP-CMS, cuz c-news only for User Updates (no images) */ +} + +/* To remove margin on narrow screens */ +/* To overwrite @tacc/core-styles/…/components/align.css */ +@media (width < 768px) /* TODO: When in Core, use @custom-media */ { + .c-news--read .c-news__content .align-center, + .c-news--read .c-news__content .align-right, + .c-news--read .c-news__content .align-left { + max-width: unset; + } + .c-news--read .c-news__content .align-right, + .c-news--read .c-news__content .align-left { + float: unset; + margin-bottom: unset; + } + .c-news--read .c-news__content .align-right { + margin-left: unset; + } + .c-news--read .c-news__content .align-left { + margin-right: unset; + } +} + +/* To reduce image width on medium screens */ +@media (width < 768px) and (width < 992px) /* TODO: When in Core, use @custom-media */ { + .c-news--read .c-news__content .align-center, + .c-news--read .c-news__content .align-right, + .c-news--read .c-news__content .align-left { + max-width: 50%; + } +} diff --git a/generic_assets/css/c-news.css b/generic_assets/css/c-news.css new file mode 100644 index 00000000..33535d75 --- /dev/null +++ b/generic_assets/css/c-news.css @@ -0,0 +1,124 @@ +/* TODO: When integrated into Core-Styles, import these */ +/* @tacc/core-styles/src/lib/_imports/components/c-tag.css */ + +@import url("./c-news--read.css"); +@import url("./c-news--list.css"); + + + + + +/* Variables */ + +.c-news { + --article-buffer: 20px; +} + + + +/* Generic */ + +.c-news { + /* To control absolute position of descendants e.g. `.blog-visual` */ + position: relative; +} + +/* TODO: Share styles between c-news and c-feed-list (`time:not(…)`) */ +.c-news article time:not(:is(h1, h2, h3, h4, h5, h6) *) { + color: var(--global-color-secondary--normal); + font-weight: var(--medium); + text-transform: uppercase; +} + + + + + +/* Header */ + +.c-news__header { + display: grid; + grid-template-areas: + 'cats' + 'tags' + 'attr' + 'head' + 'subh'; +} +.c-news__title { grid-area: head } +.c-news__subtitle { grid-area: subh } +.c-news__attr { grid-area: attr } +.c-news__cats { grid-area: cats } +.c-news__tags { grid-area: tags } + +.c-news__data { + list-style: none; + + padding-left: 0; /* overwrite html-elements.css */ + margin-bottom: 0.25em; /* overwrite html-elements.css */ + + font-size: var(--global-font-size--medium); +} + + + +/* Metadata */ + +/* To layout data */ +.c-news__attr, +.c-news__tags, +.c-news__cats { + display: flex; + flex-direction: row; + gap: 1em; +} +.c-news__attr { + justify-content: space-between; +} +.c-news__date { + order: -1 +} + +/* To conditionally hide tags & categories */ +.c-news.no-tags .c-news__tags, +.c-news.no-categories .c-news__cats { + display: none; +} + +/* To hide empty tags & categories */ +.c-news__tags:empty, +.c-news__cats:empty { + display: none; +} + +/* To style categories as "tags" (the UI pattern) */ +.c-news__cats a { + /* TODO: When integrated into Core-Styles, uncomment this */ + /* @extend :--c-tag; */ + + display: inline-block; + + color: var(--global-color-primary--xx-light); + background-color: var(--global-color-primary--xx-dark); + + font-size: var(--global-font-size--x-small); +} + +/* To style tags as "pills" (the UI pattern) */ +.c-news__tags a { + /* TODO: When available in Core-Styles, uncomment this */ + /* @extend :--c-pill; */ + + background-color: var(--global-color-primary--light); +} + +/* So byline text is all on one line */ +.c-news__data address { + display: inline; +} + +/* To style a pill (e.g. "Update" pill in a title) */ +.c-news .c-pill { + vertical-align: middle; + transform: translateY(-0.125em); +} diff --git a/generic_assets/css/core-styles-feats.css b/generic_assets/css/core-styles-feats.css new file mode 100644 index 00000000..51b86e77 --- /dev/null +++ b/generic_assets/css/core-styles-feats.css @@ -0,0 +1,2 @@ +/* TODO: Integrate into Core-Styles */ +@import url("./c-news.css") layer(base); diff --git a/tup/README.md b/tup/README.md new file mode 100644 index 00000000..5276986c --- /dev/null +++ b/tup/README.md @@ -0,0 +1,13 @@ +# Purpose + +Custom assets for [TUP](https://github.com/TACC/tup-ui), migrated out of tup-ui's `apps/tup-cms/src/taccsite_custom/tup_cms/static/tup_cms/` so other projects can discover and reuse them. + +## Status + +Migration in progress, tracked across sub-PRs: + +- `html/` — djangocms-snippet reference copies (done) +- `css/ad-hoc/`, `js/ad-hoc/` — ad-hoc CSS/JS assets loaded by the ad-hoc snippets (done) +- `css/cms.css` + `css/_imports/`, `img/logo-*.svg` — assets from tup-ui's `for-tup-cms/` (done) +- tup-ui's `for-core-cms/` and `for-core-styles/` remainders were dead/superseded, not migrated +- `s-breadcrumbs.css`/`breadcrumbs.js` were not migrated — Core-CMS already covers 2nd-crumb de-linking (`nav_cms_breadcrumbs.html`); tup-ui's copies are headed for deletion (tup-ui#535), not upstreaming diff --git a/tup/css/_imports/components/agenda-table.css b/tup/css/_imports/components/agenda-table.css new file mode 100644 index 00000000..05d64729 --- /dev/null +++ b/tup/css/_imports/components/agenda-table.css @@ -0,0 +1,40 @@ +/* FAQ: Used on https://www.tacc.utexas.edu/events/institutues/sample/ */ + +/* FAQ: To support as Black */ +/* TODO: If this is needed, add each to Core Styles as appropriate */ +/* SEE: src/lib/_imports/settings/font.css Roboto @import */ +@import url('https://fonts.googleapis.com/css?family=Roboto:900&display=swap'); +.agenda-table { --black: 900; } + +/* TODO: Implement in core-styles.cms.css as s-agenda-table aka agenda-table */ +.agenda-table time { + font-family: var(--global-font-family--mono); + display: block; /* so text-align is effectual */ + text-align: right; +} +.agenda-table p:not(:last-child) { + margin-bottom: 0.25em; +} +.agenda-table :is(td, th):first-child { + border-right: var(--global-border-width--normal) solid var(--global-color-primary--dark); +} +.agenda-table :is(td, th):nth-child(2) { + text-align: center; +} + +.agenda-table :is(td, th):not([class*="agenda-table__"]) { + background: transparent; +} +.agenda-table__neutral +/* FAQ: Phasing out "primary" misnomer by not propogating it */ { + background: var(--global-color-primary--x-light); +} +.agenda-table__accent { + background: var(--global-color-accent--xxx-light); +} +[class*="agenda-table__secondary"] { + background: var(--global-color-secondary--xx-light); +} +.agenda-table__tertiary { + background: var(--global-color-tertiary--xx-light); +} diff --git a/tup/css/_imports/components/banner.css b/tup/css/_imports/components/banner.css new file mode 100644 index 00000000..31f1cb6e --- /dev/null +++ b/tup/css/_imports/components/banner.css @@ -0,0 +1,190 @@ +/* TODO: Support .c-banner-cell */ + + + + +/* Banner Cell */ + +[class*="banner-cell--"] { + --tag-padding: 0.5rem; /* manually copied from .c-tag styles */ +} + +/* Elements */ + +[class*="banner-cell--"] :where(h1, h2, h3, h4) { + margin-bottom: 0; +} + +/* So image caption heights are equal (not an issue on narrow screen) */ +@media (width >= 576px) { + [class*="banner-cell--"] > a { + height: 100%; + display: block; + } +} + +/* FAQ: Using after so outline is on top of mix-blend-mode (see .o-colorize) */ +[class*="banner-cell--"] > a { position: relative; } +[class*="banner-cell--"] > a:hover::after { + --border-width: var(--global-border-width--thick); + + /* FAQ: Using `border` shrinks content while `outline` does not */ + outline-width: var(--border-width); + outline-style: solid; + outline-color: var(--global-color-primary--xxx-dark); + outline-offset: calc( -1 * var(--border-width) ); + + /* So ::after stretches to fill parent */ + content: ''; + display: block; + position: absolute; + left: 0; top: 0; bottom: 0; right: 0; +} +[class*="banner-cell--"] > a:active { + --border-width: var(--global-border-width--normal); +} + +[class*="banner-cell--"] figure { + margin-bottom: unset; /* undo core-cms.css and Bootstrap */ +} + +[class*="banner-cell--"] figcaption { + padding-inline: 3.0rem; +} + +/* To remove standard link text docoration */ +[class*="banner-cell--"] > a { + text-decoration: none; +} + +/* To cover a re-sized image box with the full-size image (like a bkgd image) */ +/* FAQ: If user sets dimension via style, we assume they want this feature */ +[class*="banner-cell--"] figure:where([style*="height"], [style*="width"]) img { + object-fit: cover; + height: 100%; + width: 100%; +} + +/* Components */ + +[class*="banner-cell--"] .c-tag, +[class*="banner-cell--"] [class*="tag--"] { + display: block; + margin-bottom: 2.0rem; +} + +[class*="banner-cell--"] .u-highlight { + padding-inline: var(--tag-padding); + + color: var(--global-color-primary--xx-light); + background-color: var(--global-color-primary--xxx-dark); + + line-height: 1; +} + + +/* Banner Cell (Major) */ + +/* To allow image to be underneath text */ +.banner-cell--major figure { + display: grid; + + /* To force % image height to match its container (i.e.
) */ + /* https://stackoverflow.com/a/52137966/11817077 */ + grid-template-rows: minmax( 0, 1fr ); +} + +.banner-cell--major h2 { + font-size: var(--global-font-size--xxx-large); + font-weight: var(--bold); + + text-transform: uppercase; +} + +/* To move text atop image */ +.banner-cell--major img, +.banner-cell--major figcaption { + grid-row: 1; + grid-column: 1; +} +.banner-cell--major figcaption { + align-self: end; /* to align text to bottom */ +} + +/* To showcase image more on mobile and not let tag be flush against header */ +@media (width < 576px) { + .banner-cell--major figcaption { + margin-top: 6rem; + margin-bottom: 8rem; + } +} +@media (width >= 576px) { + .banner-cell--major figcaption { + margin-top: 3.5rem; + margin-bottom: 5rem; + } +} + + + +/* Banner Cell (Minor) */ + +/* To space out cells */ +@media (width < 576px) { + .banner-cell--minor { + margin-top: calc( var(--global-space--bootstrap-gap) / 2 ); + } + .banner-cell--minor:last-child { + margin-bottom: calc( var(--global-space--bootstrap-gap) / 2 ); + } +} +@media (width >= 576px) { + .banner-cell--minor { + margin-block: var(--global-space--bootstrap-gap); + } +} + +/* To allow image to be underneath text */ +.banner-cell--minor figure { + display: grid; + + /* To make image and caption fill, but also fit within, grid */ + grid-template-rows: auto 1fr; + grid-template-columns: minmax( 0, 1fr ); +} + +/* To add space under caption text within container */ +.banner-cell--minor figcaption { + padding-bottom: 3.0rem; +} + +.banner-cell--minor h2 { + color: var(--global-color-primary--xxx-dark); /* undo core-styles.cms */ + font-weight: revert; +} + +/* To move text atop image */ +.banner-cell--minor figcaption { + /* To move by half the height of the .c-tag */ + /* FAQ: Not using `translateY(-50%)` because h2 must move same amount */ + --offset: calc( var(--tag-padding) + ( var(--global-font-size--small) / 2 ) ); + + /* FAQ: Using variable so styles that extend this can use the value */ + margin-top: calc( -1 * var(--offset) ); +} + + + + + +/* Conflicts with Core-CMS */ + +/* Overwrite Core-CMS core-cms.css */ +/* HELP: How can all CMS sites avoid this? */ +[class*="banner-cell--"] figcaption { + border-bottom: unset; + color: unset; + font-size: unset; + font-style: normal; + line-height: inherit; +} diff --git a/tup/css/_imports/components/banner.html b/tup/css/_imports/components/banner.html new file mode 100644 index 00000000..85b22353 --- /dev/null +++ b/tup/css/_imports/components/banner.html @@ -0,0 +1,56 @@ + + \ No newline at end of file diff --git a/tup/css/_imports/components/banner.md b/tup/css/_imports/components/banner.md new file mode 100644 index 00000000..92e7e10b --- /dev/null +++ b/tup/css/_imports/components/banner.md @@ -0,0 +1,3 @@ +A list of article previews. + +> **⚠️ Warning**: Styles are heavily dependent on the tags in the sample markup. diff --git a/tup/css/_imports/components/c-data-list.css b/tup/css/_imports/components/c-data-list.css new file mode 100644 index 00000000..d5926536 --- /dev/null +++ b/tup/css/_imports/components/c-data-list.css @@ -0,0 +1,15 @@ +/* SEE: https://dev.tup.tacc.utexas.edu/systems/frontera/ */ + +table[class*="data-list--"] { + /* TODO: Consider this for all tables */ + margin-bottom: 40px; +} +table[class*="data-list--"] :is(th, td) { + background: unset; +} +table[class*="data-list--"] th { + font-weight: var(--black); /* undo core-styles.base table */ +} +table[class*="data-list--"] td { + color: unset; /* undo core-styles.base table */ +} diff --git a/tup/css/_imports/components/c-footer.css b/tup/css/_imports/components/c-footer.css new file mode 100644 index 00000000..da810969 --- /dev/null +++ b/tup/css/_imports/components/c-footer.css @@ -0,0 +1,239 @@ +/* BUTTONS */ + +/* To style buttons differently than in body */ +.c-footer .c-button, +.c-footer [class*="button--"] { + & small { + font-size: var(--global-font-size--x-small); + } +} + + + + + +/* LOGOS */ + +/* To set baseline styles for footer logos */ +/* TODO: Evaluate for tup-ui or core-cms CSS */ +.c-footer svg { + fill: var(--global-color-primary--xx-light); +} +.c-footer [class*="logos--"] { + display: grid; + gap: var(--gap, 0); + grid-auto-flow: column; + justify-content: center; +} +.c-footer .logos--branding { + --gap: 2rem; + + /* NOTE: Test any changes on all browsers and screen sizes */ + grid-template-columns: repeat( 3, minmax(0, 1fr) ); +} +.c-footer .logos--branding a { + min-height: 60px; + max-height: 120px; +} + +.c-footer [class*="logos--"] a { + display: inline-flex; + align-items: center; + justify-content: center; /* horz align when image narrower than grid cell */ +} + +/* For independent logo sizes */ +.c-footer .logos--branding svg { + height: 55%; +} +.c-footer .logos__tacc svg { + /* To vertically align center as if small text was not present */ + transform: translateY(5%); +} +.c-footer .logos__ut svg { + /* To vertically align center as if small text was not present */ + transform: translateY(5%); +} + +/* To create fake border between logos */ +.c-footer [class*="logos--"] a { position: relative } +.c-footer .logos--branding a:not(:first-child)::before { + height: 75%; + + position: absolute; + left: calc( -1 * var(--gap)/2 ); + + content: ''; + display: block; + background-color: var(--global-color-primary--xx-light); + background-clip: content-box; + width: var(--global-border-width--normal); + box-sizing: content-box; + + cursor: default; +} + +/* To skin logo links */ +.c-footer [class*="logos--"] a { + &:hover { + color: inherit; + } + &:hover svg { + color: currentColor; + outline: var(--global-border-width--normal) solid currentColor; + outline-offset: 5px; + border-radius: var(--global-border-width--normal); + } + &:active svg { + outline-style: dotted; + } +} +.c-footer .logos--social a { + padding: 0.5em; +} +.c-footer .logos--social svg { + font-size: 2.5rem; +} + + +/* HACK: To undo tricky Instagram hover color */ +.c-footer .logos--social a.logos__instagram:hover { + mask: unset; + background: unset; +} +.c-footer .logos--social a.logos__instagram:hover svg { + visibility: visible; +} + + + + + +/* LAYOUT */ + + + +/* LAYOUT - All Screens */ + +.c-footer { + --pad-vert: 36px; + --pad-horz: 36px; +} + + +/* LAYOUT - Narrow Screen */ + +/* Move all panes to one column */ +@media (width < 380px) { + #cms-footer .col { + /* FAQ: I copied Bootstrap .col-6 styles and changed 50% to 100% */ + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } +} + + + + +/* LAYOUT - Wide Screen */ + +/* To draw a line between "Quick Links" and regular links */ +@media (width > 380px) { + #cms-footer .c-pane--aside { + border-left: var(--global-border-width--normal) solid var(--global-color-primary--xx-light); + } +} + +/* To draw a box behind common footer content */ +/* FAQ: The box stretches to cover the height and right side of the footer */ +@media (width >= 992px) { + #cms-footer .c-pane--common { + /* To move c-footer vertical padding into this pane */ + margin-block: calc( -1 * var(--pad-vert) ); + padding-block: var(--pad-vert); + + background-color: var(--global-color-primary--x-dark); + } + html:not(#page-portal) .c-footer { + padding-right: revert; /* undo core-styles.cms.css */ + } + #cms-footer .c-pane--common { + padding-inline: var(--pad-horz); + } + #cms-footer.row:not(.no-gutters) { + margin-right: 0; + } +} + + + + + +/* PER CLIENT */ + + +/* PER CLIENT - HIDE/SHOW */ + +/* To hide/show CMS/Portal footer */ +html#page-portal #cms-footer, /* new id */ +html:not(#page-portal) #portal-footer /* trans id */ { + display: none; +} + +/* PER CLIENT - PORTAL */ + +html:not(#page-portal) .c-footer { + /* To add a full-width border above CMS footer */ + /* TODO: Evaluate for tup-ui or Core-CMS CSS */ + border-width: var(--global-border-width--thick) 0 0 0; + border-style: solid; + border-color: var(--global-color-secondary--light); + + /* To remove padding-block on CMS footer */ + padding-block: unset; +} + +/* To reduce size of Portal footer */ +html#page-portal .c-footer { + --pad-vert: 0; + --pad-horz: 15px; /* WARNING: any less causes unexplained scrollbar */ +} +html#page-portal .c-footer p { + margin-bottom: revert; /* undo Bootstrap */ +} + +/* To vertically center text */ +#portal-footer p { + margin-block: revert; /* undo Bootstrap */ +} + + + +/* PER CLIENT - CMS */ + +/* To move footer padding into CMS footer */ +#cms-footer { + padding-block: var(--pad-vert); +} + +/* Add vertical space between panes, except for aside when it is below others */ +/* FAQ: Bootstrap 4 grid does not have a way to do so */ +#cms-footer .col.c-pane--nav { + margin-bottom: 2rem; +} + +/* To make text color match on regular text and hyperlinks */ +#cms-footer .c-pane--common, +#cms-footer .c-pane--common a { + color: var(--global-color-primary--xx-light); +} +#cms-footer .c-pane--common a { + text-decoration-line: underline; + text-decoration-color: var(--global-color-primary--dark); + + &:hover { + text-decoration-color: inherit; + } +} diff --git a/tup/css/_imports/components/c-news.css b/tup/css/_imports/components/c-news.css new file mode 100644 index 00000000..7a3a3cb3 --- /dev/null +++ b/tup/css/_imports/components/c-news.css @@ -0,0 +1,14 @@ +/* To adjust display of metadata (given what .c-update shows) */ +.c-news--read article.has-update .c-news__data { + display: none; +} +.c-news--read article.has-update .c-news__title { + /* Overwrites c-news--read.css */ + border-bottom: unset; + margin-bottom: 6.5rem; +} + +/* To hide byline on User Updates */ +.c-news__byline:not(.app-blog *) { + display: none; +} diff --git a/tup/css/_imports/components/c-tag.css b/tup/css/_imports/components/c-tag.css new file mode 100644 index 00000000..70a2b3e4 --- /dev/null +++ b/tup/css/_imports/components/c-tag.css @@ -0,0 +1,63 @@ +.c-tag, +[class*="tag--"] { + display: block; + margin-bottom: 2.0rem; + + color: var(--global-color-primary--xx-light); + + font-size: var(--global-font-size--small); +} + +/* Press Release */ +[class*="tag--pr"], +/* To overwrite core-cms django.cms.blog.app.css */ +.app-blog .categories a:is( + .blog-category-press-release +) { + background: #723B0C; +} + +/* Q&A, Human Interest */ +[class*="tag--qa"], +/* To overwrite core-cms django.cms.blog.app.css */ +.app-blog .categories a:is( + .blog-category-qa, + .blog-category-welcome-profile, + .blog-category-staff-highlight +) { + background: var(--global-color-accent--light); +} + +/* Has Video, Audio, or other media beyond statc image */ +[class*="tag--media"], +/* To overwrite core-cms django.cms.blog.app.css */ +.app-blog .categories a:is( + .blog-category-podcast, + .blog-category-multimedia +) { + background: var(--global-color-primary--dark); +} + +/* System Status Update */ +[class*="tag--system"] { + background: var(--global-color-tertiary--normal); +} + +/* Feature Story (different than a "featured" article) */ +[class*="tag--feature"], +/* To overwrite core-cms django.cms.blog.app.css */ +.app-blog .categories a:is( + .blog-category-feature-story +) { + background: var(--global-color-accent--normal); +} + +/* External Article */ +[class*="tag--external"] { + background: var(--global-color-secondary--normal); +} + +/* Event */ +[class*="tag--event"] { + background: var(--global-color-tertiary--dark); +} diff --git a/tup/css/_imports/components/c-update.css b/tup/css/_imports/components/c-update.css new file mode 100644 index 00000000..1bded943 --- /dev/null +++ b/tup/css/_imports/components/c-update.css @@ -0,0 +1,21 @@ +/* To style "Update" pill in title */ +.c-update__title .c-pill { + vertical-align: middle; + transform: translateY(-0.125em); +} +.c-update__title .c-pill:not([class*="c-pill--"]) { + background-color: var(--global-color-primary--light); +} + +/* To reduce space between "Original Update" and its content */ +.c-update__header + .c-news__content { + margin-top: unset; /* ovewrite c-news--read.css */ +} + +/* To tweak hr appearance and layout */ +.c-update + hr { + border-top-color: var(--global-color-priamry--dark); + + /* To make line between updates darker and have equal space above and below */ + margin-top: var(--global-space--hr-buffer-below); +} diff --git a/tup/css/_imports/components/c-widget.css b/tup/css/_imports/components/c-widget.css new file mode 100644 index 00000000..5016037f --- /dev/null +++ b/tup/css/_imports/components/c-widget.css @@ -0,0 +1,20 @@ +/* FAQ: Used on homepage to mimic `c-feed` style (User Updates) heading */ +/* SEE: https://dev.tup.tacc.utexas.edu/ */ + +/* TODO: Consider 1 pattern for styles shared between c-feed-list & c-widget */ + +/* !!!: Clones corresponding .c-feed-list syle */ +.c-widget > :is(h1, h2, h3, h4, h5, h6) { + margin-top: 0; + margin-bottom: 10px; + + /* TODO: When migrated to core-styles, use @extend instead */ + /* @extend .x-truncate--one-line; */ + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +.c-widget > div { + border-top: var(--global-border-width--normal) solid var(--global-color-primary--dark); +} diff --git a/tup/css/_imports/components/content-block.css b/tup/css/_imports/components/content-block.css new file mode 100644 index 00000000..2e0ace37 --- /dev/null +++ b/tup/css/_imports/components/content-block.css @@ -0,0 +1,9 @@ +/* SEE https://dev.tup.tacc.utexas.edu/use-tacc/stem-evaluation-services/ */ +/* FAQ: This is specific to TACC, not for Core */ + +/* To remove some space between content blocks */ +/* FAQ: Short-term solution to excess space */ +/* FAQ: Long-term solution is redo spacing for Rows, Cols, Blocks, and Cards */ +:is(.c-content-block, .content-block) + :is(.c-content-block, .content-block) { + margin-top: calc( -1 * var(--global-space--bootstrap-gap) ); /* usurp `:is(.c-content-block, .content-block)` */ +} diff --git a/tup/css/_imports/components/django-cms-forms.css b/tup/css/_imports/components/django-cms-forms.css new file mode 100644 index 00000000..1a3b1856 --- /dev/null +++ b/tup/css/_imports/components/django-cms-forms.css @@ -0,0 +1,11 @@ +/* Used on a TACC CMS form that is in a card */ +/* SEE: https://dev.tup.tacc.utexas.edu/about/security-and-compliance/protected-data-service/ */ + +/* Add extra space to bottom of a form in a card */ +/* NOTE: We need this only cuz/if padding is removed from card bottom… */ +/* TODO: Review selector (does a form in ANY card need this?) */ +/* TODO: Review whether to support this edge case for `.c-form` also */ +/* TODO: After review of the selector, add to core-styles.cms.css */ +:is(.card, .c-card, [class*="card--"]) .forms { + margin-bottom: 20px; +} diff --git a/tup/css/_imports/components/django.cms.blog.app.page.css b/tup/css/_imports/components/django.cms.blog.app.page.css new file mode 100644 index 00000000..90475b5b --- /dev/null +++ b/tup/css/_imports/components/django.cms.blog.app.page.css @@ -0,0 +1,28 @@ +/* To add space beneath image whose

trapped inside it the text beneath */ +/* NOTE: W.B. does NOT know how the text gets trapped with image in one

*/ +/* HELP: Do not integrate into Core unless the use case is real and clarified */ +article.post-detail .blog-content > p:first-child > img:not(:only-child) { + margin-bottom: 2rem; /* mimic core-styles.cms

margin-bottom */ +} + +/* On article page, to hide automatic main image */ +/* TODO: Consider CMS setting to hide `.blog-visual` */ +article.post-detail .blog-visual { + display: none; +} +@media (width < 576px) { + /* To continue hiding news article image on mobile */ + /* TODO: Determine how best to hide on TUP, but not every site */ + /* FAQ: Core-CMS (in dev/tup-cms) sets .blog-visual to `display: grid` */ + /* SEE: https://github.com/TACC/Core-CMS/blob/v3.12.0-alpha.9/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.page.css#L86-L93 */ + /* SEE: https://github.com/TACC/tup-ui/pull/218#issuecomment-1669960294 */ + article.post-detail .blog-visual { + display: none !important; /* HACK: heavy-handed override of core-cms */ + } +} + +/* On article page, to hide "RELATED POSTS:" */ +/* TODO: Style "RELATED POSTS:" output */ +article.post-detail .post-detail-list { + display: none; +} diff --git a/tup/css/_imports/components/layered-image--fix-raw-image-size.css b/tup/css/_imports/components/layered-image--fix-raw-image-size.css new file mode 100644 index 00000000..480cbee6 --- /dev/null +++ b/tup/css/_imports/components/layered-image--fix-raw-image-size.css @@ -0,0 +1,27 @@ +/* FIX RAW IMAGE SIZE */ +/* FAQ: This is specific to TACC, not for Core */ + +/* All images are uploaded at @2x */ +/* HELP: How can we use @2x and @4x to support retina displays */ +:is(.layered-image, [class*="layered-image--"]) +> :is(.align-left, .align-left--oversized, .align-right, .align-center) { + /* transform: scale(50%); *//* To fix image size */ + transform: scale(40%); /* To fix then tweak image size */ +} +/* FAQ: Some images are off by a different size than the others... */ +:is(.layered-image, [class*="layered-image--"]) > img[src*="/paperclip"], +:is(.layered-image, [class*="layered-image--"]) > img[src*="/spiral"] { + transform: scale(75%); +} +@media (min-width: 768px) and (max-width: 991px) { + :is(.layered-image, [class*="layered-image--"]) + > :is(.align-left, .align-left--oversized, .align-right, .align-center) { + transform: scale(31.25%); + } +} +@media (min-width: 992px) and (max-width: 1199px) { + :is(.layered-image, [class*="layered-image--"]) + > :is(.align-left, .align-left--oversized, .align-right, .align-center) { + transform: scale(37.5%); + } +} diff --git a/tup/css/_imports/components/layered-image--header-and-section-tweaks.css b/tup/css/_imports/components/layered-image--header-and-section-tweaks.css new file mode 100644 index 00000000..0e094a58 --- /dev/null +++ b/tup/css/_imports/components/layered-image--header-and-section-tweaks.css @@ -0,0 +1,23 @@ +/* HEADER & SECTION TWEAKS */ + +/* TODO: Integrate into Core-CMS */ + +/* So

content (e.g. `.c-layered-image`) does not appear atop header */ +/* So `nav.breadcrumbs` do not appear atop header CMS nav */ +body > header { + position: relative; + z-index: 2; +} + +/* So background image does NOT appear over ANY other section + (e.g. an `.align-center` "background image" of a layered image) */ +:is(.o-section, .section, [class*="section--"]) +/* FAQ: Only styled sections can use `position: relative` solution */ ++ [class*="section--"] { + position: relative; /* so previous section is z-index below next section */ +} +:is(.o-section, .section, [class*="section--"]) +/* FAQ: All sections can use `overflow-y` solution */ ++ :is(.o-section, .section, [class*="section--"]) { + overflow-y: clip; /* so successive section can not bleed into any section */ +} diff --git a/tup/css/_imports/components/layered-image.css b/tup/css/_imports/components/layered-image.css new file mode 100644 index 00000000..44af7555 --- /dev/null +++ b/tup/css/_imports/components/layered-image.css @@ -0,0 +1,200 @@ +@import url("./layered-image--header-and-section-tweaks.css"); +@import url("./layered-image--fix-raw-image-size.css"); + +/* TODO: Integrate into Core-CMS */ +/* TODO: Pull component to right LIKE DESIGN (or use o-offset-content) */ +/* CAVEAT: Does NOT yet support the offset of main image as shown in design */ +/* https://xd.adobe.com/view/dabaec5a-cc31-4c5c-876e-56d6d8cc359e-8fe9/screen/c0898d6b-2fd9-472a-bcd7-1ae9d4f9a015/specs/ */ + + + + +/* BASE */ + +/* So top of `.align-left` decal image aligns with top of

*/ +/* FAQ: To limit style to specific context, consider: `.col`, `:only-child` */ +.layered-image, [class*="layered-image--"] { + --h1-offset: 0; + + margin-top: var(--h1-offset); +} + +/* So child images can be positioned */ +.layered-image, [class*="layered-image--"] { + /* So children can `position: absolute` */ + position: relative; + + /* So background image is centered without `transform: translate(…)` */ + /* FAQ: The `transform` prop is already used to scale images (see @media) */ + /* FAQ: To combine conditional `transform` values with `var()` is complex */ + /* FAQ: To use `scale` prop would work... except on Samsung Internet */ + display: grid; + justify-items: center; +} + + + +/* ELEMENTS */ + +/* So images can be positioned */ +:is(.layered-image, [class*="layered-image--"]) +> :is(.align-left, .align-left--oversized, .align-right, .align-center) { + position: absolute; +} +:is(.layered-image, [class*="layered-image--"]) +> :is(.align-left, .align-right) { + float: unset; /* undo core-cms.css */ + max-width: unset; /* undo core-cms.css */ +} + +/* To position images at standard anchor points */ +:is(.layered-image, [class*="layered-image--"]) > .align-left, +:is(.layered-image, [class*="layered-image--"]) > .align-left--oversized { + left: calc(var(--global-space--grid-gap) / 2); +} +:is(.layered-image, [class*="layered-image--"]) > .align-right { + right: calc(var(--global-space--grid-gap) / 2); +} +:is(.layered-image, [class*="layered-image--"]) > .align-left--oversized { + top: -12%; + left: -7%; +} +:is(.layered-image, [class*="layered-image--"]) > .align-center { + /* User must set top inline, because designs are few and inconsistent */ + /* https://xd.adobe.com/view/dabaec5a-cc31-4c5c-876e-56d6d8cc359e-8fe9/screen/032918ef-38c1-4cd2-bd3b-c38a5af710da/specs/ */ + /* https://xd.adobe.com/view/dabaec5a-cc31-4c5c-876e-56d6d8cc359e-8fe9/screen/3f3faa5d-3bca-41ed-9c13-0f94a4caae93/specs/ */ + top: 0; +} +@media (max-width: 575px) /* ✅ 2023-01-27 16:00 */ { + /* To position images at standard anchor points */ + :is(.layered-image, [class*="layered-image--"]) > .align-left, + :is(.layered-image, [class*="layered-image--"]) > .align-left--oversized { + top: -8.8%; + left: calc(var(--global-space--grid-gap) / 2); + } + :is(.layered-image, [class*="layered-image--"]) > .align-right { + bottom: -9.25%; + right: calc(var(--global-space--grid-gap) / 2); + } +} +@media (min-width: 576px) and (max-width: 991px) /* ✅ 2023-01-27 16:00 */ { + :is(.layered-image, [class*="layered-image--"]) > .align-left { + top: -8.8%; + left: -3.4%; + } + :is(.layered-image, [class*="layered-image--"]) > .align-right { + bottom: -9.25%; + right: -5%; + } +} +@media (min-width: 992px) and (max-width: 1199px) /* ✅ 2023-01-27 16:00 */ { + :is(.layered-image, [class*="layered-image--"]) > .align-left { + top: -7.5%; + left: -3%; + } + :is(.layered-image, [class*="layered-image--"]) > .align-right { + bottom: -7.75%; + right: -4.35%; + } +} +@media (min-width: 1200px) and (max-width: 1679px) /* ✅ 2023-01-27 16:00 */ { + :is(.layered-image, [class*="layered-image--"]) > .align-left { + top: -8.8%; + left: -3.4%; + } + :is(.layered-image, [class*="layered-image--"]) > .align-right { + bottom: -9.25%; + right: -5%; + } +} +@media (min-width: 1680px) and (max-width: 1919px) /* ✅ 2023-01-27 16:00 */ { + :is(.layered-image, [class*="layered-image--"]) > .align-left { + top: -7.5%; + left: -3%; + } + :is(.layered-image, [class*="layered-image--"]) > .align-right { + bottom: -7.75%; + right: -4.35%; + } +} +@media (min-width: 1920px) /* ✅ 2023-01-27 16:00 */ { + :is(.layered-image, [class*="layered-image--"]) > .align-left { + top: -6.5%; + left: -3.6%; + } + :is(.layered-image, [class*="layered-image--"]) > .align-right { + bottom: -6.5%; + right: -4.9%; + } +} + +/* To reverse z-index of stacked images (so CMS user can layer intuitively) */ +/* CAVEAT: This works by accident, but designer loves it, so maintain this */ +:is(.layered-image, [class*="layered-image--"]) +> :not([class*="align-"], :only-child) { + position: relative; +} +:is(.layered-image, [class*="layered-image--"]) +> :is(.align-left, .align-left--oversized, .align-right, :not([class*="align-"], :only-child)) { + z-index: 1; +} +:is(.layered-image, [class*="layered-image--"]) +> :is(.align-left--oversized, .align-center) { + z-index: 0; +} + +/* Undo specific `core-styles.cms.css` .align-… margin */ +:is(.layered-image, [class*="layered-image--"]) > .align-left { + margin-right: unset; + margin-bottom: unset; +} +:is(.layered-image, [class*="layered-image--"]) > .align-right { + margin-left: unset; + margin-bottom: unset; +} +:is(.layered-image, [class*="layered-image--"]) > .align-center { + margin-inline: unset; +} + +/* To set origin for scaling decal and background images */ +:is(.layered-image, [class*="layered-image--"]) > .align-left { + transform-origin: top left; +} +:is(.layered-image, [class*="layered-image--"]) > .align-left--oversized { + transform-origin: top left; +} +:is(.layered-image, [class*="layered-image--"]) > .align-right { + transform-origin: bottom right; +} +:is(.layered-image, [class*="layered-image--"]) > .align-center { + transform-origin: top; +} + +/* TODO: Once in Core-CMS, use existing @custom-media */ +/* https://xd.adobe.com/view/dabaec5a-cc31-4c5c-876e-56d6d8cc359e-8fe9/screen/4906fef4-4665-473a-8ad3-459a4fab23c8/specs/ */ +@media (max-width: 575px) { + /* To pull pattern to edge of container when container has no max-width */ + :has(> .layered-image), .has-layered-image { + overflow-x: clip; + } + .layered-image, [class*="layered-image--"] { + margin-inline: calc( -1 * var(--global-space--bootstrap-gap) ); + } +} +@media (max-width: 767px) { + /* To hide background images when pattern flows vertical with content */ + :is(.layered-image, [class*="layered-image--"]) > .align-center { + display: none; + } +} + + + +/* EDGE CASES */ + +/* For a no-modifier, layered image with a single, un-aligned image */ +.layered-image :not([class*="align-"]):only-child { + /* To negate .layered-image`'s alignment with

via `margin-top` */ + /* FAQ: Can NOT just undo parent because Firefox does not support `:has` */ + margin-top: calc( -1 * var(--h1-offset) ); +} diff --git a/tup/css/_imports/elements/headings--cms.css b/tup/css/_imports/elements/headings--cms.css new file mode 100644 index 00000000..9933dd99 --- /dev/null +++ b/tup/css/_imports/elements/headings--cms.css @@ -0,0 +1,5 @@ +/* Structure */ + +table + :is(h1, h2, h3, h4, h5, h6) { + margin-top: 2em; +} diff --git a/tup/css/_imports/objects/o-section.css b/tup/css/_imports/objects/o-section.css new file mode 100644 index 00000000..4efba411 --- /dev/null +++ b/tup/css/_imports/objects/o-section.css @@ -0,0 +1,10 @@ +/* So any section touching breadcrumbs has reduced top space */ +/* TODO: Consider for Core-CMS, not Core-Styles */ +nav.s-breadcrumbs + :is(.o-section, .section):not([class*="o-section--style-"], [class*="section--"]), +nav.s-breadcrumbs + .container > :is(.o-section, .section):not([class*="o-section--style-"], [class*="section--"]):first-child { + margin-top: var(--global-space--under-breadcrumbs); +} +nav.s-breadcrumbs + :is([class*="o-section--style-"], [class*="section--"]), +nav.s-breadcrumbs + .container > :is([class*="o-section--style-"], [class*="section--"]):first-child { + padding-top: var(--global-space--under-breadcrumbs); +} diff --git a/tup/css/_imports/objects/people-grid.css b/tup/css/_imports/objects/people-grid.css new file mode 100644 index 00000000..f0191ff9 --- /dev/null +++ b/tup/css/_imports/objects/people-grid.css @@ -0,0 +1,10 @@ +/* An automatric grid layout intended for people headshots */ +/* FAQ: This pattern was nitially similar to `.o-grid--col-min-width` */ +/* TODO: Consider this pattern for Core-Styles */ +.people-grid { + --width: 192px; + + display: grid; + gap: var(--global-space--grid-gap); + grid-template-columns: repeat( auto-fill, minmax( var(--width), 1fr ) ); +} diff --git a/tup/css/_imports/trumps/s-abbr-list.css b/tup/css/_imports/trumps/s-abbr-list.css new file mode 100644 index 00000000..1fd3fe11 --- /dev/null +++ b/tup/css/_imports/trumps/s-abbr-list.css @@ -0,0 +1,19 @@ +/* ???: Where is this used?! */ + +.s-abbr-list ul, +.abbr-list ul { + padding-left: 0; /* overwrite browser */ + list-style-type: none; + font-weight: var(--medium); +} +.s-abbr-list li, +.abbr-list li { + margin-bottom: 2rem; +} +.s-abbr-list abbr, +.s-abbr-list span.abbr, +.abbr-list abbr, +.abbr-list span.abbr { + color: var(--global-color-secondary--normal); + font-weight: var(--bold); +} diff --git a/tup/css/ad-hoc/adjust-logo.css b/tup/css/ad-hoc/adjust-logo.css new file mode 100644 index 00000000..711f5259 --- /dev/null +++ b/tup/css/ad-hoc/adjust-logo.css @@ -0,0 +1,8 @@ +/* To align first CMS nav with "Dashbaord" heading in Portal */ +.s-header .navbar-brand { + flex-basis: 138px; +} +/* To give CMS nav more room by reducing size of logo */ +.portal-logo { + height: 30px; +} diff --git a/tup/css/ad-hoc/c-feed-list-tweaks.css b/tup/css/ad-hoc/c-feed-list-tweaks.css new file mode 100644 index 00000000..428f829b --- /dev/null +++ b/tup/css/ad-hoc/c-feed-list-tweaks.css @@ -0,0 +1,6 @@ +/* TODO: Release TACC/Core-Styles#508. Update Core-CMS then TUP. Remove this… */ +.c-feed-list > :is(div, article) { + /* FAQ: The `flex-grow: 1` makes /use-tacc/training/ lists same height */ + /* CAVEAT: The `flex-grow: 1` breaks max line height (user can see top of next line) */ + flex-grow: unset; +} diff --git a/tup/css/ad-hoc/fix-c-card-image-on-left-right-not-tall-enough.css b/tup/css/ad-hoc/fix-c-card-image-on-left-right-not-tall-enough.css new file mode 100644 index 00000000..6037a743 --- /dev/null +++ b/tup/css/ad-hoc/fix-c-card-image-on-left-right-not-tall-enough.css @@ -0,0 +1,17 @@ +/* NOTE: Newer Core-Styles or Texascale might have standard solution */ + +/* To enlarge images enough to never allow negative space in card */ +/* FAQ: Hide overflow of enlarged image not constrained in grid item */ +.card--image-left, +.card--image-right { + overflow: hidden; +} +/* FAQ: Enlarge image while maintaining aspect ratio */ +.card--image-left img, +.card--image-right img { + --size: calc(100% + 105px); + + width: var(--size); + height: var(--size); + object-fit: cover; /* to retain aspect ratio */ +} diff --git a/tup/css/ad-hoc/fix-news-hr-behind-offset-image.css b/tup/css/ad-hoc/fix-news-hr-behind-offset-image.css new file mode 100644 index 00000000..2cd6a61a --- /dev/null +++ b/tup/css/ad-hoc/fix-news-hr-behind-offset-image.css @@ -0,0 +1,6 @@ +/* TODO: add to Core-Styles */ +@layer foundation { + hr { + overflow: revert; /* undo Bootstrap 4 _reboot's `overflow: visible` */ + } +} diff --git a/tup/css/ad-hoc/global-a11y.css b/tup/css/ad-hoc/global-a11y.css new file mode 100644 index 00000000..01adb338 --- /dev/null +++ b/tup/css/ad-hoc/global-a11y.css @@ -0,0 +1,19 @@ +/* FOR HOMEPAGE AS OF 2024-02 */ + +/* 1. To dynamically reduce height of banner */ +/* Change — + style="height: 550px" + — on banner image to — + style="height: 60vh; max-height: 550px; min-height: 230px;" +*/ + +/* 2. To make mobile menu button stand out */ +.navbar-dark .navbar-toggler { + border-color: var(--global-color-primary--normal); +} + +/* 3. Unset color that is so light it makes links in a lead undistinguishable */ +/* TODO: Delete this after TUP-CMS uses Core-CMS since TACC/Core-CMS#1141 */ +:is(:is(.blog-list) article) .blog-lead { + color: unset; +} diff --git a/tup/css/ad-hoc/hide-blog-list-back-link.css b/tup/css/ad-hoc/hide-blog-list-back-link.css new file mode 100644 index 00000000..18a3d698 --- /dev/null +++ b/tup/css/ad-hoc/hide-blog-list-back-link.css @@ -0,0 +1,4 @@ +/* TODO: Remove when TUP CMS uses Core-CMS with PORTAL_BLOG_SHOW_BACK_LINK (default false). */ +.blog-list .blog-back { + visibility: hidden; +} diff --git a/tup/css/ad-hoc/hide-svg-icons.css b/tup/css/ad-hoc/hide-svg-icons.css new file mode 100644 index 00000000..519c83f4 --- /dev/null +++ b/tup/css/ad-hoc/hide-svg-icons.css @@ -0,0 +1,10 @@ +/* to hide SVG icons from everyone */ +& .has-svg use { + display: none !important; +} +/* to show SVG icons to editors */ +/* +[class*="cms-structure-mode-"] { + & .has-svg use { display: revert !important; } +} +*/ diff --git a/tup/css/ad-hoc/navbar-width-horz-scrollbar.css b/tup/css/ad-hoc/navbar-width-horz-scrollbar.css new file mode 100644 index 00000000..3c8d99ee --- /dev/null +++ b/tup/css/ad-hoc/navbar-width-horz-scrollbar.css @@ -0,0 +1,8 @@ +/* TO AVOID HORIZONTAL SCROLLBAR */ + +/* To hide username on Portal dropdown when it shrinks the rest of the header "too much" */ +@media (min-width: 992px) and (max-width: 1199px) { + .s-portal-nav .dropdown-toggle span { + display: none; + } +} diff --git a/tup/css/ad-hoc/podcast-embeds.css b/tup/css/ad-hoc/podcast-embeds.css new file mode 100644 index 00000000..60b432c7 --- /dev/null +++ b/tup/css/ad-hoc/podcast-embeds.css @@ -0,0 +1,4 @@ +/* to remove extra height embedded podcast audio, but not cause scrollbar */ +iframe[src*="rss.com"] { + height: 152px; +} diff --git a/tup/css/ad-hoc/scrolling-fixes.css b/tup/css/ad-hoc/scrolling-fixes.css new file mode 100644 index 00000000..cd8f6d88 --- /dev/null +++ b/tup/css/ad-hoc/scrolling-fixes.css @@ -0,0 +1,22 @@ +/* To prevent horz. body scroll because of header nav too wide, 1092px—1066px */ +/* WARNING: In Safari 16.2–16.3, this hides header dropdown behind content */ +/* HELP: Fix the bug, instead of just hiding the bug */ +/* +header { + overflow-x: clip; +} +*/ + +/* To prevent horz. body scroll because of offset SVG Icons */ +/* HELP: Fix the bug, instead of just hiding the bug */ +/* FAQ: 290px is our body min. width; narrower than that, user must scroll */ +/* SEE: /use-tacc/evaluation-services/ */ +/* SEE: /partnerships/star-industry-program/ */ +/* SEE: / (home page) */ +@media (width >= 290px) { + /* FAQ: News articles may have images that overflow */ + /* SEE: /news/latest-news/2023/04/18/welcome-new-tacc-website/ */ + html:not(#page-news) main { + overflow-x: clip; + } +} diff --git a/tup/css/ad-hoc/spacing-fixes.css b/tup/css/ad-hoc/spacing-fixes.css new file mode 100644 index 00000000..228dda6d --- /dev/null +++ b/tup/css/ad-hoc/spacing-fixes.css @@ -0,0 +1,23 @@ +/* To add extra space under columns on specific pages */ +/* HELP: How can we apply and maintian this better? */ +/* FAQ: Columns that explcitely or automatically span 12, get margin bottom */ +.col-12:not( + :last-child, + [class*="banner-cell"], + #page-scivis-gallery *, + #page-all-systems *, + #page-stampede2 *, /* 2023-10-13 *//* /systems/stampede2/ */ + :has(h1:only-child), /* /research/tacc-software/, /use-tacc/software-list/ */ + #page-weteachcs *, /* 2024-10-03 *//* /education/educators/weteachcs/ */ + #page-training *, /* 2025-04-02 *//* /use-tacc/training/ */ + #page-about-tours *, /* 2026-03-16 *//* /about/tours/ */ + #page-request-tour * /* 2026-03-16 *//* /about/tours/request/ */ + #page-acsc *, /* 2026-04-21 *//* /education/undergraduates-graduates/acsc/ */ +), +.col:not( + [class*="col-"], + [class*="banner-cell"], /* homepage banner */ + :last-child +) { + margin-bottom: 4rem; +} diff --git a/tup/css/ad-hoc/tagged-news-uppercase-tag.css b/tup/css/ad-hoc/tagged-news-uppercase-tag.css new file mode 100644 index 00000000..fcee9a8f --- /dev/null +++ b/tup/css/ad-hoc/tagged-news-uppercase-tag.css @@ -0,0 +1,5 @@ +/* To uppercase tag name on /news/…/tag/… */ +/* CAVEAT: Uppercases category name on /news/…/category/… */ +.blog-list h1 > span + em { + text-transform: uppercase; +} diff --git a/tup/css/ad-hoc/trumps-has-decal.css b/tup/css/ad-hoc/trumps-has-decal.css new file mode 100644 index 00000000..74340de4 --- /dev/null +++ b/tup/css/ad-hoc/trumps-has-decal.css @@ -0,0 +1,14 @@ +/* To restrict movement & visibility of background decal icons with a section */ +.has-decal, +[class*="has-decal--"] { + position: relative; +} +.has-decal--clip { + overflow: clip; +} +.has-decal--clip-x { + overflow-x: clip; +} +.has-decal--clip-y { + overflow-y: clip; +} diff --git a/tup/css/ad-hoc/tup-730-drop-cap-and-fix-has-blog-tag-no-drop-cap.css b/tup/css/ad-hoc/tup-730-drop-cap-and-fix-has-blog-tag-no-drop-cap.css new file mode 100644 index 00000000..624491c6 --- /dev/null +++ b/tup/css/ad-hoc/tup-730-drop-cap-and-fix-has-blog-tag-no-drop-cap.css @@ -0,0 +1,26 @@ +/* ???: What do these do or fail to do? + Is it related to this from W.B. in Slack? + "Not showing drop-cap in Drafts is a bug." +*/ + +/* TUP-730 */ +/* +@supports (-webkit-initial-letter: 3) { + .has-blog-tag-no-drop-cap .s-drop-cap > p:first-of-type:first-letter { + -webkit-initial-letter: unset; + } +} +@supports (initial-letter: 3) { + .has-blog-tag-no-drop-cap .s-drop-cap > p:first-of-type:first-letter { + initial-letter: unset; + } +} +*/ + +/* 2024-09-23 (After TUP-730) *//* +@supports (-webkit-initial-letter: 3) { + .has-blog-tag-no-drop-cap .s-drop-cap > p:first-of-type:first-letter { + -webkit-initial-letter: unset; + } +} +*/ diff --git a/tup/css/ad-hoc/u-image.css b/tup/css/ad-hoc/u-image.css new file mode 100644 index 00000000..f6f20eaa --- /dev/null +++ b/tup/css/ad-hoc/u-image.css @@ -0,0 +1,11 @@ +/* to crop any "Meet the Interns" to match "Cohort 1" */ +/* https://tacc.utexas.edu/about/internships/lccf/ */ +img.u-image--meet-the-interns, +/* FAQ: Core-CMS Django CMS template can move image class to image container */ +/* https://github.com/TACC/Core-CMS/blob/v4.33.0/taccsite_cms/templates/djangocms_picture/default/picture.html#L18-L37 */ +.u-image--meet-the-interns > img { + width: 100%; + aspect-ratio: 5 / 1; + object-fit: cover; + object-position: center 30%; +} diff --git a/tup/css/cms.css b/tup/css/cms.css new file mode 100644 index 00000000..53b36035 --- /dev/null +++ b/tup/css/cms.css @@ -0,0 +1,32 @@ +/* Organize via ITCSS */ +/* SEE: https://confluence.tacc.utexas.edu/x/IAA9Cw */ + +/* SETTINGS */ +/* ... */ + +/* GENERICS */ +/* ... */ + +/* ELEMENTS */ +@import url("./_imports/elements/headings--cms.css") layer(project); + +/* OBJECTS */ +@import url("./_imports/objects/o-section.css") layer(project); +@import url("./_imports/objects/people-grid.css") layer(project); + +/* COMPONENTS */ +@import url("./_imports/components/agenda-table.css") layer(project); +@import url("./_imports/components/banner.css") layer(project); +@import url("./_imports/components/c-data-list.css") layer(project); +@import url("./_imports/components/c-footer.css") layer(project); +@import url("./_imports/components/c-news.css") layer(project); +@import url("./_imports/components/c-tag.css") layer(project); +@import url("./_imports/components/c-update.css") layer(project); +@import url("./_imports/components/c-widget.css") layer(project); +@import url("./_imports/components/content-block.css") layer(project); +@import url("./_imports/components/django-cms-forms.css") layer(project); +@import url("./_imports/components/django.cms.blog.app.page.css") layer(project); +@import url("./_imports/components/layered-image.css") layer(project); + +/* TRUMPS */ +@import url("./_imports/trumps/s-abbr-list.css") layer(project); diff --git a/tup/html/css-ad-hoc-styles.html b/tup/html/css-ad-hoc-styles.html index 08f7889f..21060b6f 100644 --- a/tup/html/css-ad-hoc-styles.html +++ b/tup/html/css-ad-hoc-styles.html @@ -23,11 +23,13 @@ {# TODO: Delete after upgrading to Core-CMS#v4.40 (TACC/tup-ui#557) #} -{# NOTE: Redundant until deploy since TACC/tup-ui#535 #} +{# NOTE: Redundant until deploy of TACC/tup-ui#535 #} +{# NOTE: Redundant until deploy of TACC/tup-ui#570 #} + {# TODO: Delete after upgrading to Core-CMS#v4.40 (TACC/tup-ui#557) #} diff --git a/tup/img/logo-color.svg b/tup/img/logo-color.svg new file mode 100644 index 00000000..702cecee --- /dev/null +++ b/tup/img/logo-color.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tup/img/logo-white-25years--cropped.svg b/tup/img/logo-white-25years--cropped.svg new file mode 100644 index 00000000..7ef88570 --- /dev/null +++ b/tup/img/logo-white-25years--cropped.svg @@ -0,0 +1,774 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tup/img/logo-white-25years.svg b/tup/img/logo-white-25years.svg new file mode 100644 index 00000000..4ae88eae --- /dev/null +++ b/tup/img/logo-white-25years.svg @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tup/img/logo-white.svg b/tup/img/logo-white.svg new file mode 100644 index 00000000..ee96ecc5 --- /dev/null +++ b/tup/img/logo-white.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/tup/js/ad-hoc.js b/tup/js/ad-hoc.js new file mode 100644 index 00000000..691e483f --- /dev/null +++ b/tup/js/ad-hoc.js @@ -0,0 +1,2 @@ +import './ad-hoc/prevent-ugly-urls.js'; +import './ad-hoc/manage-participants-field-required-attr.js'; diff --git a/tup/js/ad-hoc/manage-participants-field-required-attr.js b/tup/js/ad-hoc/manage-participants-field-required-attr.js new file mode 100644 index 00000000..60575207 --- /dev/null +++ b/tup/js/ad-hoc/manage-participants-field-required-attr.js @@ -0,0 +1,53 @@ +/* Do not let both "Participants" fields of any form be required at once */ +document.addEventListener('DOMContentLoaded', function () { + var textArea = document.getElementById('participants'); + var fileUpload = document.getElementById('participants_via_file_upload'); + + if (!textArea || !fileUpload) { + return; + } + + /* to indicate an un-required field is "(alternative)" (not "(important)") */ + /* https://github.com/TACC/Core-Styles/blob/v2.57.3/src/lib/_imports/components/c-form.css#L98-L104 */ + var style = document.createElement('style'); + style.textContent = ` + .field-wrapper:not(.required) label[for*="participants"] .asterisk:after { + content: "(alternative)"; + } + `; + document.head.appendChild(style); + + var textAreaWrapper = textArea.closest('.field-wrapper'); + var fileUploadWrapper = fileUpload.closest('.field-wrapper'); + + function ensureAsterisk(wrapper) { + var label = wrapper.querySelector('label'); + if (label && !label.querySelector('.asterisk')) { + var asterisk = document.createElement('span'); + asterisk.className = 'asterisk'; + asterisk.textContent = '*'; + label.appendChild(asterisk); + } + } + + ensureAsterisk(textAreaWrapper); + ensureAsterisk(fileUploadWrapper); + + function updateRequired() { + const hasText = textArea.value.trim() !== ''; + const hasFile = fileUpload.value !== ''; + const shouldRequireTextArea = !hasFile; + const shouldRequireFileUpload = hasFile && !hasText; + + textArea.required = shouldRequireTextArea; + fileUpload.required = shouldRequireFileUpload; + + textAreaWrapper.classList.toggle('required', shouldRequireTextArea); + fileUploadWrapper.classList.toggle('required', shouldRequireFileUpload); + } + + textArea.addEventListener('input', updateRequired); + fileUpload.addEventListener('change', updateRequired); + + updateRequired(); +}); diff --git a/tup/js/ad-hoc/prevent-ugly-urls.js b/tup/js/ad-hoc/prevent-ugly-urls.js new file mode 100644 index 00000000..79c1b804 --- /dev/null +++ b/tup/js/ad-hoc/prevent-ugly-urls.js @@ -0,0 +1,25 @@ +/* SEE: TUP-715 */ + +const links = document.querySelectorAll( + 'body > :is(header, main, footer) a[target="_blank"]' +); + +/* HACK: To revert URL of links that Google changes on hover */ +/* FAQ: Google Analytics settings interpret subdomain links as URLs to adjust so it can track navigation */ +[...links].forEach(function restoreLinkHrefChangedOnHover(link) { + const isTACC = link.host.includes('tacc.utexas.edu'); + + if (isTACC) { + let currentHrefVal = link.getAttribute('href'); + + link.setAttribute('data-original-href', currentHrefVal); + link.addEventListener('click', () => { + const originalHrefVal = link.getAttribute('data-original-href'); + + currentHrefVal = link.getAttribute('href'); + if (currentHrefVal !== originalHrefVal) { + link.setAttribute('href', originalHrefVal); + } + }); + } +});