Skip to content

Commit 2094fdf

Browse files
committed
Add past cohorts directory, offtime outlets resource, and ticker/photo tweaks
- Split the cohort directory by a new Status column (Upcoming/Past), adding a "Past cohorts" section with gray CohortRows and dropping the sign-up arrow when a row has no Form link - Add "Offtime Outlets index" resource card to the facilitation page - Add "CALL 1-844-OFFLINE" to the ticker - Add the "what to bring" illustration above its section header - Bump CohortRow header text to the Workbench "Overexposed" variation - Fix cropped photos in the homepage photo strip and add spacing above it
1 parent f4f3adf commit 2094fdf

11 files changed

Lines changed: 97 additions & 19 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ in `src/lib/cohorts.js`):
3737
- `ORGANIZERS` — organizer name(s)
3838
- `FORM` — sign-up form link
3939
- `MONTH` — start month/date
40+
- `STATUS``Upcoming` or `Past`; controls whether the cohort lists under "Month Offline locations" or "Past cohorts" on the Home page
4041

4142
A non-technical teammate edits this sheet directly to add or update cohorts — no admin UI needed on the site itself. New rows appear on the next build (see `getCohorts()` in `src/lib/cohorts.js`).
4243

public/images/photo-1.png

-2.69 MB
Loading

public/images/photo-2.png

-4.8 MB
Loading

public/images/photo-3.png

-1.79 MB
Loading

public/images/what_to_bring.png

244 KB
Loading
368 KB
Binary file not shown.

src/components/CohortRow.astro

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,34 @@
44
55
This is the component the Google Sheet data will map onto: each row in
66
the sheet (city, state, organizer, sign-up link, start date) becomes one
7-
CohortRow. For now the Home page passes in placeholder rows; wiring it to
8-
the published CSV is the next step.
7+
CohortRow.
8+
9+
`href` is optional. When the sheet's FORM cell is blank there's nothing to
10+
link to, so the row renders as a plain <div> instead of an <a> and the
11+
trailing arrow is left off.
912
*/
1013
interface Props {
1114
location: string; // e.g. "New York City, NY"
1215
date: string; // e.g. "July 2026"
1316
organizer: string; // e.g. "Melissa"
14-
href: string; // the cohort's external sign-up form
17+
href?: string; // the cohort's external sign-up form, if any
18+
color?: 'yellow' | 'gray'; // yellow (default) for upcoming, gray for past cohorts
1519
}
16-
const { location, date, organizer, href } = Astro.props;
20+
const { location, date, organizer, href, color = 'yellow' } = Astro.props;
21+
const hasLink = Boolean(href);
22+
23+
// Astro lets a lowercase variable stand in for the tag name, so the row is
24+
// an <a> when there's somewhere to link to and a <div> when there isn't.
25+
const Tag = hasLink ? 'a' : 'div';
1726
---
1827

19-
<a class="cohort-row" href={href} target="_blank" rel="noopener">
28+
<Tag class={`cohort-row cohort-row--${color}`} {...hasLink ? { href, target: '_blank', rel: 'noopener' } : {}}>
2029
<div class="cohort-row__head">
2130
<span class="cohort-row__title font-display">{location}{date}</span>
22-
<span class="cohort-row__arrow font-display">&gt;&gt;&gt;</span>
31+
{hasLink && <span class="cohort-row__arrow font-display">&gt;&gt;&gt;</span>}
2332
</div>
2433
<p class="cohort-row__organizer">Organized by {organizer}.</p>
25-
</a>
34+
</Tag>
2635

2736
<style>
2837
.cohort-row {
@@ -39,6 +48,14 @@ const { location, date, organizer, href } = Astro.props;
3948
background: color-mix(in srgb, var(--mo-yellow) 80%, white);
4049
}
4150

