/*
The whole visual identity of Spectacles.

Three colours and nothing else: a dark red ground, a paper foreground and a
brighter red for anything that asks to be touched.

**The ground here is darker than the icon's, on purpose.** The two were the
same to begin with, and the value that works for a page of text read for
minutes at a time - often in a dark auditorium - left the icon looking
near-black among the others on a home screen. An icon has to be picked out at
a glance beside thirty rivals; an interface has to be comfortable to stare at.
Those pull in opposite directions, so the icon took the livelier red
(#B01822, in tools/make-icons.mjs) and this kept the darker one. Same family,
same paper, different value - and a change to one is not automatically a
change to the other.
*/

:root
	{
	--ink:			#4A1519;	/* the ground */
	--ink-raised:		#5B1D21;	/* a surface lifted off it */
	--ink-sunken:		#3A1014;	/* a surface pressed into it */
	--paper:		#E7E8E2;	/* text and the marks */
	--paper-dim:		#BFA9A8;	/* text that is not the point */
	--accent:		#C1272D;	/* anything that can be touched */
	--accent-dim:		#8C1C22;	/* the same, at rest */
	--radius:		12px;
	--bar-height:		50px;		/* the tab bar itself, without the inset below it */
	--safe-bottom:		env(safe-area-inset-bottom, 0px);

	/*
	How much of the home indicator's inset the bottom chrome actually keeps.

	iOS reports about 34px there, and reserving all of it leaves a band of
	dark red under the tab labels a centimetre deep - which is what it looked
	like on the phone. Nothing may sit under the indicator itself, so the
	inset cannot simply be ignored; it is clamped instead, which keeps the
	labels clear of it and takes the band back down to a few millimetres.
	A device with no indicator reports zero and nothing is reserved at all.
	*/
	--safe-keep:		min(var(--safe-bottom), 12px);

	/*
	The height the action bar occupies, which is nothing on the screens that
	do not have one. The journal sets it through body.has-action-bar, so the
	space is reserved when there is something to reserve it for and not
	otherwise - it used to be reserved always, which left an empty band of
	paler red at the foot of every other screen.
	*/
	--action-height:	0px;
	}

body.has-action-bar
	{
	/*
	What the action bar actually measures: 8px of padding, a 61px button, 8px
	again and the hairline on top. Reserving less than it occupies hides the
	last row of the journal behind it, which is the kind of thing that only
	shows up when the list is exactly long enough to scroll.
	*/
	--action-height:	78px;
	}

*
	{
	box-sizing:		border-box;
	-webkit-tap-highlight-color: transparent;
	}

/*
The hidden attribute wins over every display rule in this file.

The browser hides such an element through its own [hidden] rule, which any rule
written here beats: .sheet below sets display flex, so without this the sheet
stands on screen from the first paint, greys the application out, and its Close
button appears to do nothing because turning the attribute back on changes
nothing. The action bar does the same on every screen but the journal.

The sibling carries this rule for exactly these reasons and it was left out of
the first draft here; a screenshot is what found it, which is the argument for
taking one. Anything hidden by attribute in a screen added later is covered.
*/
[hidden]
	{
	display:		none !important;
	}

/*
The document carries the chrome's colour; only the reading area is lighter.

This is the pale band, and it took four attempts because every one of them
assumed it was at the bottom. A screenshot measured off the phone settled it:
the band is 61 CSS pixels at the **top** as well, both of them exactly the
colour of body's background, with the two bars correctly dark in between.

So nothing in the page draws it. The web view is inset from the screen and iOS
paints what surrounds it from the document's own background - above the first
element and below the last, where no rule of ours reaches. A stylesheet can
only win that argument by making the document's background the colour those
margins ought to be.

Hence the inversion: html and body take the chrome's colour, and .view paints
the lighter ground for the reading area alone. body is a flex column of full
height so .view stretches to fill whatever the content does not, which keeps
the lighter ground from stopping short and leaving a seam of its own.

Restaurants never had this because it never could: its body, its page and its
manifest are all one colour, so the margins match whatever they are painted
from.
*/
html
	{
	margin:			0;
	padding:		0;
	background-color:	var(--ink-sunken);
	}

body
	{
	display:		flex;
	flex-direction:		column;
	min-height:		100vh;
	margin:			0;
	padding:		0;
	background-color:	var(--ink-sunken);
	color:			var(--paper);
	font-family:		-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
	font-size:		16px;
	line-height:		1.45;
	overscroll-behavior-y:	none;
	}

/* ---- the bar at the top ------------------------------------------------- */

.app-bar
	{
	position:		sticky;
	top:			0;
	z-index:		20;
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	padding:		calc(env(safe-area-inset-top, 0px) + 10px) 16px 10px;
	background:		var(--ink-sunken);
	border-bottom:		1px solid rgba(231, 232, 226, 0.10);
	}

