/*
Visual identity of the journal.

The reference is the printed restaurant guide of fifty years ago: cream paper,
a serif name, an accession number set in a typewriter face, marks given in
figures rather than in stars, and a great deal of quiet space. One accent, a
bottle green, spent on the accession numbers, on the marks and on the single
action that matters. Red is reserved for destruction and never used for a good
score, because a guide whose highest praise is the same colour as its delete
button is a guide nobody trusts.
*/

:root
	{
	--paper:		#EFE9E1;
	--card:			#FBF9F5;
	--ink:			#231A18;
	--ink-soft:		#6E625C;
	--rule:			#D8CEC2;
	--accent:		#3F5E44;
	--accent-soft:		#E3EAE1;
	--danger:		#8E2C21;

	--font-body:		-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
	--font-display:		ui-serif, "New York", Georgia, "Times New Roman", serif;
	--font-mono:		ui-monospace, "SF Mono", Menlo, Consolas, monospace;

	--bar-height:		56px;
	--tab-height:		58px;
	--gutter:		20px;
	}

*
	{
	box-sizing: border-box;
	}

/*
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
stood on screen from the first paint, greyed the application out, and its Close
button appeared to do nothing because turning the attribute back on changed
nothing. Anything hidden by attribute in a screen added later is covered too.
*/
[hidden]
	{
	display: none !important;
	}

html, body
	{
	margin:		0;
	padding:	0;
	}

body
	{
	background:		var(--paper);
	color:			var(--ink);
	font-family:		var(--font-body);
	font-size:		16px;
	line-height:		1.45;
	-webkit-font-smoothing:	antialiased;
	overscroll-behavior-y:	none;
	}

body.is-sheet-open
	{
	overflow: hidden;
	}

/*
The bar at the top holds the wordmark and one line saying where the data stands.
*/
.app-bar
	{
	position:		fixed;
	inset:			0 0 auto 0;
	z-index:		30;
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	height:			calc(var(--bar-height) + env(safe-area-inset-top));
	padding:		env(safe-area-inset-top) var(--gutter) 0;
	background:		var(--paper);
	border-bottom:		1px solid var(--rule);
	}

.wordmark
	{
	margin:			0;
	font-family:		var(--font-display);
	font-size:		21px;
	letter-spacing:		-0.01em;
	}

.wordmark span
	{
	color: var(--accent);
	}

/*
The build, sitting beside the wordmark.

It takes the look of the status line at the other end of the bar rather than the
title it stands next to, because it is the same kind of small print and reading
it as part of the name would be wrong. The font has to be named: everything in
the wordmark would otherwise inherit the display serif, and the status line it is
matching is set in the body face.

The selector is nested so that it outweighs the rule above, which colours every
span in the wordmark with the accent.
*/
.wordmark .app-version
	{
	margin-left:	7px;
	font-family:	var(--font-body);
	font-size:	11px;
	text-transform:	uppercase;
	letter-spacing:	0.11em;
	color:		var(--ink-soft);
	}

.app-state
	{
	display:		flex;
	flex-direction:		column;
	align-items:		flex-end;
	gap:			2px;
	}

.app-status
	{
	margin:			0;
	font-size:		11px;
	text-transform:		uppercase;
	letter-spacing:		0.11em;
	color:			var(--ink-soft);
	}

/*
The line saying whether the application can be started without the network.
It is shown only while the answer is no, so that a working installation says
nothing and the bar stays quiet.
*/
.app-offline
	{
	margin:			0;
	font-size:		10px;
	text-transform:		uppercase;
	letter-spacing:		0.09em;
	color:			var(--accent);
	}

/*
The scrolling area holding whichever screen is current.
*/
.view
	{
	padding:	calc(var(--bar-height) + env(safe-area-inset-top) + 18px) var(--gutter)
			calc(var(--tab-height) + env(safe-area-inset-bottom) + 120px);
	max-width:	720px;
	margin:		0 auto;
	}

/*
The screens that carry no action bar can end closer to the tabs.
*/
.view.is-plain
	{
	padding-bottom:	calc(var(--tab-height) + env(safe-area-inset-bottom) + 28px);
	}

.eyebrow
	{
	margin:			0;
	font-size:		10.5px;
	font-weight:		600;
	text-transform:		uppercase;
	letter-spacing:		0.13em;
	color:			var(--ink-soft);
	}

.ref
	{
	margin:			0 0 6px;
	font-family:		var(--font-mono);
	font-size:		11px;
	letter-spacing:		0.04em;
	color:			var(--accent);
	}

.mono
	{
	font-family: var(--font-mono);
	}

/*
The day separator, ruled on both sides of the date.
*/
.day-rule
	{
	display:	flex;
	align-items:	center;
	gap:		12px;
	margin:		30px 0 14px;
	font-family:	var(--font-body);
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.13em;
	color:		var(--ink-soft);
	}

.day-rule::after
	{
	content:	"";
	flex:		1;
	height:		1px;
	background:	var(--rule);
	}

