diff --git a/README.md b/README.md
index d889b76b3..7c8926919 100644
--- a/README.md
+++ b/README.md
@@ -241,7 +241,7 @@ npm run build:css -- --build-id="..."
##### Build Individual Stylesheets
```bash
-npm run build:each -- src/lib/_imports/components/align.postcss src/lib/_imports/components/admonition.postcss ...
+npm run build:each -- src/lib/_imports/components/c-callout/c-callout.postcss src/lib/_imports/components/c-island/c-island.postcss ...
```
diff --git a/bin/build.js b/bin/build.js
index 6978f7c22..623857f85 100755
--- a/bin/build.js
+++ b/bin/build.js
@@ -2,9 +2,10 @@
/** Build CSS using the Core-Styles API */
-const { buildStylesheets } = require('../src/main');
const mininmist = require('minimist');
+const { buildStylesheets } = require('../src/main');
+
const ARGS = mininmist( process.argv.slice( 2 ) );
const BUILD_ID = ARGS['build-id'] || '';
diff --git a/bin/copy-to-dist.sh b/bin/copy-to-dist.sh
new file mode 100755
index 000000000..a8bcf9522
--- /dev/null
+++ b/bin/copy-to-dist.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -e # Exit immediately if a command exits with a non-zero status
+
+SOURCE_ROOT="src/lib/"
+DEST_ROOT="dist/"
+
+# To be reused with path appended
+source_path="$SOURCE_ROOT"
+dest_path="$DEST_ROOT"
+
+# Copy vendor stylesheets (while preserving directory structure)
+source_path="${SOURCE_ROOT}_imports/"
+echo "Copy vendor stylesheets from '$source_path' to '$DEST_ROOT'"
+rsync -av --prune-empty-dirs --include='*/' --include='*/vendor/*.css' --exclude='*' "$source_path" "$DEST_ROOT" \
+|| { echo "Error copying"; exit 1; }
+
+echo "Copied vendor stylesheets."
+
+# Copy other files
+dirs=("scripts" "fonts" "tokens")
+for dir in "${dirs[@]}"; do
+ source_path="${SOURCE_ROOT}${dir}/"
+ dest_path="${DEST_ROOT}${dir}/"
+ echo "Copying $dir from '$source_path' to '$dest_path'."
+
+ # Check for source
+ [ -d "$source_path" ] \
+ || mkdir -p "$source_path" \
+ || { echo "Error recreating '$source_path'"; exit 1; }
+
+ # Remove past output
+ rm -rf "${dest_path}" \
+ || { echo "Error removing destination"; exit 1; }
+
+ # Copy files
+ cp -r "$source_path" "$dest_path" \
+ || { echo "Error copying"; exit 1; }
+
+ echo "Copied $dir."
+done
diff --git a/bin/fix-relative-imports.sh b/bin/fix-relative-imports.sh
new file mode 100755
index 000000000..eed96fae2
--- /dev/null
+++ b/bin/fix-relative-imports.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+# Fix Relative Imports Script
+# Fixes broken relative imports in component files that were moved to subdirectories
+# The files moved one level deeper, so relative imports need an extra "../"
+
+set -e # Exit on any error
+
+echo "đ§ Fixing relative imports in moved component files..."
+
+# Change to project root, then to components directory
+cd "$(dirname "$0")/.."
+cd "src/lib/_imports/tacc/components"
+
+# Find all component directories dynamically
+# This covers all components, including those worked on independently of the refactor script
+echo "đ Discovering all component directories..."
+
+# Function to fix relative imports in a component directory
+fix_component_imports() {
+ local component=$1
+ echo "đ Fixing imports in $component..."
+
+ # Fix imports that reference ../tools/ (should be ../../tools/) - both quote types
+ find "$component" -name "*.postcss" -type f -exec sed -i '' 's|['\''"]../tools/|"../../tools/|g' {} \;
+
+ # Fix component-to-component imports that reference ./c-component/ (should be ../c-component/) - both quote types
+ find "$component" -name "*.postcss" -type f -exec sed -i '' 's|['\''"]\./c-|"../c-|g' {} \;
+
+ # Fix component variant imports that reference ../component-name.* or ../component-name--* (should be ./component-name.* or ./component-name--*)
+ # This handles any variant file belonging to the same component (selectors, structure, skin, variants, etc.)
+ find "$component" -name "*.postcss" -type f -exec sed -i '' "s|['\''\"]\.\./${component}[\.-]|\"\./${component}.|g" {} \;
+ find "$component" -name "*.postcss" -type f -exec sed -i '' "s|['\''\"]\.\./${component}--|\"\./${component}--|g" {} \;
+
+ echo " â
Fixed imports in $component"
+}
+
+# Fix imports for all component directories found
+for component_dir in */; do
+ # Remove trailing slash to get component name
+ component="${component_dir%/}"
+
+ # Skip non-directories and common non-component items
+ if [[ -d "$component" && "$component" != ".DS_Store" && "$component" != "README.css" && "$component" != "config.yml" && "$component" != "demo.postcss" ]]; then
+ fix_component_imports "$component"
+ fi
+done
+
+# Fix asset paths in config.yml files
+echo "đ§ Fixing asset paths in config.yml files..."
+
+# We're already in the components directory from the previous section
+# No need to cd again
+
+# For each component subdirectory, fix asset paths in all config.yml files
+for component_dir in */; do
+ component="${component_dir%/}"
+
+ # Skip non-directories and common non-component items
+ if [[ -d "$component" && "$component" != ".DS_Store" && "$component" != "README.css" && "$component" != "config.yml" && "$component" != "demo.postcss" ]]; then
+ echo " đ Fixing asset paths for $component..."
+
+ # Go back to project root to find all config.yml files
+ cd "../../../../.."
+
+ # Fix basic component.css pattern
+ find . -name "config.yml" -type f -exec sed -i '' "s|../../assets/components/${component}\.css|../../assets/tacc/components/${component}/${component}.css|g" {} \;
+
+ # Fix variant component--variant.css pattern
+ find . -name "config.yml" -type f -exec sed -i '' "s|../../assets/components/${component}--\([^.]*\)\.css|../../assets/tacc/components/${component}/${component}--\1.css|g" {} \;
+
+ # Go back to components directory for next iteration
+ cd "src/lib/_imports/tacc/components"
+ fi
+done
+
+# Go back to project root
+cd "../../../../.."
+
+echo "â
Fixed asset paths in config.yml files"
+
+echo "â
All relative imports and asset paths have been fixed!"
+echo ""
+echo "You can now run 'npm run build' to verify the build works correctly."
diff --git a/bin/refactor-components.sh b/bin/refactor-components.sh
new file mode 100755
index 000000000..9eb3c4c96
--- /dev/null
+++ b/bin/refactor-components.sh
@@ -0,0 +1,147 @@
+#!/bin/bash
+
+# TACC Components Refactoring Script
+# Refactors remaining flat components to subdirectory structure
+# Based on pattern from commit be1f77e
+
+set -e # Exit on any error
+
+echo "đ Starting TACC Components Refactoring..."
+
+# Change to components directory
+cd "src/lib/_imports/tacc/components"
+
+# Define components to refactor (excluding already refactored ones)
+declare -a COMPONENTS=(
+ "c-callout"
+ "c-content-block"
+ "c-hero-banner"
+ "c-image-map"
+ "c-island"
+ "c-message"
+ "c-nav"
+ "c-page"
+ "c-pill"
+ "c-recognition"
+ "c-see-all-link"
+ "c-show-more"
+ "c-tag"
+ "c-update"
+ "cortal-icon"
+)
+
+# Function to refactor a single component
+refactor_component() {
+ local component=$1
+ echo "đ Refactoring $component..."
+
+ # Create subdirectory if it doesn't exist
+ mkdir -p "$component"
+
+ # Move main postcss file
+ if [ -f "${component}.postcss" ]; then
+ git mv "${component}.postcss" "${component}/${component}.postcss"
+ echo " â
Moved ${component}.postcss"
+ fi
+
+ # Move variant files of pattern ${component}.*.postcss
+ for variant_file in ${component}.*.postcss; do
+ if [ -f "$variant_file" ] && [ "$variant_file" != "${component}.postcss" ]; then
+ git mv "$variant_file" "${component}/$variant_file"
+ echo " â
Moved $variant_file"
+ fi
+ done
+
+ # Move variant files of -- pattern (--compact, --expanded, etc.)
+ for variant_file in ${component}--*.postcss; do
+ if [ -f "$variant_file" ]; then
+ git mv "$variant_file" "${component}/$variant_file"
+ echo " â
Moved $variant_file"
+ fi
+ done
+}
+
+# Function to update import paths
+update_imports() {
+ local component=$1
+ echo "đ Updating import paths for $component..."
+
+ cd ../../../../.. # Go back to project root
+
+ # Update main component imports
+ find src -name "*.postcss" -type f -exec sed -i '' "s|components/${component}\.postcss|components/${component}/${component}.postcss|g" {} \;
+
+ # Update all variant imports with pattern ${component}.*.postcss
+ find src -name "*.postcss" -type f -exec sed -i '' "s|components/${component}\.[^/]*\.postcss|components/${component}/&|g" {} \;
+
+ # Update variant imports with -- pattern (--compact, --expanded, etc.)
+ find src -name "*.postcss" -type f -exec sed -i '' "s|components/${component}--\([^/]*\)\.postcss|components/${component}/${component}--\1.postcss|g" {} \;
+
+ cd src/lib/_imports/tacc/components # Go back to components directory
+
+ echo " â
Updated import paths for $component"
+}
+
+# Function to update or create config.yml
+update_config() {
+ local component=$1
+
+ if [ -f "${component}/config.yml" ]; then
+ echo "đ Updating config.yml for $component..."
+
+ # Check if context: already exists
+ if grep -q "^context:" "${component}/config.yml"; then
+ # Check if subdir already exists under context
+ if ! grep -q "subdir:" "${component}/config.yml"; then
+ # Add subdir property after context:
+ sed -i '' '/^context:/a\
+ subdir: "tacc/components/'$component'"\n' "${component}/config.yml"
+ echo " â
Added subdir to existing context in config.yml"
+ else
+ echo " âšī¸ subdir already exists in config.yml"
+ fi
+ else
+ # Add context: section with subdir at the end of the file
+ echo "context:" >> "${component}/config.yml"
+ echo " subdir: \"tacc/components/$component\"" >> "${component}/config.yml"
+ echo " â
Added context section with subdir to config.yml"
+ fi
+ else
+ echo "đ Creating config.yml for $component..."
+ # Create new config.yml with context and subdir
+ cat > "${component}/config.yml" << EOF
+context:
+ subdir: "tacc/components/$component"
+EOF
+ echo " â
Created config.yml with context and subdir"
+ fi
+}
+
+# Main refactoring loop
+for component in "${COMPONENTS[@]}"; do
+ echo ""
+ echo "đ§ Processing $component..."
+
+ # Check if already refactored (directory exists and main file is inside)
+ if [ -d "$component" ] && [ -f "${component}/${component}.postcss" ]; then
+ echo " âšī¸ $component files already moved, checking config.yml..."
+ # Still run config update in case context/subdir is missing
+ update_config "$component"
+ echo " â
$component config check complete!"
+ else
+ # Full refactoring needed
+ refactor_component "$component"
+ update_imports "$component"
+ update_config "$component"
+ echo " â
$component refactoring complete!"
+ fi
+done
+
+echo ""
+echo "đ All components refactored successfully!"
+echo ""
+echo "đ Summary:"
+git status --porcelain | grep -E "(renamed|modified)" | wc -l | xargs echo " Files changed:"
+echo ""
+echo "đ Review changes with: git status"
+echo "đž Commit changes with: git commit -m 'refactor(components): move remaining components to subdirectories'"
diff --git a/docs/bootstrap.md b/docs/bootstrap.md
index a4c6dfb0d..498a1f636 100644
--- a/docs/bootstrap.md
+++ b/docs/bootstrap.md
@@ -40,7 +40,9 @@ Any support is for [Bootstrap v4](https://getbootstrap.com/docs/4.0) unless othe
| Core Styles extends | Bootstrap
| - | -
-| [Row](https://github.com/TACC/Core-Styles/blob/v2.14.0/src/lib/_imports/components/bootstrap.row.css) | [Grid](https://getbootstrap.com/docs/4.0/layout/grid/): Row
+| [Container](https://github.com/TACC/Core-Styles/blob/v2.14.0/src/lib/_imports/bootstrap4/container.css) | [Grid](https://getbootstrap.com/docs/4.0/layout/grid/): Container
+| [Row](https://github.com/TACC/Core-Styles/blob/v2.14.0/src/lib/_imports/bootstrap4/row.css) | [Grid](https://getbootstrap.com/docs/4.0/layout/grid/): Row
+| [Col](https://github.com/TACC/Core-Styles/blob/v2.14.0/src/lib/_imports/bootstrap4/col.css) | [Grid](https://getbootstrap.com/docs/4.0/layout/grid/): Col
| Core Styles changes | Bootstrap
| - | -
@@ -48,7 +50,7 @@ Any support is for [Bootstrap v4](https://getbootstrap.com/docs/4.0) unless othe
| [Breadcrumb](https://cep.tacc.utexas.edu/static/ui/components/detail/bootstrap3--breadcrumb) | [Breadcrumb (**v3**)](https://getbootstrap.com/docs/4.0/components/breadcrumb/)
| [Modal](https://cep.tacc.utexas.edu/static/ui/components/detail/bootstrap--modal.html) | [Modal](https://getbootstrap.com/docs/4.0/components/modal/)
| [Nav Tabs](https://cep.tacc.utexas.edu/static/ui/components/detail/bootstrap--nav-tabs.html) | Navs: [Tabs](https://getbootstrap.com/docs/4.0/components/navs/#tabs)
-| [Pagination](https://github.com/TACC/Core-Styles/blob/v2.14.0/src/lib/_imports/components/bootstrap.pagination.css) | [Pagination](https://getbootstrap.com/docs/4.0/components/pagination/)
+| [Pagination](https://github.com/TACC/Core-Styles/blob/v2.14.0/src/lib/_imports/bootstrap4/pagination.css) | [Pagination](https://getbootstrap.com/docs/4.0/components/pagination/)
| Where Core Styles yields to | Bootstrap
| - | -
diff --git a/docs/shortcuts/forms.md b/docs/shortcuts/forms.md
index 6b0a7720b..390c1920b 100644
--- a/docs/shortcuts/forms.md
+++ b/docs/shortcuts/forms.md
@@ -6,6 +6,6 @@ title: Form Patterns
| - | - | - | - | - |
| Trumps (Scope) | [S Form]({{path '/components/detail/s-form' }}) | new,
recommended | few classes,
very strict markup | minimal TACC pattern |
| Components | [C Form]({{path '/components/detail/c-form' }}) | active,
maintained | many classes,
some flexible markup | standard TACC pattern |
-| Components | [Django CMS Forms]({{path '/components/detail/django-cms-forms' }}) | active,
legacy | very many classes,
very strict markup | for a [Django CMS plugin](https://pypi.org/project/djangocms-forms-maintained/)* |
+| Components | [Django CMS Forms]({{path '/components/detail/djangocms-forms' }}) | active,
legacy | very many classes,
very strict markup | for a [Django CMS plugin](https://pypi.org/project/djangocms-forms-maintained/)* |
* Used by [Core-CMS](https://github.com/TACC/Core-CMS)
diff --git a/docs/upgrade-client.config.yml b/docs/upgrade-client.config.yml
new file mode 100644
index 000000000..9aa09f673
--- /dev/null
+++ b/docs/upgrade-client.config.yml
@@ -0,0 +1 @@
+hidden: true
\ No newline at end of file
diff --git a/docs/upgrade-client.md b/docs/upgrade-client.md
new file mode 100644
index 000000000..20eb3048c
--- /dev/null
+++ b/docs/upgrade-client.md
@@ -0,0 +1,46 @@
+# Upgrade Client
+
+## Table of Contents
+
+- [v2 to v3](#core-cms-v2-to-v3)
+ 1. [Removed](#removed)
+ 2. [Changed](#changed)
+ 3. [Added](#added)
+
+## v2 to v3
+
+### Removed
+
+#### `.has-required`
+
+##### `.s-form`
+
+```diff
++
to continue to the TACC User Portal
- {{> @form-errors class=class.errors wrapClass=class.form_errors_wrap }} + {{> @form-errors class=class.form_errors wrapClass=class.form_errors_wrap }}