.wordmark
	{
	margin:			0;
	font-size:		19px;
	font-weight:		700;
	letter-spacing:		0.01em;
	}

.wordmark span
	{
	font-weight:		300;
	color:			var(--paper-dim);
	}

.app-version
	{
	margin-left:		6px;
	font-size:		11px;
	font-weight:		400;
	color:			var(--paper-dim);
	}

.app-state
	{
	text-align:		right;
	}

.app-status,
.app-offline
	{
	margin:			0;
	font-size:		12px;
	color:			var(--paper-dim);
	}

.app-offline
	{
	color:			var(--accent);
	}

/* ---- the screen --------------------------------------------------------- */

/*
The reading area, and the only thing wearing the lighter ground.

It grows to fill whatever the content leaves over, so the lighter red reaches
the chrome rather than stopping where the last row does and leaving a seam
across the middle of an empty screen.
*/
.view
	{
	flex:			1 1 auto;
	padding:		12px 16px calc(var(--bar-height) + var(--safe-keep) + var(--action-height));
	background-color:	var(--ink);
	}

h2.screen-title
	{
	margin:			4px 0 14px;
	font-size:		15px;
	font-weight:		600;
	text-transform:		uppercase;
	letter-spacing:		0.08em;
	color:			var(--paper-dim);
	}

.empty
	{
	margin:			48px 0;
	text-align:		center;
	color:			var(--paper-dim);
	}

.empty strong
	{
	display:		block;
	margin-bottom:		6px;
	color:			var(--paper);
	font-size:		17px;
	}

/* ---- the list of evenings ----------------------------------------------- */

/*
The month a run of evenings falls under.

White rather than the dimmed paper, for the same reason .show-meta below is:
small uppercase type at 12px with a tenth of an em between the letters is
already quiet enough, and dimming it as well leaves a heading that has to be
looked for on a phone held at arm's length in a foyer.
*/
.month-heading
	{
	margin:			22px 0 8px;
	font-size:		12px;
	font-weight:		600;
	text-transform:		uppercase;
	letter-spacing:		0.08em;
	color:			#FFFFFF;
	}

/*
The card an evening occupies.

The card and the button inside it used to be one element. They are two because
an evening still to come carries the way to its hall underneath, and that is a
link: a link nested in a button is invalid, and Safari makes its own mind up
about which of the two a tap meant. So the card holds the colour and the
corners, the button holds the tap, and the plan sits beside the button rather
than inside it.
*/
.show-entry
	{
	margin-bottom:		8px;
	background:		var(--ink-raised);
	border-radius:		var(--radius);
	overflow:		hidden;
	}

.show-row
	{
	display:		flex;
	gap:			12px;
	width:			100%;
	padding:		10px;
	background:		none;
	border:			none;
	color:			inherit;
	font:			inherit;
	text-align:		left;
	cursor:			pointer;
	}

.show-row:active
	{
	background:		var(--ink-sunken);
	}

/*
What an evening that has not happened yet says for itself.

Marked by a gilt edge rather than by a heading, because there is rarely more
than one of these and a heading over a single row is a lot of furniture for a
sentence. The list is sorted by date and already puts them at the top.
*/
.show-entry.is-ahead
	{
	border-left:		3px solid var(--accent);
	}

.show-plan
	{
	padding:		8px 10px 10px;
	border-top:		1px solid rgba(231, 232, 226, 0.12);
	}

/*
A row of the plan: a quiet label, and the thing itself.

The two are not the same size. The label is furniture - you read "Place" once
and never again - while the seat and the street are what you are holding the
phone to find out, often in a foyer with the lights going down. So the label
keeps the 13px of the meta line and the value is set larger, and the row is
aligned on the baseline the two share rather than on their boxes.
*/
.show-plan-row
	{
	display:		flex;
	align-items:		baseline;
	gap:			8px;
	margin:			0;
	padding:		2px 0;
	font-size:		13px;
	color:			var(--paper);
	}

.show-plan-key
	{
	flex:			0 0 60px;
	color:			var(--paper-dim);
	}

.show-plan-value
	{
	font-size:		15px;
	color:			#FFFFFF;
	}

/*
The countdown, which is the one line of the three worth reading across a room.
*/
.show-plan-row.is-left
	{
	padding-bottom:		4px;
	font-size:		15px;
	font-weight:		600;
	color:			var(--accent);
	}

/*
The address, which leaves for Maps.

White and underlined, not red: it carries .show-plan-value like the seat does,
because it is a street address first and a link second. What it has to do is
be read at a glance, and the touchable red is a darker ink than the paper on
this ground - it was the quietest thing in the block when it is one of the two
things the block exists for. The underline is what says it can be tapped, and
it is the only underline on the screen.

The padding is vertical only: a link in a row of text cannot be made 44px
tall without pushing the rows apart, so it is given what room there is.
*/
.show-plan-link
	{
	flex:			1 1 auto;
	padding:		4px 0;
	text-decoration:	underline;
	}