/*
One meal, presented as a catalogue entry.
*/
.meal-card
	{
	background:	var(--card);
	border:		1px solid var(--rule);
	padding:	16px 16px 18px;
	margin:		0 0 12px;
	cursor:		pointer;
	}

.meal-card:active
	{
	background: var(--accent-soft);
	}

/*
The name of the place and the mark it was given, on one line.

The mark is pushed to the right and set in the typewriter face, so that a column
of cards can be read down the right hand edge as a column of figures - which is
how a page of a guide is actually read - while the names stay left where the eye
starts.
*/
.card-head
	{
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	margin:			2px 0 6px;
	}

.card-head h3
	{
	margin:		0;
	font-family:	var(--font-display);
	font-size:	21px;
	font-weight:	500;
	line-height:	1.2;
	}

.score-badge
	{
	flex:		0 0 auto;
	font-family:	var(--font-mono);
	font-size:	17px;
	color:		var(--accent);
	}

.score-badge.is-empty
	{
	color: var(--ink-soft);
	}

.meal-address
	{
	margin:		8px 0 0;
	font-size:	14px;
	color:		var(--ink-soft);
	}

.meal-comment
	{
	margin:		10px 0 0;
	font-size:	15px;
	white-space:	pre-wrap;
	}

/*
The line under the name saying what it cost and what was decided.
*/
.meal-cost
	{
	margin:		6px 0 0;
	font-family:	var(--font-mono);
	font-size:	12px;
	color:		var(--ink-soft);
	}

.thumb-strip
	{
	display:		flex;
	gap:			6px;
	margin-top:		12px;
	overflow-x:		auto;
	-webkit-overflow-scrolling: touch;
	}

.thumb-strip img
	{
	width:		72px;
	height:		72px;
	object-fit:	cover;
	flex:		0 0 auto;
	border:		1px solid var(--rule);
	}

/*
A menu among the thumbnails is ruled in the accent, because it is the one
picture in the strip that is worth opening rather than glancing at.
*/
.thumb-strip img.is-menu
	{
	border:		1px solid var(--accent);
	outline:	1px solid var(--accent);
	outline-offset:	-3px;
	}

/*
The empty journal, which is an invitation rather than an apology.
*/
.empty-state
	{
	border:		1px solid var(--rule);
	border-left:	3px solid var(--accent);
	background:	var(--card);
	padding:	22px 18px;
	}

.empty-lead
	{
	margin:		10px 0 0;
	font-family:	var(--font-display);
	font-size:	19px;
	line-height:	1.35;
	}

.empty
	{
	color:		var(--ink-soft);
	font-size:	15px;
	padding:	18px 0;
	}

/*
The one action that matters, set as a stamped block above the tabs.
*/
.checkin-bar
	{
	position:	fixed;
	left:		0;
	right:		0;
	bottom:		calc(var(--tab-height) + env(safe-area-inset-bottom));
	z-index:	25;
	padding:	10px var(--gutter) 12px;
	background:	linear-gradient(to top, var(--paper) 72%, rgba(239, 233, 225, 0));
	}

.checkin-button
	{
	display:	block;
	width:		100%;
	max-width:	680px;
	margin:		0 auto;
	padding:	14px 16px;
	background:	var(--ink);
	color:		var(--paper);
	border:		none;
	outline:	1px solid var(--ink);
	outline-offset:	3px;
	font-family:	inherit;
	text-align:	left;
	cursor:		pointer;
	transition:	transform 120ms ease, background 120ms ease;
	}

.checkin-button:active
	{
	transform:	scale(0.985);
	background:	var(--accent);
	outline-color:	var(--accent);
	}

.checkin-label
	{
	display:	block;
	font-size:	15px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.15em;
	}

.checkin-sub
	{
	display:	block;
	margin-top:	3px;
	font-size:	11.5px;
	letter-spacing:	0.02em;
	opacity:	0.66;
	}

/*
The five screens of the application.

Five rather than the four a place journal needs, because the ranking is the
reason this exists and a ranking reached through a menu is a ranking nobody
looks at. At 10.5px the longest of the labels takes about 62px of the 78px each
column gets on the narrowest iPhone still supported, so nothing wraps.
*/
.tabs
	{
	position:	fixed;
	inset:		auto 0 0 0;
	z-index:	30;
	display:	grid;
	grid-template-columns: repeat(5, 1fr);
	height:		calc(var(--tab-height) + env(safe-area-inset-bottom));
	padding-bottom:	env(safe-area-inset-bottom);
	background:	var(--card);
	border-top:	1px solid var(--rule);
	}

.tab
	{
	appearance:	none;
	border:		none;
	background:	none;
	font-family:	inherit;
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.08em;
	color:		var(--ink-soft);
	cursor:		pointer;
	}

.tab.is-current
	{
	color:		var(--accent);
	box-shadow:	inset 0 2px 0 var(--accent);
	}

/*
Forms, shared by the editors and the settings.
*/
.field
	{
	display:	block;
	margin:		0 0 14px;
	}

.field > .eyebrow
	{
	display:	block;
	margin-bottom:	5px;
	}

