-
Notifications
You must be signed in to change notification settings - Fork 17
New landing page design #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Preview the changes: https://turinglang.org/pr-previews/119 |
If anyone is interested, then please feel free to take on this PR! |
* very basic redesign * make buttons interactive
* add dangling code example * add code example section
* quickfix alignment * add news and clean up scss
* improve colors * better link hover color
* paste in svg * responsive svg header
using the same background colour for the team "cards" as for the non-hoverable cards on the landing page
- added links to discourse and slack to the buttons at the top of the page - moved link to libraries page to "Learn more" section
Co-authored-by: Penelope Yong <[email protected]>
0046a57
to
e9e14d5
Compare
I will definitely have time to finish this in July. Which points would you like to see addressed before this PR can be merged? |
Revisiting this. Is there a reason why the old PR was closed? Also, I'd personally be happy to merge if some of the placeholder content is removed. Honestly, it's not like the existing front page has any resources, so even a fairly clean slate would be a huge improvement over the current one. |
@penelopeysm Just let me know your comments on current state of this PR whenever you have some time! |
Very nice @shravanngoswamii! Could you also add this paper https://dl.acm.org/doi/10.1145/3711897? I'll work on the placeholder text now. |
There are some annoyances with the light/dark mode toggle (e.g. how it resets the animation), but I don't think they can be fixed while we are still using Quarto. (#110, but who has the time for that...) |
🤷♀️ |
Also, let's look at the Alan Turing Institute website and try to add the ATI logo or branding material on our landing page. Cc @mhauru, who is coordinating this, I believe. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I'm done here.
Final comments:
-
Is there a way to scroll the news carousel with the mouse? Right now there's some dragging behaviour but I think just plain x-scrolling would be more intuitive.
-
The animation at the top replays when anything happens -- light/dark mode toggle is one but it also restarts when the window is resized. Is there a way to fix this?
Yep, I will do this, I was thinking of some better ways for this but let's try a mouse scroll
Actually, this isn't a Quarto issue, something on our side is triggering this, let me take a look at it! |
https://www.turing.ac.uk/contact-us/our-brand Could someone please request the logo of The Alan Turing Institute and share it here? As for how to display the branding material, here are a few suggestions:
Please suggest a better one... |
I've requested the Turing Institute logo file from our comms team, I'll send it to you @shravanngoswamii once I get it. |
…b.io into new-landing-page
Here is the News Carousel code for landing page, putting it here for just in case we want to use it again in future: News Carousel Code
File: _news-carousel.ejs/```{=html}
<div id="news-carousel-container">
<div id="news-carousel-track">
<% for (const item of items) { %>
<div class="news-carousel-slide">
<a href="<%- item.path %>" class="news-carousel-card">
<div class="news-carousel-card-body">
<h5 class="news-carousel-title"><%- item.title %></h5>
<p class="news-carousel-reading-time"><%- item['reading-time'] %> read</p>
<% if (item.description) { %>
<p class="news-carousel-description"><%- item.description %></p>
<% } %>
<div class="news-carousel-attribution">
<span class="news-carousel-author"><%- item.author %></span>
<span class="news-carousel-date"><%- item.date %></span>
</div>
</div>
</a>
</div>
<% } %>
</div>
</div>
/``` File: news.qmd---
listing:
- id: news-carousel
contents:
- "news/posts/*/index.qmd"
template: _includes/news/_news-carousel.ejs
sort: "date desc"
---
### News
::: {#news-carousel}
:::
\```{=html}
<div class="d-flex flex-column align-items-center gap-0">
<a href="news/" class="button btn">
See all news →
</a>
</div>
<style>
/* Scoped styles for the news carousel to avoid conflicts with global themes */
#news-carousel-container {
overflow: hidden;
position: relative;
width: 100%;
cursor: grab;
}
#news-carousel-container.grabbing {
cursor: grabbing;
}
#news-carousel-container #news-carousel-track {
display: flex;
align-items: stretch;
}
#news-carousel-container .news-carousel-slide {
flex-shrink: 0;
width: 33.3333%;
padding: 0.5rem;
box-sizing: border-box;
}
@media (max-width: 1024px) {
#news-carousel-container .news-carousel-slide {
width: 50%;
}
}
@media (max-width: 768px) {
#news-carousel-container .news-carousel-slide {
width: 100%;
}
}
#news-carousel-container .news-carousel-card {
overflow: hidden;
display: flex;
flex-direction: column;
height: 100%;
text-decoration: none;
border-radius: 0.5rem;
transition: background-color 0.3s ease, border-color 0.3s ease;
background-color: #ffffff;
border: 1px solid #e9ecef;
color: #212529;
}
#news-carousel-container .news-carousel-card:hover {
background-color: #e9ecef;
border-color: #dee2e6;
}
#news-carousel-container .news-carousel-card-body {
flex-grow: 1;
display: flex;
flex-direction: column;
padding: 1rem;
}
#news-carousel-container .news-carousel-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 0.25rem;
color: #212529;
font-weight: 700;
}
#news-carousel-container .news-carousel-reading-time,
#news-carousel-container .news-carousel-description,
#news-carousel-container .news-carousel-attribution {
color: #6c757d;
}
#news-carousel-container .news-carousel-reading-time {
font-size: 0.9em;
margin-bottom: 0.75rem;
}
#news-carousel-container .news-carousel-description {
flex-grow: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 1rem;
}
#news-carousel-container .news-carousel-attribution {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 1em;
font-size: 0.85em;
margin-top: auto;
}
#news-carousel-container .news-carousel-author {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
#news-carousel-container .news-carousel-date {
white-space: nowrap;
flex-shrink: 0;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
const carouselContainer = document.getElementById('news-carousel-container');
const carouselTrack = document.getElementById('news-carousel-track');
if (!carouselContainer || !carouselTrack || !carouselTrack.children.length) {
return;
}
const slides = Array.from(carouselTrack.children);
const displayDuration = 2000;
let currentTranslate = 0;
let prevTranslate = 0;
let currentIndex = 0;
let intervalId;
// Interaction state variables
let isDragging = false;
let startPos = 0;
let hasDragged = false;
let wheelTimeout;
let isWheeling = false;
const getItemsPerView = () => {
const width = window.innerWidth;
if (width <= 768) return 1;
if (width > 768 && width <= 1024) return 2;
return 3;
}
const getPositionX = (event) => {
return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX;
}
const startAutoplay = () => {
stopAutoplay();
intervalId = setInterval(autoplayNext, displayDuration);
}
const stopAutoplay = () => {
clearInterval(intervalId);
}
const setSliderPosition = () => {
carouselTrack.style.transform = `translateX(${currentTranslate}px)`;
}
const setPositionByIndex = () => {
if (slides.length === 0) return;
const itemsPerView = getItemsPerView();
const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
if (currentIndex > maxIndex) currentIndex = maxIndex;
if (currentIndex < 0) currentIndex = 0;
const slideWidth = slides[0].getBoundingClientRect().width;
currentTranslate = currentIndex * -slideWidth;
carouselTrack.style.transition = 'transform 0.4s ease-out';
setSliderPosition();
}
const autoplayNext = () => {
if (document.hidden || isDragging) return;
const itemsPerView = getItemsPerView();
const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
currentIndex++;
if (currentIndex > maxIndex) {
currentIndex = 0;
}
setPositionByIndex();
}
function handleDragStart(event) {
isDragging = true;
hasDragged = false;
startPos = getPositionX(event);
const style = window.getComputedStyle(carouselTrack);
const matrix = new DOMMatrix(style.transform);
prevTranslate = matrix.m41;
carouselContainer.classList.add('grabbing');
carouselTrack.style.transition = 'none';
stopAutoplay();
}
function handleDragMove(event) {
if (!isDragging) return;
const currentPosition = getPositionX(event);
currentTranslate = prevTranslate + currentPosition - startPos;
setSliderPosition();
if (Math.abs(currentPosition - startPos) > 10) {
hasDragged = true;
}
}
function handleDragEnd() {
if (!isDragging) return;
isDragging = false;
carouselContainer.classList.remove('grabbing');
const movedBy = currentTranslate - prevTranslate;
const itemsPerView = getItemsPerView();
const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
if (movedBy < -50 && currentIndex < maxIndex) {
currentIndex++;
}
if (movedBy > 50 && currentIndex > 0) {
currentIndex--;
}
setPositionByIndex();
startAutoplay();
}
function handleWheel(event) {
event.preventDefault();
if (isWheeling) return;
isWheeling = true;
stopAutoplay();
const itemsPerView = getItemsPerView();
const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
const delta = event.deltaY;
if (delta > 0) {
if (currentIndex < maxIndex) currentIndex++;
} else if (delta < 0) {
if (currentIndex > 0) currentIndex--;
}
setPositionByIndex();
clearTimeout(wheelTimeout);
wheelTimeout = setTimeout(startAutoplay, 500);
setTimeout(() => { isWheeling = false; }, 100);
}
carouselContainer.addEventListener('mousedown', handleDragStart);
window.addEventListener('mouseup', handleDragEnd);
window.addEventListener('mousemove', handleDragMove);
carouselContainer.addEventListener('touchstart', handleDragStart, { passive: true });
window.addEventListener('touchend', handleDragEnd);
window.addEventListener('touchmove', handleDragMove, { passive: true });
carouselContainer.addEventListener('click', (e) => {
if (hasDragged) {
e.preventDefault();
}
}, true);
carouselContainer.addEventListener('wheel', handleWheel, { passive: false });
carouselContainer.addEventListener('mouseenter', stopAutoplay);
carouselContainer.addEventListener('mouseleave', startAutoplay);
document.addEventListener('visibilitychange', () => document.hidden ? stopAutoplay() : startAutoplay());
window.addEventListener('resize', setPositionByIndex);
setPositionByIndex();
startAutoplay();
});
</script>
\``` File: theming/theme-dark.scss:// Dark mode styles for the news carousel
#news-carousel-container {
.news-carousel-card {
border: 1px solid transparent !important;
color: $body-color !important;
&:hover {
border-color: $lp-cyan !important;
}
}
.news-carousel-title {
color: $body-color !important;
}
.news-carousel-reading-time,
.news-carousel-description,
.news-carousel-attribution {
color: $text-muted !important;
}
} |
@mhauru, here is the size and position of the logo: Preview Link. We have a fixed height of 80px, and the width will automatically adjust to maintain the aspect ratio. Please provide the logo in both light mode and dark mode versions. If the dark mode version is unavailable, we can invert the colors for the ATI logo. Does this work for you? I think it would be helpful for @yebai and @penelopeysm to review the design before we request the logo. |
Continuing #105
Preview the changes: https://turinglang.org/pr-previews/119