.show-thumb
	{
	flex:			0 0 56px;
	width:			56px;
	height:			56px;
	border-radius:		8px;
	object-fit:		cover;
	background:		var(--ink-sunken);
	}

.show-thumb.is-empty
	{
	display:		flex;
	align-items:		center;
	justify-content:	center;
	font-size:		20px;
	color:			var(--paper-dim);
	}

.show-main
	{
	flex:			1 1 auto;
	min-width:		0;
	}

.show-title
	{
	margin:			0;
	font-size:		16px;
	font-weight:		600;
	overflow:		hidden;
	text-overflow:		ellipsis;
	white-space:		nowrap;
	}

/*
The line under a title, in white rather than the dimmed paper.

The date, the hall and the genre are not decoration: they are how one evening
is told from another when the titles are similar, and at thirteen pixels on a
dark red ground the dimmed tone was being read as greyed-out. The répertoire's
second line is white for the same reason.
*/
.show-meta
	{
	margin:			2px 0 0;
	font-size:		13px;
	color:			#FFFFFF;
	overflow:		hidden;
	text-overflow:		ellipsis;
	white-space:		nowrap;
	}

.show-rating
	{
	margin:			2px 0 0;
	font-size:		12px;
	color:			var(--accent);
	letter-spacing:		0.1em;
	}

/* ---- the catalogue ------------------------------------------------------ */

.work-row
	{
	display:		block;
	width:			100%;
	padding:		10px 12px;
	margin-bottom:		6px;
	background:		var(--ink-raised);
	border:			none;
	border-radius:		var(--radius);
	color:			inherit;
	font:			inherit;
	text-align:		left;
	cursor:			pointer;
	}

.work-row h3
	{
	margin:			0;
	font-size:		15px;
	font-weight:		600;
	}

.work-row p
	{
	margin:			2px 0 0;
	font-size:		13px;
	color:			#FFFFFF;
	}

.seen-count
	{
	float:			right;
	font-size:		12px;
	color:			var(--accent);
	}

/*
A work and whatever is shown under it.

The description opens in place and pushes the rest of the répertoire down,
rather than rising as a panel from the bottom of the screen. A list of works
is something to read down, and a sheet over the foot of it hides the very
rows the reader is comparing against.

No card. This was a column of rounded panels inset from both edges, each work
a box with its description in a second box beneath it - and once the whole
Wikipedia article could open there as well, that was three frames drawn around
one piece of text. The row now runs the full width of the screen and simply
grows downwards: the title, then the summary, then the article.

The hairline is pulled out to the edges with a negative margin while the text
stays on the screen's own 16px, so what divides two works is a rule across the
screen rather than the side of a box. The rules below are scoped to
.work-entry, because .work-row is also the row the settings screen offers a
deleted evening on, and that one is a card and should stay one.
*/
.work-entry
	{
	margin:			0 -16px;
	padding:		0 16px;
	border-bottom:		1px solid rgba(231, 232, 226, 0.10);
	}

.work-entry .work-row
	{
	margin-bottom:		0;
	padding:		12px 0;
	background:		none;
	border-radius:		0;
	}

.work-entry.is-open .work-row
	{
	background:		none;
	border-radius:		0;
	}

.work-detail
	{
	padding:		0 0 14px;
	background:		none;
	border:			none;
	border-radius:		0;
	}

.work-detail p
	{
	margin:			0 0 8px;
	font-size:		14px;
	}

.work-detail p:last-child
	{
	margin-bottom:		0;
	}

.work-detail .source
	{
	font-size:		12px;
	font-style:		italic;
	color:			var(--paper-dim);
	}

.work-detail a
	{
	color:			var(--accent);
	}

/*
What a work says about the article kept on the phone, set apart from the
summary above it by a rule rather than by a heading. It is a different kind of
thing - what can be read here with no network, rather than what is known about
the work - and without the rule its button reads as another line of the
description.
*/
.work-offline
	{
	margin-top:		10px;
	padding-top:		10px;
	border-top:		1px solid rgba(231, 232, 226, 0.10);
	}

/*
A whole article, unfolded under the work it is about.

Set as Wikipedia sets it: dark text on white, body at 16px over a line and a
half, section titles in a serif above a hairline. The journal's own 14px of
pale paper on dark red is right for three lines of summary beside a date and a
hall and wrong for forty thousand characters - and it would be passing off
somebody else's page as the journal's own writing. This is a page quoted
whole, and it is shown as itself.

It runs the full width, with no corners and no scrolling of its own. A box
that scrolls inside a page that scrolls is two scrollbars under one thumb,
and the thumb never knows which one it has hold of; the article is simply part
of the row now, and the row grows to hold it.
*/
.work-article
	{
	margin:			0 -16px 12px;
	padding:		16px;
	background:		#FFFFFF;
	color:			#202122;
	font-size:		16px;
	line-height:		1.65;
	}