input[type="text"],
input[type="url"],
input[type="date"],
input[type="tel"],
input[type="search"],
input[type="number"],
input[type="password"],
input[type="datetime-local"],
textarea
	{
	width:		100%;
	padding:	11px 12px;
	font-family:	inherit;
	font-size:	16px;
	color:		var(--ink);
	background:	var(--card);
	border:		1px solid var(--rule);
	border-radius:	0;
	appearance:	none;
	}

textarea
	{
	resize: vertical;
	}

input:focus-visible,
textarea:focus-visible,
button:focus-visible
	{
	outline:	2px solid var(--accent);
	outline-offset:	1px;
	}

/*
The number spinners are taken off the money and the party size.

Safari draws them inside the field, they are far too small to hit with a thumb,
and the keyboard that "number" brings up already has the digits. Removing them
leaves the field the same width as every other one, which is what keeps a row
of fields aligned.
*/
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button
	{
	appearance:	none;
	margin:		0;
	}

.button
	{
	appearance:	none;
	display:	inline-block;
	width:		100%;
	padding:	12px 14px;
	font-family:	inherit;
	font-size:	12px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.12em;
	color:		var(--ink);
	background:	var(--card);
	border:		1px solid var(--ink);
	cursor:		pointer;
	}

.button-primary
	{
	color:		var(--paper);
	background:	var(--accent);
	border-color:	var(--accent);
	}

.button-danger
	{
	color:		var(--danger);
	border-color:	var(--danger);
	background:	transparent;
	}

/*
The kinds of cooking, all of them in view at once.

This is not a <select>, and on an iPhone that is not a matter of taste. iOS
draws one of those itself as a wheel of about five rows: reaching the last of
twenty two kinds would mean scrolling a list the page has no say over, and no
amount of CSS reaches it.

Twenty one of the twenty two divide into three columns of seven. "Something
else" takes the eighth row on its own, across all three columns, which is the
right shape for it: it is the answer given when none of the others fits, not
another kind alongside them. The flow is by column so that the alphabet reads
down the left before it moves right, and the buttons stay in alphabetical order
in the markup, so the tab order follows the eye instead of zigzagging.
*/
.cuisine-grid
	{
	display:		grid;
	grid-template-columns:	repeat(3, 1fr);
	grid-template-rows:	repeat(7, auto);
	grid-auto-flow:		column;
	gap:			1px;
	background:		var(--rule);
	border:			1px solid var(--rule);
	}

/*
The height is fixed and the type is sized against it rather than the other way
round, which is what lets the letters be legible without the grid growing.

Three columns leave about 100px a cell on a 390pt screen. "North African" is the
longest label and takes two lines there, which costs nothing: two lines at this
size and leading come to about 35px and still sit inside the 42px the cell is
given, so the box does not move.
*/
.cuisine
	{
	appearance:	none;
	border:		none;
	display:	flex;
	align-items:	center;
	justify-content: center;
	min-height:	42px;
	padding:	4px 5px;
	font-family:	inherit;
	font-size:	11px;
	font-weight:	600;
	line-height:	1.15;
	text-transform:	uppercase;
	letter-spacing:	0.02em;
	text-align:	center;
	color:		var(--ink);
	background:	var(--card);
	cursor:		pointer;
	}

/*
"Something else" is placed rather than flowed. The others fill downwards, a
column at a time, so left to itself the twenty second would begin a fourth
column instead of finishing the eighth row.
*/
.cuisine:last-child
	{
	grid-column:	1 / -1;
	grid-row:	8;
	}

.cuisine.is-current
	{
	color:		var(--paper);
	background:	var(--accent);
	}

/*
A row of choices that are few enough to sit side by side: the occasion, the
verdict, the order of the ranking, what a photograph is of.

Equal columns whatever the labels say, so the row reads as one control with
several ends rather than as buttons of unequal importance.
*/
.pill-row
	{
	display:	grid;
	grid-auto-flow:	column;
	grid-auto-columns: 1fr;
	gap:		1px;
	background:	var(--rule);
	border:		1px solid var(--rule);
	}

.pill
	{
	appearance:	none;
	border:		none;
	min-height:	40px;
	padding:	4px 6px;
	font-family:	inherit;
	font-size:	11px;
	font-weight:	600;
	line-height:	1.15;
	text-transform:	uppercase;
	letter-spacing:	0.03em;
	color:		var(--ink);
	background:	var(--card);
	cursor:		pointer;
	}

.pill.is-current
	{
	color:		var(--paper);
	background:	var(--accent);
	}

/*
The marks.

One row a criterion: the name on the left, five figures on the right. Figures
rather than stars, because a star tells you the mark was four and a figure tells
you it was four out of five, and because five stars at a size a thumb can hit
take more room than the row has.

The mark already given can be tapped again to withdraw it, which is the only way
to get back to "not marked" - and "not marked" has to be reachable, since the
score is renormalised over the criteria actually marked and an unwanted three
is not the same as silence.
*/
.rating-row
	{
	display:		grid;
	grid-template-columns:	1fr auto;
	align-items:		center;
	gap:			10px;
	padding:		4px 0;
	}

