Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/rules/common
Submodule common updated 1 files
+0 −9 README.md
50 changes: 26 additions & 24 deletions website/modules/asset/ui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,19 @@ import { setupTagSearchForInput } from './searchInputHandler';
import { FilterModal } from './filterModal';
import { initClientSideFiltering } from './clientSideFiltering';

/* eslint-enable sort-imports */
function revealLoaded() {
document
.querySelectorAll(
'.breadcrumb.loading, .sf-container.loading, .page-main_content.loading',
)
.forEach((el) => {
el.classList.remove('loading');
el.classList.add('loaded');
if (el.hasAttribute('aria-busy')) {
el.setAttribute('aria-busy', 'false');
}
});
}

function initConfiguration() {
window.DEFAULT_VISIBLE_TAGS_COUNT = 5;
Expand Down Expand Up @@ -57,13 +69,11 @@ function initFontChanger() {

setInterval(() => {
currentFontIndex = (currentFontIndex + 1) % fonts.length;
// Use Array.prototype.at() for safer array access
const currentFont = fonts.at(currentFontIndex);
heroContent.style.fontFamily = currentFont;
}, 500);
}

// Tag search filter for case studies page
function initCaseStudiesTagFilter({
inputSelector = '.tag-search',
containerSelector = '.filter-section',
Expand Down Expand Up @@ -92,12 +102,10 @@ function initializeAllComponents() {
initClientSideFiltering();
}

// Barba pages
function initBarbaPageTransitions() {
if (!document.querySelector('[data-barba="container"]')) return;

apos.util.onReady(() => {
// Initialize case studies filter handler
initCaseStudiesFilterHandler();

// Original Barba enter callback
Expand Down Expand Up @@ -175,23 +183,22 @@ function initBarbaPageTransitions() {
],
});

// Add after hook for updating menu state
barba.hooks.after(() => {
// Update menu active state
const currentPath = window.location.pathname;
const menuLinks = document.querySelectorAll('.sf-nav__list a');

// First, remove active class from all menu items
menuLinks.forEach((link) => link.classList.remove('active'));

// Then, add active class to the current menu item
menuLinks.forEach((link) => {
const href = link.getAttribute('href');
const hrefPath = new URL(href, window.location.origin).pathname;
if (hrefPath === currentPath) {
link.classList.add('active');
}
});

revealLoaded();

initFilterModal();
});
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Expand Down Expand Up @@ -259,17 +266,13 @@ function initFilterModal() {

document.addEventListener('DOMContentLoaded', initFilterModal);

if (typeof barba !== 'undefined') {
barba.hooks.after(() => {
initFilterModal();
});
}

export default () => {
initConfiguration();

initializeAllComponents();

document.addEventListener('DOMContentLoaded', revealLoaded);

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
apos.util.onReady(() => {
initCaseStudiesFilterHandler();
});
Expand All @@ -281,14 +284,13 @@ export default () => {
// Case studies anchor fix
setTimeout(() => {
const { pathname, search, hash } = window.location;
const isCasesPage = pathname.includes('/cases');
const hasFilterParams =
search.includes('industry') ||
search.includes('stack') ||
search.includes('caseStudyType') ||
hash.includes('filter');

if (isCasesPage && hasFilterParams) {
if (
pathname.includes('/cases') &&
(search.includes('industry') ||
search.includes('stack') ||
search.includes('caseStudyType') ||
hash.includes('filter'))
) {
const filterAnchor = document.getElementById('filter');
if (filterAnchor) filterAnchor.scrollIntoView({ behavior: 'smooth' });
}
Expand Down
37 changes: 37 additions & 0 deletions website/modules/asset/ui/src/scss/_animation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,40 @@
filter: blur(0);
}
}

// Loading/Loaded states for reveal animations
.loading {
opacity: 0;
overflow: hidden;
visibility: hidden;
transform: translateY(20px);
transition:
opacity 0.6s ease-out,
transform 0.6s ease-out;
}

.loaded {
opacity: 1;
overflow: visible;
visibility: visible;
transform: translateY(0);
}

// Specific loading states for breadcrumbs and containers
.breadcrumb.loading,
.sf-container.loading {
opacity: 0 !important;
visibility: hidden !important;
transform: translateY(15px);
transition:
opacity 0.5s ease-out,
visibility 0.5s ease-out,
transform 0.5s ease-out;
}

.breadcrumb.loaded,
.sf-container.loaded {
opacity: 1 !important;
visibility: visible !important;
transform: translateY(0);
}
1 change: 0 additions & 1 deletion website/modules/asset/ui/src/scss/_cases.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
&_content {
display: flex;
flex-direction: column;
gap: 2rem;
margin-bottom: 3rem;
}

Expand Down
18 changes: 17 additions & 1 deletion website/modules/case-studies-page/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
data-default-visible-tags="{{ data.defaultVisibleTagsCount }}"
>
<div class="cs_content">
<div class="page-main_content">{% area data.page, 'main' %}</div>
<div
class="page-main_content loading"
id="page-main_content"
aria-busy="true"
>
{% area data.page, 'main' %}
</div>

<div id="filter" class="filter-anchor"></div>

Expand Down Expand Up @@ -295,6 +301,16 @@ <h4 class="portfolio-title">{{ article.portfolioTitle }}</h4>
<script>
window.totalPages = {{ data.totalPages | json }};
</script>

<noscript>
<style>
#page-main_content {
opacity: 1 !important;
overflow: visible !important;
visibility: visible !important;
}
</style>
</noscript>
<script src="/js/modules/case-studies-page/infinite-scroll.js"></script>

{% endblock main %}
39 changes: 27 additions & 12 deletions website/views/fragments/fragments.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,52 @@
<footer class="sf-footer sf-container">
<div class="sf-footer__content">
<div class="sf-footer__top">
<p class="sf-footer__tagline">A Deliberately Developmental Organization.</p>
<p class="sf-footer__tagline">
A Deliberately Developmental Organization.
</p>
<p class="sf-footer__tagline">Built by real people, for real impact.</p>
<p class="sf-footer__tagline">Let's grow something meaningful together.</p>
<p class="sf-footer__tagline">
Let's grow something meaningful together.
</p>
</div>

<div class="sf-footer__links">
<div class="sf-footer__links-group">
<a href="https://www.linkedin.com/company/speed-and-function/"
class="sf-footer__links-item"
target="_blank"
rel="noopener noreferrer">
<a
href="https://www.linkedin.com/company/speed-and-function/"
class="sf-footer__links-item"
target="_blank"
rel="noopener noreferrer"
>
linkedin
</a>
<a href="mailto:connect@speedandfunction.com"
class="sf-footer__links-item">
<a
href="mailto:connect@speedandfunction.com"
class="sf-footer__links-item"
>
connect@speedandfunction.com
</a>
</div>
<a href="/privacy-policy" class="sf-footer__links-item sf-footer__links-item--policy">
<a
href="/privacy-policy"
class="sf-footer__links-item sf-footer__links-item--policy"
>
privacy policy
</a>
</div>

<div class="sf-footer__bottom">
<p class="sf-copy">&#169; {{ data.currentYear or '2025' }} S&amp;F</p>
</div>
</div>
</footer>
{% endfragment %} {% fragment breadcrumbs() %} {% if data.page._url !=
data.home._url %}
<nav class="breadcrumb" aria-label="Breadcrumb navigation">
<nav
class="breadcrumb loading"
aria-label="Breadcrumb navigation"
aria-busy="true"
>
<ol class="breadcrumb-list">
{% for page in data.page._ancestors %}
<li class="breadcrumb-item">
Expand Down
19 changes: 14 additions & 5 deletions website/views/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@
<div
class="bp-wrapper relative"
data-barba="wrapper"
data-barba-namespace="home"
>
{% render fragments.header() %}
<main
class="bp-main"
role="main"
id="main"
{% if not data.user %}
data-barba="container"
data-barba="container"
data-barba-namespace="{{ (data.page and data.page.type) or 'default' }}"
{% endif %}
>
{% render fragments.breadcrumbs() %}
<div class="sf-container">
<div class="sf-container loading" aria-busy="true" data-reveal="dom">
{% endblock %}

{% block main %}
Expand All @@ -46,7 +46,16 @@
</div>
</main>
{% render fragments.footer() %}
<script type="text/javascript"></script>
<noscript>
<style>
.breadcrumb.loading,
.sf-container.loading {
opacity: 1 !important;
overflow: visible !important;
visibility: visible !important;
}
</style>
</noscript>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
</div>
{# Close .bp-wrapper #}
{# Close .bp-wrapper #}
{% endblock %}
Loading