/*
A section title, as fr.wikipedia draws one: a serif half again the size of the
text, not bold, over a hairline the width of the column.
*/
.work-article h4
	{
	margin:			24px 0 8px;
	padding-bottom:		4px;
	border-bottom:		1px solid #A2A9B1;
	color:			#000000;
	font-family:		"Linux Libertine", Georgia, "Times New Roman", serif;
	font-size:		23px;
	font-weight:		400;
	line-height:		1.3;
	}

.work-article h4:first-child
	{
	margin-top:		0;
	}

/*
A subsection, which the encyclopaedia sets in bold sans at about the size of
the text rather than in the serif of the sections above it.
*/
.work-article h5
	{
	margin:			18px 0 6px;
	color:			#000000;
	font-size:		17px;
	font-weight:		700;
	}

.work-article p
	{
	margin:			0 0 14px;
	font-size:		16px;
	line-height:		1.65;
	}

/*
Last of all, and more specific than .work-detail p:last-child, which would
otherwise reach in here and close the gap under the final paragraph.
*/
.work-article p:last-child
	{
	margin-bottom:		0;
	}

/*
The lists, which for an opera are half the article: the roles and the voices
they are written for, the recordings, the first casts.
*/
.work-article ul,
.work-article ol
	{
	margin:			0 0 14px;
	padding-left:		22px;
	}

.work-article li
	{
	margin-bottom:		4px;
	}

/*
A table, in the encyclopaedia's own grey rules.

It scrolls sideways when it is wider than the screen, and that is not the
nested scrolling that was taken out of this screen: the page scrolls down and
a table scrolls across, so the two gestures never ask which one the thumb
meant. The alternative is a cast list with its last column cut off.
*/
.work-table
	{
	margin:			0 0 16px;
	overflow-x:		auto;
	-webkit-overflow-scrolling: touch;
	}

.work-table table
	{
	border-collapse:	collapse;
	background:		#F8F9FA;
	font-size:		14px;
	line-height:		1.45;
	}

.work-table th,
.work-table td
	{
	padding:		5px 8px;
	border:			1px solid #A2A9B1;
	text-align:		left;
	vertical-align:		top;
	}

.work-table th
	{
	background:		#EAECF0;
	font-weight:		700;
	}

/*
A photograph of the article, with what the page said about it underneath.

Full width of the column and never floated. Wikipedia floats its pictures
right on a desktop and stops doing so on a telephone, where a 500px picture
beside a column of text leaves neither of them readable; the caption follows
in the grey the encyclopaedia uses for it.

The ground behind the picture is Wikipedia's own pale grey rather than the
white of the page, so that an image still arriving - or one whose bytes went
missing - leaves a block that looks deliberate instead of a hole.
*/
.work-figure
	{
	margin:			0 0 16px;
	}

/*
Capped in height as well as in width, and centred when the cap is what bites.

A portrait set to the full width of the column is a thousand pixels tall on a
phone: the coronation portrait at the head of Il viaggio a Reims filled the
entire screen and put the first sentence of the article below the fold, which
is a picture standing in front of the thing it illustrates. Half the screen is
as much as any one of them gets. A landscape photograph still fills the width,
because at these sizes that is well under the cap.
*/
.work-figure img
	{
	display:		block;
	max-width:		100%;
	max-height:		48vh;
	margin:			0 auto;
	background:		#EAECF0;
	}

.work-figure figcaption
	{
	margin-top:		5px;
	font-size:		13px;
	line-height:		1.4;
	color:			#54595D;
	}

/* ---- the bar at the bottom ---------------------------------------------- */

/*
The action bar, which is part of the bottom chrome and looks like it.

It used to carry a gradient of --ink fading upwards, which is the page's own
colour: against the darker tab bar below it that read as a pale band a
centimetre deep sitting across the foot of the screen, and it was the thing
that looked wrong on the phone. It takes the tab bar's colour now, so the
chrome is one dark piece from the buttons to the bottom edge rather than two
tones with a seam between them.
*/
.action-bar
	{
	position:		fixed;
	left:			0;
	right:			0;
	bottom:			calc(var(--bar-height) + var(--safe-keep));
	z-index:		15;
	display:		flex;
	gap:			8px;
	padding:		8px 16px;
	background:		var(--ink-sunken);
	border-top:		1px solid rgba(231, 232, 226, 0.10);
	}

.action-button
	{
	flex:			1 1 auto;
	padding:		10px 14px;
	background:		var(--accent);
	border:		none;
	border-radius:		var(--radius);
	color:			#FFF;
	font:			inherit;
	text-align:		left;
	cursor:			pointer;
	}