.rating-label
	{
	min-width: 0;
	}

.rating-hint
	{
	display:	block;
	font-size:	11px;
	font-weight:	400;
	letter-spacing:	0;
	text-transform:	none;
	color:		var(--ink-soft);
	}

.rating-pips
	{
	display:	grid;
	grid-template-columns: repeat(5, 32px);
	gap:		1px;
	background:	var(--rule);
	border:		1px solid var(--rule);
	flex:		0 0 auto;
	}

.pip
	{
	appearance:	none;
	border:		none;
	min-height:	38px;
	font-family:	var(--font-mono);
	font-size:	13px;
	color:		var(--ink-soft);
	background:	var(--card);
	cursor:		pointer;
	}

/*
Every pip up to the mark is filled, not only the one that was tapped, because a
row of five in which the fourth alone is dark reads as "the fourth" rather than
as "four".
*/
.pip.is-filled
	{
	color:		var(--paper);
	background:	var(--accent);
	}

/*
Two or three fields sharing a line: the party and the bill, the dates of the
record. They are equal columns, and the labels sit above so that a long one
does not squeeze its neighbour.
*/
.field-pair
	{
	display:		grid;
	grid-template-columns:	1fr 1fr;
	gap:			10px;
	}

.field-trio
	{
	display:		grid;
	grid-template-columns:	1fr 1fr 1fr;
	gap:			10px;
	}

/*
The dishes, which are what you actually came back for.

One row a dish: the name across the top, then the price, the mark and a note.
The name is given the whole width because it is the thing that will be searched
for a year later; everything else is secondary and shares the line below.
*/
.dish-list
	{
	display:	grid;
	gap:		10px;
	margin-bottom:	10px;
	}

.dish-row
	{
	border:		1px solid var(--rule);
	background:	var(--card);
	padding:	10px;
	}

.dish-row .dish-line
	{
	display:		grid;
	grid-template-columns:	1fr auto;
	align-items:		center;
	gap:			8px;
	margin-top:		8px;
	}

.dish-row input
	{
	background: var(--paper);
	}

.dish-remove
	{
	appearance:	none;
	border:		1px solid var(--rule);
	background:	var(--card);
	color:		var(--danger);
	font-family:	inherit;
	font-size:	10px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.1em;
	padding:	8px 10px;
	cursor:		pointer;
	}

/*
The dish marks are the same control as the criteria, one size down: a dish is
marked out of five like everything else, but it is a detail of a meal and
should not shout as loudly as the food score.
*/
.dish-row .rating-pips
	{
	grid-template-columns: repeat(5, 28px);
	}

.dish-row .pip
	{
	min-height: 32px;
	}

/*
The dishes read off a photographed menu, offered to be added.

Chips rather than rows, because they are a list to be picked from and not a
list to be read: a menu yields thirty of them and a column of thirty rows would
bury the dishes you had actually eaten, which are the point of the screen and
sit directly above. They wrap, they are ruled rather than filled so that
nothing about them looks like a decision already taken, and the plus sign says
that tapping adds rather than selects.
*/
.suggestion-list
	{
	display:	flex;
	flex-wrap:	wrap;
	gap:		6px;
	margin-top:	8px;
	}

.suggestion
	{
	appearance:	none;
	display:	flex;
	align-items:	baseline;
	gap:		6px;
	max-width:	100%;
	padding:	7px 10px;
	background:	var(--card);
	border:		1px solid var(--rule);
	font-family:	inherit;
	font-size:	13px;
	text-align:	left;
	cursor:		pointer;
	}

.suggestion::before
	{
	content:	"+";
	flex:		0 0 auto;
	font-family:	var(--font-mono);
	color:		var(--accent);
	}

.suggestion:active
	{
	background:	var(--accent-soft);
	border-color:	var(--accent);
	}

.suggestion-name
	{
	min-width:	0;
	overflow-wrap:	anywhere;
	}

.suggestion-price
	{
	flex:		0 0 auto;
	font-family:	var(--font-mono);
	font-size:	11.5px;
	color:		var(--ink-soft);
	}

/*
The transcription, behind a disclosure because it is long and is wanted rarely -
when a dish was misread, or when what you want is the wording rather than the
list. A native <details> so that it costs no script and works before anything
has loaded.
*/
.menu-text
	{
	margin-top:	12px;
	border:		1px solid var(--rule);
	background:	var(--card);
	padding:	9px 11px;
	}

.menu-text summary
	{
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.12em;
	color:		var(--ink-soft);
	cursor:		pointer;
	}

.menu-text pre
	{
	margin:		10px 0 0;
	font-family:	var(--font-mono);
	font-size:	11.5px;
	line-height:	1.45;
	white-space:	pre-wrap;
	overflow-wrap:	anywhere;
	}

/*
A field and a small square button sharing a line.
The field takes whatever is left once the button has its corner, and both are
stretched to the same height so the pair reads as one control.
*/
.field-row
	{
	display:	flex;
	align-items:	stretch;
	gap:		8px;
	}

