diff --git a/PROJECT.md b/PROJECT.md index 30698ce..c37f4f0 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -4,73 +4,57 @@ - Stack: Node/Express + EJS templates + global CSS/JS. - Brand/entity: **AutoTQ** / Golden Hour Medical, Inc. - Content source remains `site.config.js` for factual data (team, literature, testimonials, news, contact). -- This update focused on a stronger visual hierarchy, mixed section layouts, and reduced repetitive card patterns. +- This revision focused on UX/content-structure consistency for people imagery and team bio presentation. ## 2) Updated file structure notes (files changed in this pass) -- `views/layout.ejs` -- `views/index.ejs` -- `views/about-autotq.ejs` - `views/company.ejs` -- `views/research.ejs` -- `views/literature.ejs` -- `views/testimonials.ejs` -- `views/news.ejs` - `public/css/style.css` +- `public/js/main.js` - `PROJECT.md` ## 3) Navigation/routes -- Primary nav: `/`, `/about-autotq`, `/company`, `/research`, `/literature`, `/news`, `/testimonials`, `/contact`. -- **Removed Company Gallery references** from page structure and nav rendering behavior. +- Primary nav remains: `/`, `/about-autotq`, `/company`, `/research`, `/literature`, `/news`, `/testimonials`, `/contact`. +- Team profile links from the Company roster continue to use slug routes (e.g., `/`). -## 4) Design system (refresh) -- Updated primary red toward requested tone: `--brand-red: #d12020`. -- Complementary palette introduced with dark neutrals for contrast bands: - - `--dark: #111315` - - `--dark-soft: #1e2124` - - white/light-gray surfaces for cleaner reading sections. -- Larger red/dark surface usage in hero, strip bands, and CTA moments while keeping body sections clean. +## 4) Design system notes (this revision) +- Reinforced visual logic: profile/headshot treatment is now isolated to the team roster cards. +- Narrative sections (Company mission and Operating mission) continue using neutral/non-profile supporting media (`company4`, `company5`). +- Added dedicated team-roster card styles and a clear CTA hierarchy for bio reveal (`Read bio` button + collapsible panel). ## 5) Component patterns now used -- Alternating split sections (`.split`, `.split-reverse`) for left/right rhythm. -- Media-first blocks (`.media-band`, `.media-stack`, `.video-grid`). -- Quote strip and quote row formats (`.quote-strip`, `.quote-row`) replacing repetitive equal cards. -- Context list and research/doc rows (`.context-list`, `.research-item`, `.doc-row`). -- News rows with left accent instead of repeated large cards. +- Existing split sections and capability cards retained for company narrative blocks. +- New team-specific component set: + - `.team-roster` (2-column responsive grid) + - `.team-person-card` (headshot + person details) + - `.btn-team-bio` (bio reveal control) + - `.team-bio-panel` (collapsible bio region) +- Bio reveal behavior is managed by progressive JS and keeps native button keyboard behavior. ## 6) Content/layout updates by page -- **Home (`index.ejs`)**: kept mixed-layout structure; replaced research-adjacent image with product visual and tightened internal anchor linking. -- **About (`about-autotq.ejs`)**: redesigned with high-contrast statistic showcase (`2`, `92%`, `100%`) and alternating split sections. -- **Company (`company.ejs`)**: moved away from headshot-heavy cards to capability cards + clean people list rows. -- **Research (`research.ejs`)**: added `#sources` anchor and expanded source-adjacent internal CTA links. -- **News (`news.ejs`)**: added `#press-links` anchor and split CTA band to drive research/literature discovery. -- **Literature (`literature.ejs`)**: improved heading hierarchy with section-level H2 and document-level H3 rows; added implementation CTA split section. -- **Testimonials (`testimonials.ejs`)**: kept quote-row format and added balanced contextual section with supporting links. +- **Company (`company.ejs`)** + - Kept non-team sections free of employee portraits in mission/operating mission blocks. + - Reworked “Leadership and specialists” into a true roster with each person’s headshot, name, role, and a `Read bio` button. + - Added collapsible bio panel per person instead of displaying long bios inline by default. +- **Audit pass completed (no edits required):** + - `views/literature.ejs` + - `views/testimonials.ejs` + - `views/about-autotq.ejs` + - `views/research.ejs` + - `views/index.ejs` + - These pages were verified to use non-employee support visuals in narrative sections. -## 7) Media inventory used in redesign -Reused existing configured assets (from `config.assets.images`) across pages: -- `hero`, `product` -- `company1`–`company7` -- no new external assets introduced in this pass +## 7) JS behavior updates +- `public/js/main.js` now includes a scoped team bio accordion behavior: + - Uses `.team-bio-toggle` buttons with `aria-expanded` + `aria-controls`. + - Toggles `hidden` state on associated `.team-bio-panel`. + - Keeps one bio open at a time within the company roster for cleaner scanning. + - Button labels switch between **Read bio** / **Hide bio**. -Added provided YouTube embeds: -- `z7VjjfdjIhU` -- `l2ocd5el0Yc` -- `4PnhBm5WIg0` -- `rI2n9TlMYIU` - -## 8) SEO and UX pass (this revision) -- Added global per-page metadata defaults in `views/layout.ejs`: - - unique `` + meta description mapping by `pageName` - - canonical URLs - - Open Graph + Twitter card defaults -- Improved internal linking and anchors: - - Home evidence CTA links to `/research#sources` - - News press list has `#press-links` - - Research source section has `id="sources"` -- Replaced homepage research-adjacent visual with product imagery (`config.assets.images.product`) to avoid profile-style mismatch. -- Updated logo presentation in header/footer via transparent styling (removed white box treatment). -- Added shared UI consistency styles for new patterns: `.stats-showcase`, `.capability-grid`, `.people-list`, `.person-row`. +## 8) Accessibility/UX notes +- Team bio interaction is button-based and keyboard accessible by default. +- ARIA state and controlled-region linkage are implemented per card. +- Visual hierarchy now clearly separates abstract/company claims from individual people content. ## 9) Known TODOs -- If route-level rendering does not pass expected `pageName` values on some pages, map those names in server routes so metadata mapping applies exactly. -- Optional next pass: expand structured data (`JSON-LD`) for organization and article/news items. +- Optional next pass: animate panel expansion/collapse while preserving reduced-motion preferences. +- Optional next pass: consolidate legacy unused classes (`.people-list`, `.person-row`, `.team-grid`, `.team-card`) if no longer referenced elsewhere. diff --git a/public/css/style.css b/public/css/style.css index c7fb2ba..b00d4dd 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -242,6 +242,54 @@ p { margin: 0 0 1rem; color: var(--text); } border-radius: 12px; padding: .9rem 1rem; } +.team-roster { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1rem; +} +.team-person-card { + display: grid; + grid-template-columns: 150px 1fr; + gap: 1rem; + align-items: start; + background: #fff; + border: 1px solid var(--border); + border-radius: 14px; + box-shadow: var(--shadow); + padding: 1rem; +} +.team-person-card img { + width: 100%; + height: 150px; + object-fit: cover; + border-radius: 12px; + border: 1px solid #ddd; +} +.team-person-content { + display: grid; + gap: .6rem; +} +.team-role { + margin: 0; + color: var(--muted); + font-weight: 600; +} +.btn-team-bio { + width: fit-content; + background: #fff; + color: var(--brand-red); + border-color: #f1cdcd; +} +.btn-team-bio:hover { + background: #fff5f5; +} +.team-bio-panel { + border-top: 1px solid var(--border); + padding-top: .75rem; +} +.team-bio-panel p { + margin-bottom: .65rem; +} .doc-row h3 { margin-bottom: .3rem; } .brand-footer img { filter: none; } .quote-row { @@ -330,7 +378,7 @@ select:focus-visible { } @media (max-width: 980px) { - .hero-grid, .split, .video-grid, .news-testimonials, .footer-grid, .form-grid, .team-grid, .team-card, .quote-row, .stats-showcase, .capability-grid { grid-template-columns: 1fr; } + .hero-grid, .split, .video-grid, .news-testimonials, .footer-grid, .form-grid, .team-grid, .team-card, .quote-row, .stats-showcase, .capability-grid, .team-roster, .team-person-card { grid-template-columns: 1fr; } .person-row { flex-direction: column; } .split-reverse .split-copy, .split-reverse .split-media { order: initial; } diff --git a/public/js/main.js b/public/js/main.js index 3d965e3..9482c84 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -59,6 +59,44 @@ reveals.forEach((el) => el.classList.add('is-visible')); } + const teamBioToggles = document.querySelectorAll('.team-bio-toggle'); + if (teamBioToggles.length) { + const closeBioPanel = (button) => { + const panelId = button.getAttribute('aria-controls'); + const panel = panelId ? document.getElementById(panelId) : null; + if (!panel) return; + + button.setAttribute('aria-expanded', 'false'); + button.textContent = 'Read bio'; + panel.hidden = true; + }; + + teamBioToggles.forEach((button) => { + button.addEventListener('click', () => { + const panelId = button.getAttribute('aria-controls'); + const panel = panelId ? document.getElementById(panelId) : null; + if (!panel) return; + + const isExpanded = button.getAttribute('aria-expanded') === 'true'; + const roster = button.closest('[data-team-roster]'); + + if (roster) { + roster.querySelectorAll('.team-bio-toggle[aria-expanded="true"]').forEach((openBtn) => { + if (openBtn !== button) closeBioPanel(openBtn); + }); + } + + if (isExpanded) { + closeBioPanel(button); + } else { + button.setAttribute('aria-expanded', 'true'); + button.textContent = 'Hide bio'; + panel.hidden = false; + } + }); + }); + } + const contactForm = document.getElementById('contactForm'); const status = document.getElementById('formStatus'); const endpoint = 'https://api.corben.world/forms/af90392e-9399-4778-9b80-9eed83580f1d/submit'; diff --git a/views/company.ejs b/views/company.ejs index 2683d7e..ae70409 100644 --- a/views/company.ejs +++ b/views/company.ejs @@ -44,14 +44,30 @@ <section class="section section-alt"> <div class="container"> <h2>Leadership and specialists</h2> - <div class="people-list"> - <% (config.team || []).forEach(member => { %> - <article class="person-row reveal" data-reveal> - <div> + <div class="team-roster" data-team-roster> + <% (config.team || []).forEach((member, index) => { + const bioId = `team-bio-${index}`; + const imageSrc = config?.assets?.images?.[member.image]; + %> + <article class="team-person-card reveal" data-reveal> + <% if (imageSrc) { %> + <img src="<%= imageSrc %>" alt="<%= member.name %> headshot" loading="lazy" /> + <% } %> + <div class="team-person-content"> <h3><%= member.name %></h3> - <p><%= member.role %></p> + <p class="team-role"><%= member.role %></p> + <button + class="btn btn-team-bio team-bio-toggle" + type="button" + aria-expanded="false" + aria-controls="<%= bioId %>"> + Read bio + </button> + <div class="team-bio-panel" id="<%= bioId %>" hidden> + <p><%= member.bio %></p> + <a class="text-link" href="/<%= member.slug %>">View full profile →</a> + </div> </div> - <a class="text-link" href="/<%= member.slug %>">View profile →</a> </article> <% }) %> </div>