.action-button:active
	{
	background:		var(--accent-dim);
	}

.action-label
	{
	display:		block;
	font-size:		16px;
	font-weight:		600;
	}

.action-sub
	{
	display:		block;
	font-size:		12px;
	opacity:		0.85;
	}

.action-secondary
	{
	flex:			0 0 auto;
	padding:		10px 14px;
	background:		var(--ink-raised);
	border:			1px solid rgba(231, 232, 226, 0.18);
	border-radius:		var(--radius);
	color:			var(--paper);
	font:			inherit;
	font-size:		14px;
	cursor:			pointer;
	}

/* ---- the tabs ----------------------------------------------------------- */

.tabs
	{
	position:		fixed;
	left:			0;
	right:			0;
	bottom:			0;
	z-index:		20;
	display:		flex;
	height:			calc(var(--bar-height) + var(--safe-keep));
	padding-bottom:		var(--safe-keep);
	background:		var(--ink-sunken);
	border-top:		1px solid rgba(231, 232, 226, 0.10);
	}

/*
The labels are 14px, and the bar is no taller for it.

Its height is stated outright - bar-height plus whatever of the home
indicator's inset is kept - so the type inside can grow without the bar
following it. That is the only reason this is safe to change.

What it is not safe against is wrapping. The height being fixed, a label that
broke onto two lines would be cut off rather than make room for itself, so
nowrap is not a nicety here. At 14px the longest label, "Répertoire", comes
to about 74px bold against the 80px a quarter of the narrowest phone gives
it; that is the margin, and it is why this went to 14 and not to 16.
*/
.tab
	{
	flex:			1 1 0;
	min-width:		0;
	padding:		0 2px;
	background:		none;
	border:			none;
	color:			var(--paper-dim);
	font:			inherit;
	font-size:		14px;
	white-space:		nowrap;
	cursor:			pointer;
	}

.tab.is-current
	{
	color:			var(--paper);
	font-weight:		600;
	box-shadow:		inset 0 2px 0 var(--accent);
	}

/* ---- the sheet ---------------------------------------------------------- */

.sheet
	{
	position:		fixed;
	inset:			0;
	z-index:		40;
	display:		flex;
	flex-direction:		column;
	justify-content:	flex-end;
	}

.sheet-backdrop
	{
	position:		absolute;
	inset:			0;
	background:		rgba(0, 0, 0, 0.55);
	}

.sheet-panel
	{
	position:		relative;
	display:		flex;
	flex-direction:		column;
	max-height:		94vh;
	background:		var(--ink);
	border-radius:		18px 18px 0 0;
	border-top:		1px solid rgba(231, 232, 226, 0.14);
	}

.sheet-head
	{
	display:		flex;
	align-items:		center;
	justify-content:	space-between;
	padding:		12px 16px;
	border-bottom:		1px solid rgba(231, 232, 226, 0.10);
	}

.sheet-head h2
	{
	margin:			0;
	font-size:		17px;
	}

.sheet-close
	{
	background:		none;
	border:			none;
	color:			var(--accent);
	font:			inherit;
	font-size:		15px;
	cursor:			pointer;
	}

.sheet-body
	{
	flex:			1 1 auto;
	overflow-y:		auto;
	-webkit-overflow-scrolling: touch;
	padding:		14px 16px 18px;
	}

/*
The foot of the sheet, which does not scroll.

Enregistrer, Annuler and Supprimer used to be the last thing in the scrolling
body, so on a long evening they were a dozen fields below the fold and saving
meant scrolling to the bottom to find out where the button had got to. They sit
here instead: the panel is a flex column, the body takes the slack, and this
keeps its place at the bottom whatever the body is doing.
*/
.sheet-foot
	{
	flex:			0 0 auto;
	padding:		10px 16px calc(10px + var(--safe-keep));
	background:		var(--ink-sunken);
	border-top:		1px solid rgba(231, 232, 226, 0.10);
	}

.sheet-foot .button-row
	{
	margin-top:		0;
	}

/* ---- forms -------------------------------------------------------------- */

.field
	{
	margin-bottom:		14px;
	}

/*
A field heading with something on its right - the web lookup, on Programme.

The label keeps its own bottom margin inside here, so the row below sits
where it would if the heading were a plain label and nothing shifts for the
fields that have no action.
*/
.field-head
	{
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	}

.field-head > label
	{
	flex:			1 1 auto;
	}

.field > label,
.field-head > label
	{
	display:		block;
	margin-bottom:		4px;
	font-size:		12px;
	font-weight:		600;
	text-transform:		uppercase;
	letter-spacing:		0.06em;
	color:			var(--paper-dim);
	}