.field-row input
	{
	flex:	1;
	min-width: 0;
	}

/*
A button carrying an icon and nothing else.
Square, the height of the field beside it, and wide enough for a thumb.
*/
.icon-button
	{
	display:		flex;
	align-items:		center;
	justify-content:	center;
	flex:			0 0 auto;
	width:			44px;
	padding:		0;
	color:			var(--accent);
	background:		var(--card);
	border:			1px solid var(--rule);
	appearance:		none;
	cursor:			pointer;
	}

.icon-button:active
	{
	color:		var(--paper);
	background:	var(--accent);
	border-color:	var(--accent);
	}

/*
Two buttons sharing a line, each taking half of it.
*/
.button-pair
	{
	display:		grid;
	grid-template-columns:	1fr 1fr;
	gap:			8px;
	}

/*
The button offering the pictures just taken to the photo album.
It sits under the pair above rather than beside them because it comes and goes
with the pictures, and a grid cell that empties would move its neighbour.
*/
.button-album
	{
	margin-top:	8px;
	}

.sheet-actions
	{
	display:	grid;
	gap:		8px;
	margin-top:	18px;
	}

.checkline
	{
	display:	flex;
	align-items:	center;
	gap:		9px;
	font-size:	14px;
	margin:		4px 0 14px;
	}

.checkline input
	{
	width:	18px;
	height:	18px;
	}

/*
A heading inside a sheet, which is a long screen and needs dividing.
*/
.sheet-rule
	{
	display:	flex;
	align-items:	center;
	gap:		12px;
	margin:		22px 0 12px;
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.13em;
	color:		var(--ink-soft);
	}

.sheet-rule::after
	{
	content:	"";
	flex:		1;
	height:		1px;
	background:	var(--rule);
	}

/*
The sheet, used for checking in, for editing a meal and for a place.
*/
.sheet
	{
	position:	fixed;
	inset:		0;
	z-index:	60;
	display:	flex;
	align-items:	flex-end;
	}

.sheet-backdrop
	{
	position:	absolute;
	inset:		0;
	background:	rgba(35, 26, 24, 0.42);
	}

.sheet-panel
	{
	position:	relative;
	width:		100%;
	max-width:	720px;
	margin:		0 auto;
	max-height:	90vh;
	display:	flex;
	flex-direction:	column;
	background:	var(--paper);
	border-top:	3px solid var(--ink);
	animation:	rise 180ms ease-out;
	}

@keyframes rise
	{
	from	{ transform: translateY(14px); opacity: 0.4; }
	to	{ transform: translateY(0); opacity: 1; }
	}

.sheet-head
	{
	display:		flex;
	align-items:		center;
	justify-content:	space-between;
	padding:		14px var(--gutter) 10px;
	border-bottom:		1px solid var(--rule);
	}

.sheet-head h2
	{
	margin:		0;
	font-family:	var(--font-display);
	font-size:	19px;
	font-weight:	500;
	}

.sheet-close
	{
	appearance:	none;
	border:		none;
	background:	none;
	font-family:	inherit;
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.12em;
	color:		var(--ink-soft);
	cursor:		pointer;
	}

.sheet-body
	{
	padding:	16px var(--gutter) calc(24px + env(safe-area-inset-bottom));
	overflow-y:	auto;
	}

.sheet-lead
	{
	margin:		0 0 14px;
	font-family:	var(--font-display);
	font-size:	18px;
	line-height:	1.35;
	}

.sheet-foot
	{
	margin:		14px 0 0;
	font-size:	12px;
	color:		var(--ink-soft);
	}

.candidate-list
	{
	display:	grid;
	gap:		1px;
	background:	var(--rule);
	border:		1px solid var(--rule);
	margin-bottom:	14px;
	}

.candidate
	{
	appearance:	none;
	display:	block;
	width:		100%;
	text-align:	left;
	padding:	11px 13px;
	background:	var(--card);
	border:		none;
	font-family:	inherit;
	cursor:		pointer;
	}

.candidate:active
	{
	background: var(--accent-soft);
	}

.candidate-name
	{
	display:	block;
	font-family:	var(--font-display);
	font-size:	17px;
	}

.candidate-meta
	{
	display:	block;
	margin-top:	2px;
	font-size:	11px;
	text-transform:	uppercase;
	letter-spacing:	0.1em;
	color:		var(--ink-soft);
	}

/*
The note on a candidate you have already eaten at.

Worth the room it takes. A street can hold two places of nearly the same name,
and knowing which of them is the one already in the journal - with what it
scored - is the difference between adding a third meal to a record and starting
a second record that will split the ranking in two.
*/
.candidate-known
	{
	display:	inline-block;
	margin-top:	4px;
	padding:	1px 6px;
	background:	var(--accent-soft);
	color:		var(--accent);
	font-family:	var(--font-mono);
	font-size:	10.5px;
	letter-spacing:	0.02em;
	}

.spinner
	{
	width:		22px;
	height:		22px;
	margin:		6px 0 4px;
	border:		2px solid var(--rule);
	border-top-color: var(--accent);
	border-radius:	50%;
	animation:	spin 720ms linear infinite;
	}

