Basic pages
Five bodies of a basic page, and the only markup in this library the theme does not control: whatever an author typed into CKEditor, reached through one class, `.text-formatted`. Plain prose, code blocks, links dressed as buttons, tables drawn in the editor, and the wrappers an author adds expecting a rule to exist. The classes are real -- they were read out of the `html_tag_usage` report over four of the sites -- but the content is made up and nothing is saved.
A page of prose
The ordinary case, and the one every other page here is a departure from: headings, paragraphs, lists and links, with no classes on most of it. What the report turned up on top of that is four classes an author reaches for often enough to be worth styling -- `p.label` for the line that names the thing under it, `p.compact` for a run of lines that belong together, `p.plain`, and `h3.section-header` and `h3.section-title` for a heading that opens a part of a long page. Two of those the theme has rules for and two it does not, which is the point of showing them side by side. The measure of this column is the one thing the theme has no rule for at all: `--text-formatted-max-width` is declared at 72ch in the variables and then never used, so prose here runs the full width of whatever holds it.
Booking a room
Every room in the building can be booked by anyone with an account, for any period up to a full working day. Bookings close at midnight on the day before, and a room left unclaimed for fifteen minutes goes back into the pool.
Who can book
Staff, for any room.
Students, for the four rooms on the ground floor.
Visitors, through the person who invited them.
What a booking holds
A booking is a room, a period and a purpose. The purpose is shown on the screen outside the door, so keep it short and keep it accurate — it is the only thing anyone walking past has to go on.
- The room, which cannot be changed once the booking is made.
- The period, in half hours, which can.
- The purpose, which is public.
- A note to the caretaker, which is not.
Changing one
Open the booking and edit it. There is no separate cancel: clear the period and save, and the room is released. A booking that has already started can be shortened but not moved, because the screen outside the door has already announced it.
- Find the booking under My bookings.
- Change the period, or clear it.
- Save. The screen updates within a minute.
Rooms 1 to 4 have a hearing loop. Room 7 does not, and the lift to it is out until March.
The room is the least of it. Book the room, then tell the people.
Written by the facilities team. Corrections to facilities@example.com, or through the form on the intranet. There is a printer friendly version at the foot of every page.
A page of code
`code` carries a class more often than any other tag in the report: 53 of them on `theme`, and every one of them a `language-*` from Prism. Across the four sites the languages actually saved are php (78), plaintext (67), yaml (42), javascript (30), twig (18), css (11), html (5), and then single figures of bash, json, sql, xml, diff, ini, typescript, apache and coffeescript. Six of them are below. The pairing is always the same and it matters: the class goes on the `code`, inside a `pre` that carries none, so a rule written against `pre` alone reaches the block and a rule written against `.language-css` alone reaches only the inner element. The theme has one rule for the pair, and it is a repair -- `:is(code, pre)[class*=language-]` resets `--link-color` to `currentColor`, because the link colour was leaking into the syntax highlighting. Nothing is highlighted on this page even though the Prism module is installed: its library is attached by the text format filter as a field is rendered, and there is no field and no filter here -- so this is the classed markup without the script, which is also what the page looks like before the script has run.
Declaring a table column
A column is declared once and applied everywhere it has to be applied. The component takes the role and puts it on the header cell and on every body cell beneath it.
$build['table'] = [
'#type' => 'component',
'#component' => 'mantra_starter:table',
'#props' => [
'columns' => [
['header' => $this->t('Component'), 'role' => 'grow'],
['header' => $this->t('Summary'), 'role' => 'text-sm'],
],
'rows' => $rows,
],
];
The same thing from a template, where the props are handed over as a mapping:
{{ include('mantra_starter:table', {
columns: [
{ header: 'Component'|t, role: 'grow' },
{ header: 'Summary'|t, role: 'text-sm' },
],
rows: rows,
}, with_context = false) }}
What the component declares
Every value the role can take is enumerated in the component's metadata, so an unknown one fails validation rather than rendering as a class nobody styled.
props:
type: object
properties:
columns:
type: array
items:
type: object
properties:
role:
type: string
enum:
- shrink
- grow
- text-sm
What the roles do
width: 0 is a bid of zero rather than a width, which auto layout
then floors at the minimum width:
.col-shrink {
width: 0;
min-width: fit-content;
white-space: nowrap;
}
.col-grow {
width: 100%;
}
Anything that has to move after the page is rendered is a behaviour, and a behaviour runs once per element:
Drupal.behaviors.exampleTableStyles = {
attach(context) {
once('example-table-style', '[data-table-style]', context).forEach(
(select) => {
select.addEventListener('change', () => render(select));
},
);
},
};
And the measurements the whole thing was settled by, which are not code in any language:
column no role with role
------------ --------- ---------
check box 47px 31px
title 212px 608px
summary 604px 288px
operations 118px 96pxA page with calls to action
`a.button` is the most common authored class in the report after the code languages -- seven on `classes`, four on `theme` -- with `button--primary` and `button--danger` appearing beside it. It is worth its own page because it is the one place where authored content borrows a class the theme owns: `.button` is a component of the design system, styled for the form actions of the back office, and an author reaching for it in a body gets whatever those rules happen to say. The `form-actions` rules do not apply here, and that turns out to be the whole of it: `button--primary` and `button--danger` appear nowhere in the theme except inside those rules, and only as `:not()` exclusions, so neither has a declaration of its own. Measured on this page, all three links below come out identical -- same background, same border, same padding. A body asking for a primary button gets a plain one. `a.formtip` is on this page for the same reason from the other direction: five of them on `architect`, and nothing in the theme matches it.
Applying for a place
Applications open on the first Monday of October and close six weeks later. There is one form, it can be saved and returned to, and nothing is looked at until the window shuts.
Start an application Save and come back later
Before you start
Have the reference numbers of any previous application to hand. The form asks for them and will not let you past the second step without them. Where do I find these?
- A reference number, in the form
AP-2026-0000. - The name of the person who supervised you.
- Two dates, neither of which has to be exact.
If you have applied before
Your previous answers are carried over. Check them: several of the questions changed this year, and a carried-over answer to a changed question is the most common reason an application comes back.
Withdrawing
An application can be withdrawn at any point before the window closes, and cannot be withdrawn after it. Withdrawing deletes the answers rather than hiding them, so take a copy first if you want one.
Questions to the admissions office. The office does not read applications and cannot tell you how yours is going.
A page with tables in it
A table an author draws in CKEditor is not a table Drupal built, and it arrives carrying the editor's own classes: `table` on the element and `table-style-align-center` beside it on `calendar`, `border` on the wrapper, `tr.color` sixteen times on `theme`, and `td[style]` forty-eight times, which is a colour picked in the editor and written inline. It has none of the classes the column width roles are hung on, because nothing in the editor knows about them -- so this is the page where a table gets whatever auto layout decides on its own, and the `table-responsive` and `sticky-enabled` wrappers found in the same content are the author reaching for behaviour the theme provides elsewhere. `sticky-enabled` is worth a note: the theme turns core's sticky header script off and does it in CSS, so the class is inert and the header of the last table here stays put anyway.
Opening hours
The building is open to everyone during core hours and to staff at all times. The times below are the ones on the door.
| Day | Opens | Closes | Desk staffed |
|---|---|---|---|
| Monday to Thursday | 08:00 | 20:00 | 09:00 to 17:00 |
| Friday | 08:00 | 18:00 | 09:00 to 16:00 |
| Saturday | 10:00 | 16:00 | Not staffed |
| Sunday | Closed | ||
Room capacities
Centred in the editor, which writes the alignment as a class on the table rather than on each cell:
| Room | Seated | Standing | Loop |
|---|---|---|---|
| 1 | 12 | 20 | Yes |
| 2 | 12 | 20 | Yes |
| 7 | 40 | 90 | No |
Charges
Wide enough to want the wrapper the author reached for:
| Room | Half day, internal | Full day, internal | Half day, external | Full day, external | Out of hours |
|---|---|---|---|---|---|
| 1 to 4 | £0 | £0 | £45 | £80 | £25 per hour |
| 5 and 6 | £0 | £0 | £60 | £110 | £25 per hour |
| 7 | £20 | £35 | £140 | £260 | £40 per hour |
A page of embeds and layout
The last group in the report is the one an author cannot type: `div.raw-html-embed` is what CKEditor 5 wraps a block of pasted HTML in, `p.codepen` is what a CodePen embed leaves behind once its script has run, and `div.columns-2`, `div.link-red` and `div.tags` are wrappers somebody added by hand expecting a rule to exist for them. None of those five is styled by the theme, and `columns-2` is the one that shows it: it is two columns in name only. `div.border` is the exception -- it is a real utility and it works. This page is worth keeping because it is the honest inventory of what authored content asks the theme for and does not get.
Getting here
In short
Fifteen minutes from the station, on foot.
Two accessible bays behind the building.
The gate is locked after 20:00.
On foot
Leave the station by the north exit, cross at the lights and follow the canal path east. The path is lit until 22:00 and is level the whole way.
By car
There is no visitor parking. The two accessible bays are bookable with the room and the barrier code is sent the day before.
The map
What the entrance looks like
The embed replaces this paragraph once its script has run. Until then it is a paragraph, and it is styled like one.
Getting in
Out of hours
Ring the bell to the left of the door and wait — the desk is at the back of the building. If nobody comes within five minutes, the number on the card in the window reaches the duty phone.
Deliveries
Deliveries go to the yard, not the front door. The yard gate is the one with the green post beside it.
The lift to the seventh floor is out of service until March. Room 7 is not reachable without stairs during that time.