The spreadsheet
The whole of ETS27 is one shared spreadsheet: grey cells, row numbers, a formula bar, four track colours borrowed from the Texas grid gauge, and FREE YOUR MIND typed into the sheet at about 269 px. The mind is a collaborator in that sheet: its cursor carries a black name flag, it fills cells to answer you, and it keeps typing answers for other visitors while you read.
The story
Everyone in the ETS audience lives in spreadsheets, which is exactly why nobody expects a summit to be one. The page opens on a sheet and nothing else. The frozen title row carries the facts (ETS27 · Energy Thought Summit · Free Your Mind · Austin, Texas · May 3–6, 2027 · Tickets from $320.89). Row 2 prints the fork as two verbs. Rows 3 to 24 hold the theme as a floating text box fitted to columns A–L, its baselines sitting on gridlines and the gutter numbers running beside the letters like a ruler.
Beside MIND, the mind has pasted five of Tuesday's speakers in two tiers (H15, J15 and L15, then I19 and K19), each cropped from the nose bridge up at one scale. This is the owner's original seed image (a head from the nose bridge up: a mind in free space), rebuilt from real people instead of a mannequin. Apple Vision face landmarks find each person's eye line, so every crop ends exactly on the nose bridge. A crop rule refuses any photo that would need a blurry upscale, has no room above the eyes, would push the face off-centre or would hide the eyes, plus four photos that were looked at and rejected (sunglasses, a turned face, café bokeh, a soft scan). A refused photo leaves a hatched cell of the same size, never a bad head.
Directly under MIND, in G22:L22, the mind is visibly typing an answer for another visitor (=MIND("where do I stay")), and the cell says "simulated visitor" where it sits. The row is drawn as a single 2 px rule under the text, the formula bar's own grammar, with the mind's flag standing on it. Rows 23 and 24 stay blank, so the answer's selection border is the only heavy rule at the seam, and a still frame always catches the mind mid-sentence.
Under the title is answer 01, "Who's speaking Tuesday". It has a numbered black cell, a 40 px heading, a short caption in the light weight, eleven rows copied from the Tuesday block below with their track colours, and a source footnote.
The rest of the site is the same sheet read downward:
- Theme: a 40 px statement and the ERCOT gauge as a colour band.
- Lineup: 77 rows. Each head is pasted on its own person's row, stepping J, K, L, J, and its corner names the cell it belongs to (A49), so every face pairs with a name. 52 of the 77 have a usable portrait; the others are hatched.
- Four day blocks. Each opens with a 40 px heading and the day's own gauge reading: one row of filled cells that counts its sessions by ERCOT level, in gauge order and in proportion (Tuesday reads Normal 4 · Conserve 5 · EEA 1 1 · EEA 2 1). They are the programme's four stops. Tuesday's eleven source rows are highlighted black inside marching ants, because the answer was copied from them.
- Tickets: the four real Eventbrite tiers in accounting format, with Buy cells.
- Place: one more giant cell, AUSTIN, with latitude, longitude and elevation in the cells beside it, and a venue that honestly reads
#N/Awith a note: announced soon. - A footer state line: snapshot 2026-10-13 · 77 speakers · 50 sessions · sample data.
Sheet tabs are the navigation. The status bar does spreadsheet arithmetic on whatever is selected, and also shows Austin time to the second and the days to go.
Typography
- One family: Mozilla Text (Google Fonts, variable, wght 200–700, no other axes), one font file. It is a plain grotesk with a text-face skeleton and a slashed zero, so every time in the sheet (09:00, 13:30) reads as data. It was chosen because a sheet must look like a sheet and must not be Arial.
- Size 1, 13 px for every cell, the gutter numbers, the column letters, the chrome, the status bar and the cell names in the corners of pasted heads. Line height 18 px, or 17 px where a cell wraps. It stays the spreadsheet default on purpose: the facts row and the answer, which a visitor reads first, are bold or 40 px. Weights:
- 400 for cells.
- 700 for names, session titles, facts and column labels. Labels are uppercase, +0.06 em.
- 300 for the mind's caption.
- Tabular figures throughout.
- Size 2, 40 px on a 44 px line, weight 700, −0.025 em, for every heading: the answer question ("Who's speaking Tuesday"), the day names, Theme, Lineup, Tickets, Place, and the gauge levels (Normal, Conserve, EEA 1, EEA 2). The theme statement uses the same size at weight 300 on a 46 px line.
- Size 3, the title cell. A few lines of JavaScript measure the ink of FREE YOUR and fit it exactly to columns A–L: 268.7 px at 1440 wide, weight 700, −0.04 em. The cap height (0.69 em, about 185 px) spans eight and a half rows, and both baselines sit on gridlines (between rows 12 and 13, and 23 and 24). AUSTIN shares the size. Ratio to the cells: about 21 to 1.
- There is no fourth size. The composer stays 13 px in the frozen bar; its weight comes from the 2 px rule under it and from the black = Type cell.
- Phone: the title stacks FREE / YOUR / MIND at 138 px, the width-bound size, and AUSTIN drops to 104 px so that it stays one word on one line.
Colour world
- The sheet:
- cell
#E9E9E6 - gridline
#C9C9C5, heavier rule#B4B4AF - gutter and column letters
#DCDCD8with ink#5D5D58(4.8:1); selected header#C4C4BF - label rows
#E2E2DE - chrome (formula bar, tabs)
#F3F3F0 - freeze line
#8C8C87 - ink
#121212; secondary text#5D5D58(5.4:1 on the cell grey). - The four tracks take ERCOT's grid-conditions gauge, the meter every Texan in the room checks on a hot afternoon:
- Normal
#23A95B: customers & community. - Conserve
#F5C31C: AI, data & digital. - EEA 1
#F0862A: load, grid edge & policy. - EEA 2
#E2433A: resilience & security (4.6:1 under black text). - These colours appear only as filled cells: key cells, the gauge band, the four day gauge rows, and the note marker on the venue. The
#N/Aitself is set in#B8261E(5.2:1). EEA 3, black, is the level where rotating outages begin, and the sheet says nothing on the programme is black. - Black belongs to the doors and to the mind: the Tickets cell, the "= Type" cell, the answer number, Buy, the mind's flag, and the highlighted source rows.
Layout grammar
- One grid, edge to edge, no page around it:
- a 48 px row-number gutter
- twelve integer-width columns A–L (112 px at 1440)
- a partial column M at the right edge, so the sheet visibly continues
- 22 px rows, the spreadsheet default.
- Frozen at the top: the formula bar (44 px), the column letters (24 px) and row 1 with the facts above the freeze line.
- Fixed at the bottom: the sheet tabs (34 px) and the status bar (24 px).
- Every unit is a row. Sessions are time · format · title (six columns) · speakers (three) · track key. Speakers are name · title · organisation · first slot · three columns of pasted heads.
- Merged ranges carry headings, and blank rows carry breath. Floating objects are anchored in cells the way a sheet anchors them: the title text box, and portrait crops one column wide and three rows tall, each on its own person's row.
- Tempo changes come from the sheet's own tools: a 40 px statement, the gauge band in proportional widths (3 : 4 : 3 : 2 columns for 9 : 12 : 7 : 4 sessions), a gauge row in integer columns under each day heading, the black Tuesday band, and AUSTIN.
- The whole desktop page is 225 rows, about 6,120 px.
- Phone at 390: still a sheet. It reflows to a 28 px gutter and three columns (64 px, flexible, 78 px), with two-line rows.
- The facts become two lines beside a black Tickets cell.
- Every hero row stays: the live row runs full width on two lines under MIND, the flag above it, and two heads are pasted under it at the right edge.
- Each key names its track and its ERCOT level ("Customers / Normal"), so colour is never the only channel. The day gauge rows keep their proportions and carry the counts.
- The lineup opens as a sheet filter on the 16 keynotes and moderators. Hidden rows keep their numbers, so the gutter skips and a heavier gutter line marks the gap, and the row under them shows all 77 in place. Each row puts a head from the nose bridge up in column A; its second line is the title, then the organisation after the dot, wrapping to two lines so only the organisation can clip.
- AUSTIN keeps seven rows and hides the rest. The phone page runs to about 9,650 px.
Motion and life
- On load:
- The composer types
=MIND("Who's speaking Tuesday")and the status bar reads Calculating. - The mind's cursor hops cell to cell and fills answer 01, about 2.3 s in all; the heading records the time it took.
- It pastes the five heads (two on the phone).
- The visitor's own selection settles on A25:L37, with the column letters and row numbers darkened as in any sheet. The status bar sums the selection: Count 11 · Sum 5 h 45 min · Avg 31 min. Marching ants stay around the Tuesday rows the answer was copied from.
- Then the mind keeps working. In the row under MIND it types answers for other visitors at human speed, with jitter, and loops through five real questions answered from the data. The resting frame is therefore always mid-sentence.
- Other live elements:
- the Austin clock ticks every second
- days to go are computed in Austin's time zone
- a "minds in this sheet" counter drifts; it reads "simulated" beside the number, and the footer says so too.
- Typing a question dims every row the mind does not mean, answers included, and the status bar counts the matches. Enter inserts a new numbered block (02, 03 …) under the last one, and every row number below shifts, as inserting rows does; the cell names on the pasted heads follow.
- Clicking a column label sorts its block. Clicking a computed cell shows its formula in the status bar (
=299.00+21.89,=VENUE("ETS27")). - Reduced motion gets the finished state at once and no live loop.
- With JavaScript off, everything is readable: the answer, the title at a CSS-fitted size, the heads and every fact.
The fork and the mind
- The fork is printed as two verbs in row 2, weighted differently:
- ↓ Scroll reads the programme in order. This is the standard route: the sheet read downward, with sheet tabs as the navigation.
- = Type, set in a black cell, asks the mind. This is the interactive route: the sheet rearranged, with answer blocks inserted at the top.
- Both doors are the same object. There are no cards and no gate.
- The composer is the formula bar. One 2 px ink rule runs under
=MIND("…")and under the three suggested questions set on the same line ("who speaks wednesday", "what does a pass cost", "where is it"). There is no box, no pill and no send button; Enter is the sheet's own. Typing=anywhere on the page, or clicking the black = Type cell, focuses it. Because the formula bar is frozen on every scroll position, it is the omnipresent assistant of the standard route. - On the phone the formula takes the first line of the bar and the suggested questions take the whole second line: two whole questions, and the third a sideways scroll away. Narrow laptop widths shorten them without losing the verb ("who speaks wed", "what it costs").
- An answer is first a change in the material: rows dim while you type, then the cursor fills cells. It then becomes a section in the grid:
- a black number cell
- the question in sentence case at 40 px
- a caption of at most 45 words in the light weight
- rows copied from the sheet's own records, with their own columns and colours
- the source as a footnote row.
- Older answers stay as blocks you can re-read and sort.
- The mind is never a face, an orb or a bubble. It is a collaborator's cursor with a black flag. Other visitors' questions surface as the mind typing their answers under the word MIND, which is the "asked on this page" mechanic in spreadsheet form.
- State is exposed lab-notebook style in the status bar, the footer state line and every answer's footnote.
What to build next
- Real data. Swap the ETS26 stand-ins for the ETS27 lineup and agenda as they are announced. The generator lives in
src/:python3 -I -B src/gen.py index.htmlreadsprototype/data/ets.sample.json,src/faces.jsonand the crop rule insrc/crops.py, and writes this static sheet byte for byte. To redo the crops, runswift src/faces.swiftagainst fresh portraits; it writes the face landmarks. - The mind as a service. Route
=MIND()to the model with the sheet's rows as its only context: the brief's structured answer, a short say-line plus row ids. Stream cells back in the same typing choreography, and keep the dim-while-typing preview local. - Real other-visitor questions, moderated and anonymised, queued into the live cell. This replaces the simulated counter and the scripted questions.
- Export. Offer "download this sheet" as .xlsx or .csv of the programme, plus a calendar file per row. Other event sites struggle to offer this, and here it is trivial.
- Accessibility. The title is already a level-one heading and only the status bar's mode cell is a live region. Still to build: grid semantics (real row and column headers), arrow-key cell navigation, and a screen-reader summary of each answer block.
- Production portraits. Copy them into the build instead of hotlinking, re-run the nose-bridge crop on the ETS27 headshots, and agree the crop style with speakers, with a full-portrait fallback.
- Consent. When a consent notice is needed it appears as the sheet's message bar under the formula bar, never as a strip over the tabs, which are the navigation.
Risks
- Boredom, the risk the seed names. The defence is scale (a 269 px cell), the heads, the colour cells and a mind visibly typing. If any of these go, the page is a table. The sheet must stay edge to edge: never wrap it in a container and never put a hero above it.
- Spreadsheet cosplay. The chrome is deliberately generic (formula bar, tabs, status bar; no ribbon, no product icons), and every control on it works. A dead toolbar would kill the idea.
- The crops. Some speakers or Zpryme may find the nose-bridge crop strange. It needs consent and a fallback to full portraits. Today 25 of the 77 lineup rows are hatched (18 without a photo, one where no face was found, six refused), which reads honestly but leaves gaps in the paste-up.
- Sample data. 77 real people spoke at ETS26 and none is confirmed for ETS27. The sheet flags this in the lineup header, the answer footnote, the status bar and the footer, and those flags must survive until the real data lands.
- Length. The desktop page is 225 rows. The lineup is still one long beat carried by the heads; the day gauge rows give the programme four stops. The phone opens the lineup filtered and runs to about 9,650 px.
- Overlap with the lattice concept. Both treat the programme as a ledger. This one is literal (a working sheet with chrome, rows and a cursor) and grey; the lattice is abstract and teal.
- Simulated elements. The minds counter and the scripted other-visitor questions are simulated in this mockup and say so where they sit. They must become real or be removed before launch.