@keyframes spin
	{
	to { transform: rotate(360deg); }
	}

/*
Photographs inside the editor.
*/
.photo-grid
	{
	display:		grid;
	grid-template-columns:	repeat(3, 1fr);
	gap:			6px;
	margin-bottom:		10px;
	}

/*
The menus are shown two across rather than three. They are portrait sheets of
small type, and at a third of the width there is nothing to see at all.
*/
.photo-grid.is-menus
	{
	grid-template-columns: repeat(2, 1fr);
	}

.photo-cell
	{
	position:	relative;
	aspect-ratio:	1;
	border:		1px solid var(--rule);
	background:	var(--card);
	}

.photo-grid.is-menus .photo-cell
	{
	aspect-ratio: 3 / 4;
	}

.photo-cell img
	{
	width:		100%;
	height:		100%;
	object-fit:	cover;
	display:	block;
	}

.photo-missing
	{
	display:	grid;
	place-items:	center;
	height:		100%;
	font-size:	11px;
	color:		var(--ink-soft);
	text-align:	center;
	padding:	6px;
	}

.photo-remove
	{
	position:	absolute;
	inset:		auto 0 0 0;
	appearance:	none;
	border:		none;
	background:	rgba(35, 26, 24, 0.78);
	color:		var(--paper);
	font-family:	inherit;
	font-size:	9.5px;
	text-transform:	uppercase;
	letter-spacing:	0.1em;
	padding:	4px 0;
	cursor:		pointer;
	}

/*
The ranking, which is what this application is for.
*/
.rank-tools
	{
	margin-bottom: 14px;
	}

.rank-tools .pill-row
	{
	margin-bottom: 10px;
	}

/*
The line saying what the ranking is a ranking of.
It is small print and it is not decoration: a reader who does not know that the
scores are pulled towards an average will read a 4.3 beside one meal as a
measurement, which it is not.
*/
.rank-note
	{
	margin:		0 0 14px;
	font-size:	12px;
	line-height:	1.4;
	color:		var(--ink-soft);
	}

.rank-list
	{
	display:	grid;
	gap:		1px;
	background:	var(--rule);
	border:		1px solid var(--rule);
	}

.rank-row
	{
	appearance:	none;
	display:	grid;
	grid-template-columns: 30px 1fr auto;
	align-items:	center;
	gap:		10px;
	width:		100%;
	padding:	11px 13px;
	background:	var(--card);
	border:		none;
	text-align:	left;
	font-family:	inherit;
	cursor:		pointer;
	}

.rank-row:active
	{
	background: var(--accent-soft);
	}

.rank-place
	{
	font-family:	var(--font-mono);
	font-size:	13px;
	color:		var(--accent);
	}

/*
The name and the line under it. It has to be told it may be narrower than its
contents, or a long restaurant name pushes the score off the right of the row
instead of wrapping: a grid track of 1fr will not shrink below the width of
what is in it unless it is allowed to.
*/
.rank-body
	{
	min-width: 0;
	}

.rank-name
	{
	display:	block;
	font-family:	var(--font-display);
	font-size:	17px;
	line-height:	1.2;
	}

.rank-meta
	{
	display:	block;
	margin-top:	2px;
	font-size:	10.5px;
	text-transform:	uppercase;
	letter-spacing:	0.09em;
	color:		var(--ink-soft);
	}

.rank-figure
	{
	text-align:	right;
	flex:		0 0 auto;
	}

.rank-score
	{
	display:	block;
	font-family:	var(--font-mono);
	font-size:	16px;
	color:		var(--accent);
	}

/*
The bar under the figure.

It is there so that a column of scores can be compared without reading any of
them, and it is drawn from the bottom of the scale rather than from zero: every
score worth having falls between three and five, and a bar that starts at zero
puts them all within a fifth of each other and says nothing.
*/
.rank-bar
	{
	display:	block;
	width:		52px;
	height:		3px;
	margin-top:	4px;
	background:	var(--rule);
	}

.rank-bar span
	{
	display:	block;
	height:		100%;
	background:	var(--accent);
	}

/*
The place sheet: what one restaurant amounts to.
*/
.stat-grid
	{
	display:		grid;
	grid-template-columns:	repeat(3, 1fr);
	gap:			1px;
	background:		var(--rule);
	border:			1px solid var(--rule);
	margin-bottom:		16px;
	}

.stat
	{
	background:	var(--card);
	padding:	10px 8px 11px;
	text-align:	center;
	}

.stat-value
	{
	display:	block;
	font-family:	var(--font-mono);
	font-size:	18px;
	color:		var(--accent);
	}

.stat-label
	{
	display:	block;
	margin-top:	2px;
	font-size:	9.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.1em;
	color:		var(--ink-soft);
	}

/*
The mean mark of each criterion at one place, drawn as a bar so that the shape
of the place can be read at a glance: the kitchen that is better than the room,
the room that is better than the kitchen.
*/
.criterion-bars
	{
	display:	grid;
	gap:		7px;
	margin-bottom:	16px;
	}

