# Shift Timetable Careers

> A careers section that draws every open role as a shift across one working day under a pinned hours ruler: set the hours you could work and the roles that fit rise to the top, each shift filling where it overlaps.

Canonical: https://gsapvault.com/sections/shift-timetable-careers-section
Live demo: https://gsapvault.com/demos/shift-timetable-careers-section/index.html

| Property | Value |
|----------|-------|
| Type | section |
| Tier | paid |
| Price | Included only in the Vault |
| Difficulty | advanced |
| Plugins | Flip |
| Techniques | flip-layout, filter, range-input, custom-properties, keyboard-navigation, progressive-enhancement, container-queries, responsive-section |
| Uses Lenis | No |

## Overview

Shift Timetable Careers Section is the careers block for an employer whose work runs in shifts: restaurants and bars, hotels, care homes, hospitals, shops, warehouses and transport. It answers an applicant's first two questions, what is it like to work here and is there a role that fits my life, and takes them to an apply page for the role they choose.

A framed photograph of the bar at evening service, with the title in tracked serif capitals set over it, leads straight into the board. Every open role is drawn as a shift on one shared day axis, with the night shaded, so the board shows at a glance which jobs are nights, early mornings or office hours. A dark hours ruler pins to the top of the timetable while the roles scroll beneath it, so every bar can be read against the hours. Drag its two handles or press a quick-hours button such as School hours: the window sweeps down the board, each shift fills with the accent where it overlaps, and the roles regroup under Fits your hours, Overlaps your hours and Outside your hours, each saying how far it runs over. Team buttons narrow the list, and each role opens in place to show a photo, pay, pattern and its apply link. When nothing fits, the section says so and names the nearest shift.

The fictional Calder's example, a restaurant and late bar in Leeds, is set on warm paper in Brygada 1918 with a claret accent; its fourteen roles run from 06:00 deliveries to a bar that closes at two, and each opens onto one of nine further generated documentary photographs of the kitchen, the dining room, the bar and the office. Every role is an ordinary list item with two time elements, so a buyer adds, removes or reorders roles in HTML.

## Features

- Every role drawn as a shift bar on one shared day axis, with the night shaded and overnight shifts drawn as one unbroken bar
- A pinned hours ruler (readout, day axis, two native range handles, fit count) stays at the top of the timetable while the roles scroll, and lets go where the timetable ends
- The chosen window sweeps down every row live and each shift fills where it overlaps
- Roles regroup with GSAP Flip into fits, overlaps and outside, each overlap saying how far it runs over
- Quick-hours buttons (mornings, school hours, office hours, evenings, late nights) sweep the window before regrouping
- Team buttons and counts generated from the markup; counts show how many roles in each team fit your hours
- Honest empty state that names the nearest shift and links to an open application
- Roles open in place with photo, pay, pattern and an apply link
- Interruptible throughout: new input always settles on the last hours requested
- Every role, its hours and its apply link readable with no JavaScript
- Container-aware layout with a sticky hour ruler, independent instances and exact teardown

## Use Cases

- Restaurants, bars and hospitality groups hiring for mornings, service, late bars and closing shifts
- Care homes and hospital bank staff with day, twilight and waking-night shifts
- Retail, warehouse and delivery operators recruiting across shift patterns
- Any careers page where working hours decide whether a role is possible

## Vibe-Code Ready Setup

This website section includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

The section starts as an ordinary ordered list of roles, each with a title, a team, two time elements for the shift and a details block with its apply link. The script reads those times, places each shift on a 24-hour axis that begins at the hour set on the section root (so a late bar shift is one bar), and adds a bar, a status line and a details button to every row. Team buttons are built from the team names in the markup.

The visitor's window is two CSS custom properties on the section. Dragging a handle tweens them towards the new hours; each bar's filled part and the window's column are pure CSS calculations from those two numbers, so the whole board follows the handles every frame without layout work. A moment after the handle is released, the roles are classified, reordered into fits, overlaps and outside with group labels and moved into place with Flip.getState and Flip.from. A quick-hours button tweens the window across the day first and regroups when it arrives.

New input kills the running sweep and tweens from where the window is drawn; a new regroup captures positions mid-flight, kills the previous Flip and continues from there, so repeated or reversed input always settles on the last request. Reduced motion, including a change while the page is open, applies every change instantly, and teardown restores the original list, order and markup.

## Documentation

How this website section works and how it goes into a page. The reference you use once you own the files (worked examples, events, the programmatic API, the class list) ships with the download.

### Quick Start

Copy these into your project:

- the `<section class="stc">` element from `index.html`, between the `EXTRACT START` and `EXTRACT END` comments
- `assets/style.css`
- `assets/script.js`
- `assets/img/` (or your own photographs)