.field input[type="text"],
.field input[type="date"],
.field input[type="time"],
.field input[type="number"],
.field input[type="url"],
.field input[type="password"],
.field textarea,
.field select
	{
	width:			100%;
	padding:		10px 12px;
	background:		var(--ink-raised);
	border:			1px solid rgba(231, 232, 226, 0.16);
	border-radius:		10px;
	color:			var(--paper);
	font:			inherit;
	font-size:		16px;	/* never smaller: iOS zooms the page on any input below 16px */
	}

.field textarea
	{
	min-height:		88px;
	resize:			vertical;
	}

.field-hint
	{
	margin:			4px 0 0;
	font-size:		12px;
	color:			var(--paper-dim);
	}

.field-row
	{
	display:		flex;
	gap:			10px;
	}

.field-row .field
	{
	flex:			1 1 0;
	}

/*
The grid of kinds.

Not a <select>: iOS does not draw one as a list but as a wheel of about five
rows at the foot of the screen, and no CSS reaches it, so with twelve kinds the
last of them can only be got at by scrolling something the page does not
control.

They read down the columns, not across the rows, which is grid-auto-flow:
column over six explicit rows. Keeping it a matter of layout rather than
reordering the markup means the buttons stay in alphabetical order in the DOM,
so the tab order follows the eye instead of zigzagging.

The cell is 44px and the type is sized against it. In French the longest label
is "Comédie musicale", which is appreciably shorter than the sibling's "Concert
hall or theatre" - so this grid can carry 13px where the sibling needed 11.5px,
and still keep every label on one line at 390pt.
*/
.kind-grid
	{
	display:		grid;
	grid-template-columns:	1fr 1fr;
	grid-template-rows:	repeat(6, 44px);
	grid-auto-flow:		column;
	gap:			6px;
	}

.kind-button
	{
	display:		flex;
	align-items:		center;
	justify-content:	center;
	padding:		2px 6px;
	background:		var(--ink-raised);
	border:			1px solid rgba(231, 232, 226, 0.16);
	border-radius:		10px;
	color:			var(--paper);
	font:			inherit;
	font-size:		13px;
	line-height:		1.15;
	text-align:		center;
	cursor:			pointer;
	}

.kind-button.is-chosen
	{
	background:		var(--accent);
	border-color:		var(--accent);
	color:			#FFF;
	font-weight:		600;
	}

/* ---- buttons ------------------------------------------------------------ */

.button
	{
	display:		inline-block;
	padding:		10px 16px;
	background:		var(--accent);
	border:			none;
	border-radius:		10px;
	color:			#FFF;
	font:			inherit;
	font-weight:		600;
	cursor:			pointer;
	}

.button.is-quiet
	{
	background:		var(--ink-raised);
	border:			1px solid rgba(231, 232, 226, 0.18);
	color:			var(--paper);
	font-weight:		400;
	}

/*
The tools scattered through the screens: the web lookup, the venue searches,
adding photographs, the exports.

Gilt, and that is not decoration. A button and a text field were the same
colour - both var(--ink-raised) behind a border of rgba(231, 232, 226, 0.16)
against the field's 0.18 - so a button did not look like a button, it looked
like an empty box waiting to be typed into. The one thing a button has to say
is the one thing it did not.

Gold because the room is red: it is the pairing every opera house already
makes, and it is the only gold on the screen, so nothing has to be learned.
Outlined rather than filled because the sheet already has a filled red
button at its foot, and a second solid shape of equal weight would leave
five things shouting at once. The hierarchy is one filled primary, gilt
tools, flat fields.

Not used for Annuler, which stays quiet with the two buttons it belongs to.
*/
.button.is-gilt
	{
	background:		transparent;
	border:			1.5px solid #C9A227;
	color:			#EBC55A;
	font-weight:		400;
	}

.button.is-gilt:active
	{
	background:		rgba(201, 162, 39, 0.16);
	}

/*
These disable themselves while they work, and a brass outline at full
strength says nothing about being inert. The label changes too; this is so
that it reads as unavailable before it is read at all.
*/
.button:disabled
	{
	opacity:		0.5;
	cursor:			default;
	}

.button.is-danger
	{
	background:		none;
	border:			1px solid var(--accent);
	color:			var(--accent);
	font-weight:		400;
	}

/*
A button that has to share a line with a field heading.

Still 32px tall with its padding, which is under the 44px Apple asks for -
so the vertical padding is kept as generous as the line allows and the
horizontal padding gives it width to be hit by. It is a convenience beside a
label, not one of the three buttons an evening is saved with.
*/
.button.is-compact
	{
	flex:			0 0 auto;
	padding:		5px 12px;
	border-radius:		8px;
	font-size:		13px;
	white-space:		nowrap;
	}

.button-row
	{
	display:		flex;
	gap:			8px;
	flex-wrap:		wrap;
	margin-top:		18px;
	}