.criterion-bar
	{
	display:		grid;
	grid-template-columns:	86px 1fr 30px;
	align-items:		center;
	gap:			8px;
	font-size:		11px;
	text-transform:		uppercase;
	letter-spacing:		0.08em;
	color:			var(--ink-soft);
	}

.criterion-bar .track
	{
	height:		6px;
	background:	var(--rule);
	}

.criterion-bar .track span
	{
	display:	block;
	height:		100%;
	background:	var(--accent);
	}

.criterion-bar .figure
	{
	font-family:	var(--font-mono);
	font-size:	12px;
	text-align:	right;
	color:		var(--ink);
	}

/*
The meals eaten at one place, listed on its sheet.
*/
.meal-list
	{
	display:	grid;
	gap:		1px;
	background:	var(--rule);
	border:		1px solid var(--rule);
	margin-bottom:	16px;
	}

.meal-row
	{
	appearance:		none;
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	width:			100%;
	padding:		10px 13px;
	background:		var(--card);
	border:			none;
	text-align:		left;
	font-family:		inherit;
	cursor:			pointer;
	}

.meal-row .row-main
	{
	font-family:	var(--font-display);
	font-size:	15px;
	}

.meal-row .row-figure
	{
	font-family:	var(--font-mono);
	font-size:	13px;
	color:		var(--accent);
	}

/*
The map screen.
*/
.map-tools
	{
	margin-bottom: 12px;
	}

.map-canvas
	{
	height:		52vh;
	min-height:	260px;
	border:		1px solid var(--rule);
	background:	var(--card);
	}

.map-list
	{
	display:	grid;
	gap:		1px;
	background:	var(--rule);
	border:		1px solid var(--rule);
	border-top:	none;
	}

.map-row
	{
	appearance:		none;
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	width:			100%;
	padding:		11px 13px;
	background:		var(--card);
	border:			none;
	font-family:		var(--font-display);
	font-size:		16px;
	text-align:		left;
	cursor:			pointer;
	}

.map-row .row-figure
	{
	font-family:	var(--font-mono);
	font-size:	13px;
	color:		var(--accent);
	}

/*
The marker drawn for a place on the map, carrying its score.

A pin says where; a pin with a figure in it says whether it was any good, which
on a map of somewhere you are standing is the only question. The colour is the
accent whatever the score, because colouring the good ones green and the bad
ones red would put a red mark on a restaurant in a street where the owner might
be standing behind you.
*/
.map-mark
	{
	display:		flex;
	align-items:		center;
	justify-content:	center;
	width:			30px;
	height:			30px;
	border-radius:		50%;
	background:		var(--accent);
	color:			var(--paper);
	border:			2px solid var(--card);
	box-shadow:		0 1px 3px rgba(35, 26, 24, 0.4);
	font-family:		var(--font-mono);
	font-size:		12px;
	}

.map-mark.is-empty
	{
	background:	var(--ink-soft);
	}

/*
The document screen, which is also what the printer receives.
*/
.doc-tools
	{
	border:		1px solid var(--rule);
	background:	var(--card);
	padding:	16px;
	margin-bottom:	22px;
	}

.doc-range
	{
	display:		grid;
	grid-template-columns:	1fr 1fr;
	gap:			10px;
	}

.doc-sheet
	{
	background:	var(--card);
	border:		1px solid var(--rule);
	padding:	26px 20px 30px;
	}

.doc-head
	{
	border-bottom:	2px solid var(--ink);
	padding-bottom:	14px;
	margin-bottom:	8px;
	}

.doc-head h1
	{
	margin:		6px 0 4px;
	font-family:	var(--font-display);
	font-size:	26px;
	font-weight:	500;
	line-height:	1.15;
	}

.doc-count
	{
	margin:		0;
	font-family:	var(--font-mono);
	font-size:	11px;
	color:		var(--accent);
	}

.doc-day
	{
	margin:		26px 0 12px;
	font-family:	var(--font-body);
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.13em;
	color:		var(--ink-soft);
	border-bottom:	1px solid var(--rule);
	padding-bottom:	5px;
	}

.doc-entry
	{
	break-inside:	avoid;
	margin:		0 0 20px;
	}

.doc-entry h3
	{
	display:		flex;
	align-items:		baseline;
	justify-content:	space-between;
	gap:			12px;
	margin:			2px 0 5px;
	font-family:		var(--font-display);
	font-size:		19px;
	font-weight:		500;
	}

.doc-score
	{
	flex:		0 0 auto;
	font-family:	var(--font-mono);
	font-size:	15px;
	color:		var(--accent);
	}

/*
The marks of one meal, on one line, in the order the criteria are declared.
Set in the typewriter face so that the figures line up down a printed page.
*/
.doc-marks
	{
	margin:		6px 0 0;
	font-family:	var(--font-mono);
	font-size:	11.5px;
	letter-spacing:	0.02em;
	color:		var(--ink);
	}