Load the font and styles, then GSAP, Flip and the section script after the markup:

_Code snippet omitted: it ships with the download._

Everything outside the `<section>` in `index.html` (the page background and body margin) is demo furniture. No build step is needed.

### Make it yours

#### Roles

Each role is one `<li class="stc-role">` inside `<ol class="stc-roles" data-stc-list>`. To add a role, copy a whole `<li>` and edit it; to remove or reorder roles, delete or move whole `<li>` elements. Within each group the board keeps your order, so put the roles you most want to fill first.

| What | Where |
| --- | --- |
| Title | `.stc-role__title` |
| Team | `.stc-role__team` text. The team buttons and their counts are built from these, in order of first appearance |
| Place and contract | the rest of `.stc-role__meta` |
| Shift | the two `<time datetime="HH:MM">` elements in `.stc-role__shift` (24-hour clock). A shift that ends earlier than it starts runs past midnight, like `22:00` to `06:00` |
| Description, pay, pattern | `.stc-role__text` paragraph and the `<dl class="stc-role__facts">` rows (add or remove rows freely) |
| Apply link | `.stc-role__apply` `href` and text |
| Photo | `.stc-role__photo img` |

The apply links in the demo point at `https://jobs.example.com/calders/apply?role=...`. Replace each with your applicant tracking system's job URL or your own application page. The **Send an open application** link at the bottom (`.stc__open-link`) is reused by the "nothing fits" message, so point it at a general application or contact page.

There is no count limit and one role works. With a single team the team buttons are hidden. A role without two valid `<time>` elements is treated as "Hours agreed with you": it has no bar and always counts as fitting.

#### The day axis

- `data-day-start="6"` on the section root sets where the axis begins (here 06:00, so a bar shift that runs past midnight is one unbroken bar). Choose the hour when the fewest of your shifts are running; every shift must fit inside the 24 hours that follow it.
- `data-night="22:00-06:00"` sets the darker night band. It may wrap around the axis start. Remove the attribute for no night band.
- The quick-hours buttons (Mornings, School hours, Office hours, Evenings, Late nights, Any time) are plain `<button class="stc-preset" data-from="HH:MM" data-to="HH:MM">` elements inside the `<template data-stc-controls>`; edit, add or delete them. `data-from` equal to `data-to` means the whole day.

#### Masthead

The title, dotted ornament and kicker sit over the masthead photograph in `<div class="stc-hero">`; the lede follows beneath it. All are plain HTML. The count after **Open roles** (`[data-stc-total]`) is filled from the number of roles.

**Masthead photo** (`.stc-hero` `<picture>`):

- Files: `assets/img/bar-hero.webp` (1536 x 1024, with a 960 x 640 copy in `srcset`) for wide screens and `assets/img/bar-hero-portrait.webp` (800 x 1000, a 4:5 crop) in the `<source media="(max-width: 640px)">` for phones.
- Frames: 12:5 on wide layouts and 4:5 in narrow ones, cropped to fill. The title sits over the photo's lower part behind a dark gradient, so choose a photo whose lower third is fairly dark and calm (a counter, a floor, a table edge).
- Replace: change the `src`, `srcset`, `width`/`height` and the `<source>` `srcset`, `width`/`height`, and rewrite the `alt`. With only one file, delete the `<source>` line.
- Focal point: set `--stc-hero-focus` (wide crop, default `50% 60%`) and `--stc-hero-focus-narrow` (4:5 crop, default `50% 50%`) on `.stc`.
- Heading colour over the photo: `--stc-hero-ink` (default `#f6efe2`).

#### Role photos

Role photos appear in each role's opened details (`.stc-role__photo img`): 800 x 533 files framed at 3:2 and loaded lazily. Roles in one team can share a file. Every photo is an ordinary local `<img>`; none is baked into CSS or script.

- **Replace:** change `src`, `width`/`height` to your file's size, and `alt`. Any photo works; it is cropped to fill the 3:2 frame.
- **Focal point:** `object-position` in `.stc-role__photo img` in `style.css`, or per image with `style="object-position: 50% 30%"` (for one image only).
- **Aspect ratio:** change `aspect-ratio` in the same rule.

#### Brand

The brand controls are custom properties on `.stc` at the top of `style.css`:

| Variable | Default | Controls |
| --- | --- | --- |
| `--stc-paper` | `#f0ebdf` | Ground and photo mats |
| `--stc-night` | `#e7e0d0` | Night band on the axis |
| `--stc-ink` | `#2a2520` | Text, rules, frames, bars |
| `--stc-muted` | `#5f574c` | Secondary text |
| `--stc-rule` | 20% ink | Hairlines |
| `--stc-accent` | `#8c2a2e` | Filled part of each shift, window edges, handles, apply buttons |
| `--stc-accent-ink` | `#fbf7ef` | Text on the accent |
| `--stc-accent-bright` | `#e06a6a` | The chosen hours and handles on the dark ruler |
| `--stc-bar`, `--stc-bar-ink`, `--stc-bar-muted` | ink, paper, 74% paper | The pinned hours ruler's ground and text |
| `--stc-stick` | `0px` | How far below the top of the window the ruler pins, e.g. the height of a fixed site header |
| `--stc-band` | 9% accent | The window's tint |
| `--stc-font` | Brygada 1918 | Every text role |
| `--stc-width` | `82rem` | Content width |
| `--stc-gutter`, `--stc-space` | fluid | Side padding, vertical rhythm |
| `--stc-cols` | `21rem 1fr 10rem` | Role, day axis and status columns |

Rebrand example, for a care provider with a cool ground and teal accent:

_Code snippet omitted: it ships with the download._

Keep text colours at 4.5:1 against the paper and the accent-ink at 4.5:1 on the accent.

### Behaviour and options

- `index.html` also defines `window.__thumbnail()` after the section script. It is demo furniture used by our catalogue thumbnail generator (it sets the evening hours on the first instance) and is not part of the section; leave it out of your page.

- `data-duration="0.6"` on the root sets the motion length in seconds (the sweep for a quick-hours button is slightly longer).
- Dragging a handle moves the window live; the roles regroup a moment after you let go, or after a short pause while an arrow key is held. Each quick-hours button sweeps the window, then regroups. New input at any point interrupts the running motion and the board always settles on the last hours requested.
- The script exposes `window.ShiftTimetableCareers`:
  - `mountAll(scope?)` mounts every `[data-shift-careers]` in the document or in `scope` (safe to call again; mounted roots are skipped)
  - `mount(root)` / `get(root)` return an instance with `setHours('09:00', '17:30')` and `destroy()`
  - `destroyAll(scope?)` tears instances down. Teardown kills this section's tweens and Flip animations, removes its listeners and every node it added, and restores the original role order, ids and details, leaving the plain readable list.

### Accessibility and integration

- The hour handles are native range inputs labelled "Earliest start" and "Latest finish", announced as clock times and moved in quarter hours with the arrow keys. Teams are native radio buttons. The result ("Your hours 09:00 to 17:30. 2 roles fit, 10 overlap, 1 outside.") is announced politely after the board settles. Each role's status is visible text, not colour alone.
- Each role opens with a native button (`aria-expanded`, `aria-controls`); closed details are `hidden`, `inert` and `aria-hidden`.
- `prefers-reduced-motion: reduce`, including a change while the page is open, applies every change instantly.
- Without JavaScript the controls never render and every role shows its hours, details and apply link. If GSAP or Flip fails to load, the controls still work without animation.
- Headings: the section title is an `h2`, the board title an `h3`, each role an `h4`. Change the tags freely; the styles target classes.
- The layout responds to its own width (container queries named `stc`), so it works in a narrow column as well as full width.
- The hours ruler is `position: sticky` inside `.stc__timetable`: it pins while the roles scroll and lets go where the timetable ends. If your site has a fixed header, set `--stc-stick` to its height. An ancestor with `overflow: hidden` or `overflow: auto` stops sticky working. While the ruler is pinned, a focused button or link that would sit under it is scrolled clear of it, and after the roles regroup the page scrolls back up to the top of the list so the roles that fit are in view.
- The section does not change page scrolling, install smooth scroll or take over navigation. Two or more copies on a page run independently; a copy that repeats the markup's ids is given its own.

### Dependencies and credits

- [GSAP 3](https://gsap.com) and its Flip plugin (free, standard GSAP licence), from jsDelivr.
- [Brygada 1918](https://fonts.google.com/specimen/Brygada+1918) from Google Fonts, SIL Open Font License.
- Photographs: generated concept images made for this section (the bar at evening service in the masthead, and deliveries at the back door, morning prep, the pass during service, the dish station, lunch and dinner service, the bar at night and after closing, and the events office). They show fictional people and places; replace them with photographs of your own team.
- Calder's, its people, roles and pay are fictional sample content.

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This website section is included only in the Vault, for existing and new owners. It is not sold individually. The standard licence covers unlimited personal and commercial projects; bundled assets retain their own licence requirements.

- [Get the Vault](https://gsapvault.com/pricing)
- [The Vault (£99 one-time, best value): every collection in the Vault library, plus future items added to those collections](https://gsapvault.com/effects)

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