.button-row .button
	{
	flex:			1 1 auto;
	}

/* ---- the rating --------------------------------------------------------- */

.stars
	{
	display:		flex;
	gap:			6px;
	}

.star
	{
	flex:			0 0 auto;
	width:			40px;
	height:			40px;
	background:		none;
	border:			none;
	color:			var(--paper-dim);
	font-size:		26px;
	line-height:		1;
	cursor:			pointer;
	}

.star.is-lit
	{
	color:			var(--accent);
	}

/* ---- the programme and the candidates ----------------------------------- */

.chip-list
	{
	display:		flex;
	flex-wrap:		wrap;
	gap:			6px;
	margin-bottom:		8px;
	}

.chip
	{
	display:		inline-flex;
	align-items:		center;
	gap:			6px;
	padding:		6px 10px;
	background:		var(--ink-raised);
	border:			1px solid rgba(231, 232, 226, 0.16);
	border-radius:		999px;
	font-size:		13px;
	}

.chip button
	{
	background:		none;
	border:			none;
	color:			var(--accent);
	font:			inherit;
	cursor:			pointer;
	padding:		0;
	}

.candidate
	{
	display:		block;
	width:			100%;
	padding:		9px 12px;
	margin-bottom:		5px;
	background:		var(--ink-raised);
	border:			1px solid rgba(231, 232, 226, 0.14);
	border-radius:		10px;
	color:			inherit;
	font:			inherit;
	text-align:		left;
	cursor:			pointer;
	}

.candidate strong
	{
	display:		block;
	font-size:		15px;
	}

.candidate span
	{
	display:		block;
	font-size:		13px;
	color:			var(--paper-dim);
	}

/* ---- the reading of a ticket -------------------------------------------- */

.read-note
	{
	padding:		10px 12px;
	margin-bottom:		14px;
	background:		var(--ink-raised);
	border-left:		3px solid var(--accent);
	border-radius:		0 8px 8px 0;
	font-size:		13px;
	color:			var(--paper-dim);
	}

.read-flag
	{
	display:		inline-block;
	padding:		2px 8px;
	margin-bottom:		10px;
	background:		var(--accent-dim);
	border-radius:		999px;
	font-size:		11px;
	font-weight:		600;
	text-transform:		uppercase;
	letter-spacing:		0.06em;
	color:			#FFF;
	}

/* ---- the gallery -------------------------------------------------------- */

.gallery
	{
	display:		grid;
	grid-template-columns:	repeat(3, 1fr);
	gap:			6px;
	margin-bottom:		10px;
	}

.gallery figure
	{
	position:		relative;
	margin:			0;
	}

.gallery img
	{
	width:			100%;
	aspect-ratio:		1 / 1;
	object-fit:		cover;
	border-radius:		8px;
	background:		var(--ink-sunken);
	}

.gallery .drop
	{
	position:		absolute;
	top:			4px;
	right:			4px;
	width:			26px;
	height:			26px;
	background:		rgba(0, 0, 0, 0.6);
	border:			none;
	border-radius:		50%;
	color:			#FFF;
	font-size:		15px;
	line-height:		1;
	cursor:			pointer;
	}

/* ---- settings ----------------------------------------------------------- */

.stat-grid
	{
	display:		grid;
	grid-template-columns:	repeat(2, 1fr);
	gap:			8px;
	margin-bottom:		18px;
	}

.stat
	{
	padding:		10px 12px;
	background:		var(--ink-raised);
	border-radius:		var(--radius);
	}

.stat strong
	{
	display:		block;
	font-size:		21px;
	}

.stat span
	{
	font-size:		12px;
	color:			var(--paper-dim);
	}

/* ---- the toast ---------------------------------------------------------- */

.toast
	{
	position:		fixed;
	left:			50%;
	bottom:			calc(var(--bar-height) + var(--safe-keep) + var(--action-height) + 16px);
	z-index:		50;
	transform:		translateX(-50%) translateY(12px);
	max-width:		86vw;
	margin:			0;
	padding:		9px 16px;
	background:		var(--paper);
	border-radius:		999px;
	color:			var(--ink);
	font-size:		14px;
	font-weight:		500;
	text-align:		center;
	opacity:		0;
	pointer-events:		none;
	transition:		opacity 180ms ease, transform 180ms ease;
	}

.toast.is-shown
	{
	opacity:		1;
	transform:		translateX(-50%) translateY(0);
	}

/* ---- what is shown while a ticket is being read -------------------------- */

/*
Over the reading area and nothing else.

It stops short of the tab bar and the app bar on purpose: reading a ticket is
a call to a model and takes most of a minute, and the tabs stay reachable so
that the wait can be spent looking at something. The scan carries on and the
sheet opens over whatever screen is showing when the answer arrives.
*/
.busy
	{
	position:		fixed;
	left:			0;
	right:			0;
	top:			0;
	bottom:			calc(var(--bar-height) + var(--safe-keep));
	z-index:		40;
	display:		flex;
	align-items:		center;
	justify-content:	center;
	padding:		24px;
	background:		rgba(58, 16, 20, 0.92);
	}