.doc-cost
	{
	margin:		4px 0 0;
	font-family:	var(--font-mono);
	font-size:	11.5px;
	color:		var(--ink-soft);
	}

.doc-comment
	{
	margin:		9px 0 0;
	font-size:	15px;
	white-space:	pre-wrap;
	}

/*
The dishes, in the printed record.
*/
.doc-dishes
	{
	margin:		9px 0 0;
	padding:	0 0 0 14px;
	font-size:	14px;
	}

.doc-dishes li
	{
	margin-bottom: 2px;
	}

.dish-name
	{
	font-family: var(--font-display);
	}

.dish-mark,
.dish-price
	{
	margin-left:	7px;
	font-family:	var(--font-mono);
	font-size:	11.5px;
	color:		var(--accent);
	}

.dish-note
	{
	margin-left:	7px;
	font-size:	13px;
	color:		var(--ink-soft);
	}

.doc-photos
	{
	display:		grid;
	grid-template-columns:	repeat(3, 1fr);
	gap:			6px;
	margin-top:		12px;
	}

.doc-photos img
	{
	width:		100%;
	aspect-ratio:	4 / 3;
	object-fit:	cover;
	border:		1px solid var(--rule);
	}

/*
The menus in the printed record are given the whole width, two across, and are
not cropped. A menu cropped to a landscape box is a menu with its prices cut
off, which defeats the point of having photographed it.
*/
.doc-menus
	{
	display:		grid;
	grid-template-columns:	repeat(2, 1fr);
	gap:			8px;
	margin-top:		10px;
	}

.doc-menus img
	{
	width:		100%;
	height:		auto;
	border:		1px solid var(--rule);
	}

/*
The ranking table at the front of the printed record.
*/
.doc-ranking
	{
	margin-bottom: 8px;
	}

.rank-table
	{
	width:		100%;
	border-collapse:	collapse;
	font-size:	14px;
	}

.rank-table th
	{
	text-align:	left;
	font-size:	9.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.1em;
	color:		var(--ink-soft);
	border-bottom:	1px solid var(--rule);
	padding:	0 6px 4px 0;
	}

.rank-table td
	{
	padding:	5px 6px 5px 0;
	border-bottom:	1px solid var(--rule);
	vertical-align:	baseline;
	}

.rank-table .rank-cell,
.rank-table .number-cell
	{
	font-family:	var(--font-mono);
	font-size:	12px;
	}

.rank-table .rank-cell
	{
	color: var(--accent);
	}

.rank-table .number-cell
	{
	text-align: right;
	}

.rank-table .eyebrow
	{
	font-size: 9.5px;
	}

.doc-note
	{
	margin:		10px 0 0;
	font-size:	12px;
	line-height:	1.4;
	color:		var(--ink-soft);
	}

/*
The settings screen.
*/
.panel
	{
	background:	var(--card);
	border:		1px solid var(--rule);
	padding:	18px 16px;
	margin-bottom:	16px;
	}

.panel-lead
	{
	margin:		8px 0 16px;
	font-size:	14px;
	color:		var(--ink-soft);
	}

.facts
	{
	display:		grid;
	grid-template-columns:	auto 1fr;
	gap:			6px 16px;
	margin:			12px 0 0;
	font-size:		14px;
	}

.facts dt
	{
	font-size:	10.5px;
	font-weight:	600;
	text-transform:	uppercase;
	letter-spacing:	0.12em;
	color:		var(--ink-soft);
	padding-top:	3px;
	}

.facts dd
	{
	margin: 0;
	}

/*
The short confirmation shown after a change.
*/
.toast
	{
	position:	fixed;
	left:		50%;
	bottom:		calc(var(--tab-height) + env(safe-area-inset-bottom) + 84px);
	z-index:	80;
	transform:	translate(-50%, 8px);
	margin:		0;
	padding:	9px 16px;
	background:	var(--ink);
	color:		var(--paper);
	font-size:	12px;
	text-transform:	uppercase;
	letter-spacing:	0.11em;
	opacity:	0;
	pointer-events:	none;
	transition:	opacity 180ms ease, transform 180ms ease;
	}

.toast.is-visible
	{
	opacity:	1;
	transform:	translate(-50%, 0);
	}

@media (prefers-reduced-motion: reduce)
	{
	*
		{
		animation-duration:	0.001ms !important;
		transition-duration:	0.001ms !important;
		}
	}

/*
What the printer sees: the document alone, on white, with no interface.
*/
@media print
	{
	.no-print
		{
		display: none !important;
		}

	body
		{
		background: #FFFFFF;
		}

	.view
		{
		padding:	0;
		max-width:	none;
		}

	.doc-sheet
		{
		border:		none;
		background:	transparent;
		padding:	0;
		}

	.doc-photos
		{
		grid-template-columns: repeat(4, 1fr);
		}

	/*
	A page break in the middle of the ranking is acceptable; one in the middle
	of a row of it is not, and neither is a table whose heading is left on the
	previous page.
	*/
	.rank-table tr
		{
		break-inside: avoid;
		}

	.rank-table thead
		{
		display: table-header-group;
		}
	}