51+
/* Gray variant — past cohorts, matching the "Read all about it" press box. */
52+
.cohort-row--gray {
53+
background: var(--mo-gray);
54+
}
55+
.cohort-row--gray:hover {
56+
background: color-mix(in srgb, var(--mo-gray) 80%, white);
57+
}
58+
4259
.cohort-row__head {
4360
display: flex;
4461
justify-content: space-between;
@@ -49,6 +66,15 @@ const { location, date, organizer, href } = Astro.props;
4966
.cohort-row__title,
5067
.cohort-row__arrow {
5168
font-size: var(--size-body);
69+
/* Workbench has no real weight (wght) axis — it only has BLED and SCAN,
70+
so `font-weight` was just triggering the browser's faux-bold, which
71+
looked muddy on a pixel font like this. The font's own named
72+
instances step up in heaviness by raising SCAN (letters go from
73+
"Delicate" through "Touching" to "Maximum" as the scanlines merge).
74+
"Overexposed" (SCAN 67) is a couple steps past the site-wide default
75+
of "Touching" (SCAN 21, set via --workbench-axes), so this row reads
76+
noticeably heavier than the rest of the page. */
77+
font-variation-settings: 'BLED' 0, 'SCAN' 67;
5278
}
5379
.cohort-row__arrow {
5480
transition: transform 0.15s ease;

src/layouts/BaseLayout.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ import '../styles/global.css';
8787
<div class="ticker font-display">
8888
<div class="ticker__track">
8989
<span class="ticker__group">
90-
<span class="ticker-date">{initialDate}</span> * <span class="ticker-time">{initialTime}</span> * <a class="ticker__link" href="https://www.offline.community">WWW.OFFLINE.COMMUNITY</a> * ALUMNI COUNTER: 400 PPL * CITY COUNTER: 5 * JOIN THE CHALLENGE * DITCH THE DOOMSCROLL * LOG OFF AND LINK UP * TOUCH GRASS *
90+
<span class="ticker-date">{initialDate}</span> * <span class="ticker-time">{initialTime}</span> * <a class="ticker__link" href="https://www.offline.community">WWW.OFFLINE.COMMUNITY</a> * ALUMNI COUNTER: 400 PPL * CITY COUNTER: 5 * JOIN THE CHALLENGE * DITCH THE DOOMSCROLL * LOG OFF AND LINK UP * TOUCH GRASS * CALL 1-844-OFFLINE *
9191
</span>
9292
<span class="ticker__group" aria-hidden="true">
93-
<span class="ticker-date">{initialDate}</span> * <span class="ticker-time">{initialTime}</span> * <a class="ticker__link" href="https://www.offline.community" tabindex="-1">WWW.OFFLINE.COMMUNITY</a> * ALUMNI COUNTER: 400 PPL * CITY COUNTER: 5 * JOIN THE CHALLENGE * DITCH THE DOOMSCROLL * LOG OFF AND LINK UP * TOUCH GRASS *
93+
<span class="ticker-date">{initialDate}</span> * <span class="ticker-time">{initialTime}</span> * <a class="ticker__link" href="https://www.offline.community" tabindex="-1">WWW.OFFLINE.COMMUNITY</a> * ALUMNI COUNTER: 400 PPL * CITY COUNTER: 5 * JOIN THE CHALLENGE * DITCH THE DOOMSCROLL * LOG OFF AND LINK UP * TOUCH GRASS * CALL 1-844-OFFLINE *
9494
</span>
9595
</div>
9696
</div>

src/lib/cohorts.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Papa from 'papaparse';
1010
// The sheet has one row per cohort. Header names are normalized to UPPERCASE
1111
// (see transformHeader below) so a stray capitalization or space in the sheet
1212
// won't silently blank out a column. Current headers in the sheet:
13-
// CITY | STATE | ORGANIZERS | FORM | MONTH
13+
// CITY | STATE | ORGANIZERS | FORM | MONTH | STATUS
1414
// NB: the organizer column is "ORGANIZERS" (plural) in the live sheet — it must
1515
// match exactly (after uppercasing), so this can't be "ORGANIZER".
1616
const COLUMNS = {
@@ -19,12 +19,19 @@ const COLUMNS = {
1919
organizer: 'ORGANIZERS',
2020
signupUrl: 'FORM',
2121
startDate: 'MONTH',
22+
status: 'STATUS',
2223
};
2324

2425
/**
2526
* Fetch + parse the sheet, returning an array of cohort objects shaped for
2627
* the CohortRow component:
27-
* { location, date, organizer, href }
28+
* { location, date, organizer, href, status }
29+
*
30+
* `status` is lowercased to either "past" or "upcoming" — the Home page uses
31+
* it to sort each cohort into the "Month Offline locations" or "Past
32+
* cohorts" section. Anything other than "Past" in the sheet (including a
33+
* blank cell) is treated as "upcoming", so existing rows without a Status
34+
* cell yet keep showing up under Locations.
2835
*
2936
* If SHEET_CSV_URL isn't set yet, returns an empty array (and warns), so the
3037
* site still builds before the sheet is wired up.
@@ -68,12 +75,16 @@ export async function getCohorts() {
6875
.map((row) => {
6976
const city = (row[COLUMNS.city] || '').trim();
7077
const state = (row[COLUMNS.state] || '').trim();
78+
const status = (row[COLUMNS.status] || '').trim().toLowerCase();
7179
return {
7280
// "City, State" — but tolerate a missing state.
7381
location: [city, state].filter(Boolean).join(', '),
7482
date: (row[COLUMNS.startDate] || '').trim(),
7583
organizer: (row[COLUMNS.organizer] || '').trim(),
76-
href: (row[COLUMNS.signupUrl] || '').trim() || '#',
84+
// Empty string (not "#") when there's no sign-up link, so CohortRow
85+
// can tell "no link" apart from a real href and drop the arrow.
86+
href: (row[COLUMNS.signupUrl] || '').trim(),
87+
status: status === 'past' ? 'past' : 'upcoming',
7788
};
7889
})
7990
// Drop any row without at least a city (e.g. stray blank rows).

src/pages/diy/facilitate-meetups.astro

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const resources = [
2828
{ title: 'Conversation Cards', description: 'weekly prompts to use at each meetup.', href: '/resources/mo_prompts.pdf' },
2929
{ title: 'Facilitation Guides', description: "beat-for-beat structure of the og MO meetups. take what's useful, leave the rest.", href: '/resources/mo_facilitator_guides.pdf' },
3030
{ title: 'Certificates of Completion', description: 'graduate from Month Offline in style.', href: '/resources/mo_certificate.pdf' },
31+
{ title: 'Offtime Outlets index', description: 'invite ppl to add their creative outlet to a shared inventory.', href: '/resources/mo_offtime_outlets.pdf' },
3132
];
3233
---
3334

@@ -64,6 +65,13 @@ const resources = [
6465
detailed facilitation guides for each meetup, or create ur own!
6566
</p>
6667

68+
<img
69+
class="card__photo photo-bring"
70+
src="/images/what_to_bring.png"
71+
width="980"
72+
height="218"
73+
alt="A handbell, a box of crayons, a book, and a portable speaker"
74+
/>
6775
<h3 class="label">What should I bring?</h3>
6876
<ul class="bring">
6977
<li>✶ a handbell to easily get the attention of a large group</li>
@@ -211,6 +219,21 @@ const resources = [
211219
margin-top: 0;
212220
}
213221

222+
/* The "what 2 bring" illustration sits flush on top of its label bar,
223+
like the items are resting on a shelf, so it drops the usual gap
224+
below the photo and the label's own top margin. */
225+
.photo-bring {
226+
display: block;
227+
width: 440px;
228+
max-width: 100%;
229+
margin-left: auto;
230+
margin-right: auto;
231+
margin-bottom: 0;
232+
}
233+
.photo-bring + .label {
234+
margin-top: 0;
235+
}
236+
214237
/* Vertical breathing room around the audio player in the card. */
215238
.card__audio {
216239
margin: var(--space-3) 0;

0 commit comments

Comments
 (0)