.busy-card
	{
	width:			100%;
	max-width:		320px;
	padding:		22px 20px;
	background:		var(--ink-raised);
	border-radius:		var(--radius);
	text-align:		center;
	}

/*
The ticket itself, so that the wait is visibly about the thing just
photographed and not about the application in general.
*/
.busy-thumb
	{
	display:		block;
	width:			100%;
	max-height:		190px;
	margin:			0 0 16px;
	border-radius:		8px;
	object-fit:		cover;
	}

.busy-message
	{
	margin:			0 0 14px;
	color:			#FFFFFF;
	font-size:		16px;
	font-weight:		600;
	}

.busy-track
	{
	height:			4px;
	overflow:		hidden;
	border-radius:		999px;
	background:		var(--ink-sunken);
	}

/*
Indeterminate, and it has to be: nothing here knows how long the model will
take. A bar that filled up would be a bar that lied, and one that reached the
end and stopped would read as a failure.
*/
.busy-bar
	{
	width:			40%;
	height:			100%;
	border-radius:		999px;
	background:		var(--accent);
	animation:		busy-slide 1.4s ease-in-out infinite;
	}

@keyframes busy-slide
	{
	0%	{ transform: translateX(-100%); }
	100%	{ transform: translateX(250%); }
	}

.busy-detail
	{
	margin:			12px 0 0;
	min-height:		18px;
	color:			var(--paper-dim);
	font-size:		13px;
	}

/*
A moving bar is exactly what this setting asks to be rid of, and it is the one
thing here that is decoration rather than information. The card, the message
and the ticket all stay.
*/
@media (prefers-reduced-motion: reduce)
	{
	.busy-bar
		{
		width:		100%;
		animation:	none;
		}
	}

/* ---- the document ------------------------------------------------------- */

.document
	{
	background:		var(--paper);
	color:			#1A1A1A;
	border-radius:		var(--radius);
	padding:		18px;
	}

.document h1
	{
	margin:			0 0 4px;
	font-size:		24px;
	}

.document h2
	{
	margin:			26px 0 10px;
	padding-bottom:		4px;
	border-bottom:		1px solid #CFC9C2;
	font-size:		17px;
	}

.document h2 .count
	{
	float:			right;
	font-size:		12px;
	font-weight:		400;
	color:			#6A6560;
	}

.document .entry
	{
	margin-bottom:		18px;
	break-inside:		avoid;
	}

.document h3
	{
	margin:			0;
	font-size:		16px;
	}

.document .meta
	{
	margin:			1px 0 6px;
	font-size:		13px;
	color:			#6A6560;
	}

.document .work
	{
	margin:			0 0 6px 12px;
	padding-left:		10px;
	border-left:		2px solid #D8D2CB;
	}

.document .work-title
	{
	margin:			0;
	font-size:		14px;
	font-weight:		600;
	}

.document .work-creator
	{
	font-weight:		400;
	color:			#6A6560;
	}

.document .work-summary
	{
	margin:			2px 0 0;
	font-size:		13px;
	}

.document .work-source
	{
	margin:			1px 0 0;
	font-size:		11px;
	font-style:		italic;
	color:			#8A857F;
	}

/*
Your own words, set apart from the fetched ones. One of them is yours, and a
record that blurs the two is worth less than one that does not.
*/
.document .mine
	{
	margin:			8px 0 0;
	padding:		6px 0 6px 12px;
	border-left:		3px solid var(--accent);
	font-size:		14px;
	}

.document .mine p
	{
	margin:			0;
	}

.document .people,
.document .cast,
.document .aside
	{
	margin:			4px 0 0;
	font-size:		13px;
	color:			#4A4642;
	}

/*
What the web lookup said, set apart from what you wrote and from the fetched
summary alike. Three kinds of sentence end up in one entry and only one of
them is yours.
*/
.document .found
	{
	margin:			4px 0 0;
	font-size:		12.5px;
	font-style:		italic;
	color:			#6A6560;
	}

.document .found-source
	{
	font-style:		normal;
	font-size:		11px;
	word-break:		break-all;
	}

.document .aside
	{
	color:			#6A6560;
	}

/* ---- print -------------------------------------------------------------- */

@media print
	{
	.no-print		{ display: none !important; }

	html, body
		{
		background:	#FFF;
		color:		#000;
		}

	.view			{ padding: 0; }

	.document
		{
		background:	#FFF;
		padding:	0;
		border-radius:	0;
		}

	.document .entry	{ page-break-inside: avoid; }
	}
