/*
 * CQPweb: a user-friendly interface to the IMS Corpus Query Processor
 * Copyright (C) 2008-today Andrew Hardie and contributors
 *
 * See http://cwb.sourceforge.net/cqpweb.php
 *
 * This file is part of CQPweb.
 * 
 * CQPweb is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * CQPweb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */



/* These are the bits and pieces of CSS that are for the "system" - ie, can't be changed just to "skin" the UI. 
 * many times, the clientside code depends on these being here. */


/* 
 * a note on measures. Primary unit here is rem. 
 * USUALLY, 1rem = 12pt = 16px = 100%. 
 */

/*
TODO   https://css-tricks.com/box-sizing/
The above recommends a practice for getting box sizing to work better.
Might make it possible to get rid of some of the table-based layout.
*/

/*
 * =========
 * RESET CSS 
 * =========
 */

/* Some selected bits from Meyer's classic reset.css, merged into base rules for CQPweb. */

html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, pre,
a, code, em, img, strong, sub, sup, 
ol, ul, li, form, label,
table, tbody, tfoot, thead, tr, th, td,
footer, menu, nav, 
audio, video {
	margin           : 0;     /* margin & padding syntax is TOP RIGHT BOTTOM LEFT */
	padding          : 0;
	border           : 0;
	text-indent      : 0;
	line-height      : 120%;
	font-size        : inherit;
	font-family      : inherit;
}

html {
	/* doesn't work in safari, apparently; but if available, we should use. */
	scroll-behavior  : smooth;
	color            : var(--colour-text-normal)
}

	/* for debug: to see where the transparent patches are... 
body { background-color:pink; }
	*/

p {
	/* standard paragraph: 0.8 rem above & below, nothing left or right.  */
	display          : block;
	margin           : 0.8rem 0rem 0.8rem 0rem;
	font-size        : inherit;
	font-family      : inherit;
}

ul, ol {
	margin           : 1rem 0 1rem 0;  
	padding-left     : 2.5rem;
}
ol {
	list-style       : decimal outside none;
}
ul {
	list-style       : disc outside none;
}

/* default table bordering : nothing! */
table {
	border-spacing   : 0;
	border-collapse  : separate; 
}

/* put strong and em to useful defaults; set font for pre and code. */
em {
	font-style       : italic;
}
strong {
	font-weight      : bold;
}
pre, code {
	font-family      : "Courier New", Courier, "Lucida Console", Monaco, monospace;
}

/* setup pointers */
select, button, label, input[type="radio"], input[type="checkbox"], input[type="submit"] , input[type="reset"] , input[type="file"]  {
	/* because clickable */
	cursor           : pointer; 
}

/* radio buttons and cursors have weird defaults in the user agent stylesheet */
input[type="radio"], input[type="checkbox"] {
	margin           : 0;
}

textarea, input[type="text"]  {
	cursor           : text;
}
/* a generally-OK text size for all textareas. Specific classes of textarea may override. */
textarea {
	font-size        : 1rem;
}

/* end of basic resets */



/* Modern flat styling for form controls, replacing raw user-agent defaults
   site-wide (buttons, selects, text-like inputs) -- textarea deliberately
   excluded, since #searchBox relies on character-based rows/cols sizing
   and no box-sizing:border-box reset exists yet to make padding safe there. */
select,
input[type="text"],
input[type="number"],
input[type="password"],
input[type="email"],
input[type="url"] {
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
	padding          : 0.35rem 0.6rem;
	border-style     : solid;
	border-width     : var(--border-width-hairline);
	border-color     : var(--colour-layout-strong);
	border-radius    : 0.25rem;
	background-color : var(--colour-layout-fg);
	color            : var(--colour-text-normal);
}

button,
input[type="submit"],
input[type="reset"],
input[type="button"] {
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
	font-weight      : bold;
	padding          : 0.35rem 0.9rem;
	border-style     : none;
	border-radius    : 0.25rem;
	background-color : var(--colour-layout-strong);
	color            : var(--colour-text-strong);
	box-shadow       : 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.08);
	transition       : background-color 0.15s ease, box-shadow 0.15s ease;
}

button:hover,
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover {
	background-color : var(--colour-layout-contrast);
	box-shadow       : 0 0.125rem 0.25rem rgba(0, 0, 0, 0.12);
}

button:disabled,
input[type="submit"]:disabled,
input[type="button"]:disabled {
	cursor           : not-allowed;
	opacity          : 0.6;
	box-shadow       : none;
}


/*
 * =====================================
 * Colour scheme variables! Documenation
 * =====================================
 */
 
/*

The following is what the colour scheme definition looks like.

 -- FOUR basic layout colours: a foreground colour (normally pastel), a background colour (grey),
    a strong colour (more vivid version of the pastel foregreound), 
    and a contrast colour (for messages / errors. 
    
 -- TWO layout colours that mostly don't change: data2 is s variant grey, ouline is white 
    because it's for linesbetween layiout boxes.
    
 -- FOUR font colours:
     -- normal: usually black, it needs to work against fg, bg, and string. 
     -- faint : usually grey, it is used for washed-out text. 
     -- bright: a colour that stands out against fg and strong (and needs to stand out against bg as well though it doesn't always. 
     -- mid   : like bright, but less so.  bright and mid are usually used for links. 
     
ISSUES:

- "normal" doesn't always work equally against fg and strong. 
- colour scheme "dusk is a good example of this. White is good against "stong", less good against fg, and bad against bg.
  (I haven't yet dsared look at how it appears on top of onctrast). 
  
Solution: split normal into fg, bg, strong, contrast - for what they stand in front of?
and those should be used for noonlinks; 

Then, for mid and bright, these should be used for inks

BUT be careful with these 

An unhovered ink should be normal - BUT we put these links on both fg and bg blocks. 
So bright appears (onhover) on top of fg and strong. 

Inactive CONTROLS are mid,but inactive menulinks are normal!
(sigh)

=================================================================
TYPE        CONTROL           MENU ITEM           LINK
------------------------------------------------------------
Normal
  L/o       fg or bg          fg                  fg or bg
  text      mid               normal              bright     
Hover
  L/o       strong            bg                  (same as normal)
  text      bright            bright              bright
=======================================================================
 
:root {
	--colour-layout-fg       : #d1a4ff ;
	--colour-layout-bg       : #d5d5d5 ;
	--colour-layout-strong   : #8000ff ; 
	--colour-layout-contrast : #ffeeaa ;

	--colour-layout-data2    : #f0f0f0 ;    
	--colour-layout-outline  : white   ;

	--colour-text-normal     : black   ;
	--colour-text-strong     : white   ;
	
	
	--colour-text-bright     : yellow  ;
	
	--colour-text-faint      : gray    ;
}

solution:
new color, -text-strong

-bright => 

menuItem should use normal and bright still. 

*/






/*
 * =========================================================================================================
 * Commonly-used string definitions (some, e.g. fonts, may become part of the modifiable stuff like colours)
 * =========================================================================================================
 */

:root {
	--font-ui        : -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, Helvetica, Arial, sans-serif;
	--font-content   : "Times New Roman", Times, Georgia, serif;
	--boxpad-default : 0.6rem 0.9rem 0.6rem 0.9rem;

	--border-width-hairline : 0.0625rem;
	--border-width-strong   : 0.0625rem;
}


/* 
 * ==================================================
 * alignment classes for containers
 * ==================================================
 */

/* replacement for align="left,right,center" in HTML. */
.algC {
	text-align       : center;
}
.algL {
	text-align       : left;
}
.algR {
	text-align       : right;
}

/* add margin auto to any table inside a text-centre block. */
.algC table {
	margin-left      : auto;
	margin-right     : auto;
}



/* 
 * ==========================
 * different paragraph styles 
 * ==========================
 */

p.errormessage {
	font-family      : var(--font-ui);
	font-size        : 1rem;
}

p.instruction {
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
}

p.helpnote {
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
}

p.bigbold {
	font-family      : var(--font-ui);
	font-size        : 1.2rem;
	font-weight      : bold;
}

p.spacer {
	font-size        : 0.8rem;
	padding          : 0rem;
	line-height      : 10%;
	height           : 0.8rem;
}



/* 
 * ============
 * table layout 
 * ============
 */

/* class for making any kind of block take up all horizontal space */
.fullwidth {
	width            : 100%;
}

/* Wraps a table whose column count/content width is arbitrary and unbounded (e.g. an admin
   raw-SQL-table dump, print_sql_result_dump() in sql-lib.php) -- unlike the form-field overflow
   fixes elsewhere in this file, there's no known/fixed content size here to cap with max-width,
   so table-layout:fixed would just squash arbitrary data unreadably. A dedicated horizontally-
   scrolling container is the correct fit instead: the table renders at its natural width (however
   wide that is), header and data cells stay perfectly aligned as one table always does, and only
   this container scrolls -- so a wide table can never push the rest of the page/frame outward. */
.table-scroll {
	overflow-x       : auto;
	max-width        : 100%;
}

/* class for making any kind of block take up only as much horizontal space as it needs */
.minwidth {
	width            : intrinsic;
	width            : -webkit-max-content;
	width            : -moz-max-content;
	width            : max-content;
}

/* class which replicates the old HTML "nowrap" Boolean attribute for table cells. */
.nowrap {
	white-space      : nowrap;
}
/* class which stops tables using the "margin" feture to centre thmeselves 
.noCentre */

/*
seems to be unused
table.controlbox {
	border: thick outset;
}

td.controlbox {
	font-family:      var(--font-ui);
	padding-top:      5px;
	padding-right:    10px;
	padding-bottom:   5px;
	padding-left:     10px;
	border:           medium outset;
}
*/



/* 
 * ==================
 * Major layout units 
 * ==================
 *
 * NB don't forget the padding rule:
 *	padding: TOP RIGHT BOTTOM LEFT;
 */

/* NOTE: these four box classes were originally table/th/td-scoped
   (table.layout-frame, th.layout-strong, td.layout-fg/contrast/bg).
   They're plain box styling (border/background/padding/font) with nothing
   table-specific in it, so the selectors are now tag-agnostic classes --
   this lets a page use a <div> instead of a <table> for a "boxed panel"
   without duplicating the look, while every existing td/th usage is
   unaffected. */
.layout-frame {
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-hairline);
	/* 0.0625rem = 1px given descent from html font-size  */
	box-shadow       : 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.08);
}

.layout-strong {
	padding          : 0.5rem;
	background-color : var(--colour-layout-strong);
	font-family      : var(--font-ui);
	font-size        : 1rem;
	font-weight      : bold;
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
	color            : var(--colour-text-strong);
}

.layout-fg {
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-fg);
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
}

.layout-contrast {
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-contrast);
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
}

.layout-bg {
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-bg);
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
}

/* class to make direct inline content of a cell (or, now, a div box) have more
   space around it (as if it were <td><p>WRITING</p></td>); makes a th/.layout-strong
   have the same top/bottom as the comfy td (a slighter increase for layout-strong). */
.comfy {
	padding-top      : 1rem;
	padding-bottom   : 1rem;
	/* left / right padding stays as-is in a comfy cell. */
}

/* class to turn off the padding of any of the above (i.e. hollow them out) in order to let it be filled by an a.control-box -- tag-agnostic (was td.hollow) so a div can use it too */
.hollow {
	/* hollow cells are centred by default. Use "style" on the td to override if need be. */
	padding          : 0;
	text-align       : center;
}
.hollow.algL {
	text-align       : left;
}
.hollow.algR {
	text-align       : right;
}

/* non-outlined box (with padding) */
td.basicbox {
	padding          : 0.625rem 0.5rem 0.625rem 0.5rem;
	background-color : var(--colour-layout-fg);
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
}

/* like basic box, but with no padding */
td.tightbox {
	padding          : 0;
	background-color : var(--colour-layout-fg);
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
}


/*
 * ===========
 * UI features
 * ===========
 */

/* this blocks links from inheriting "block" from the para they are in. 
   Some specific classes will override that. */
   /* the comment above seems to have come astray  */

a.link {
	color            : var(--colour-text-bright);
	text-decoration  : underline dotted var(--colour-text-bright);
}

a.link:hover, a.link:visited {
	text-decoration-style: dashed;
}

a.external::after {
	content          : url(../css/img/ext-link.png);
}
/* TODO there might need ot be a slightly different styling for <a> with external ref in the monochrome view...*/


/* text that is a control button. These go within [...], and appear inline (they don't fill a cell properly if made "block"). */
a[class*=control-], button[class*=control-] {
	cursor           : pointer;
	white-space      : nowrap;
	font-family      : inherit;
	font-size        : inherit;
	color            : var(--colour-text-bright);
}

/* Override the nowrap above for the "Observed collocate frequency" sort-link column header
   (collocation-ui.php): unlike the short 1-3 word icon+label links this rule is meant for, that
   header is a long phrase deliberately narrowed (via max-width on its <td>) so it wraps onto
   multiple lines instead of forcing its column wider than its actual data needs -- nowrap on the
   <a> itself was overriding that width constraint and letting the text spill out unwrapped
   regardless. Needs an ID, not just a class, to outrank the a[class*=control-] rule above. */
#collocHeaderObservedFreq .control-inline {
	white-space      : normal;
}

/* a button styled to look like the icon-link controls above (e.g. the categorise
   save/discard actions in print_control_row(), lib/concordance-lib.php) -- unlike an
   <a>, a <button> can be a genuine form submitter while still living outside its
   form via form="...", so this is used wherever an "action icon" needs to carry along
   sibling form fields rather than just navigate. Strip the native button chrome so it's
   indistinguishable from an a.control-inline. */
button.control-inline {
	background       : none;
	border           : none;
	padding          : 0;
	margin           : 0;
	line-height      : inherit;
}

a.control-inline, button.control-inline {
	display          : inline;
}

/* span.control-box-off formats text as a "dead link" IE an unusable control box.
   Without it, control boxes without an <a> would look weird. */
a.control-box, span.control-box-off {
	display          : block;
	padding          : 0.8rem;
}
a.control-inline:link, a.control-inline:visited, a.control-box:link, a.control-box:visited {
	text-decoration  : none;
}
a.control-inline:hover, a.control-inline:active, a.control-box:hover, a.control-box:active, button.control-inline:hover, button.control-inline:active  {
	background-color : var(--colour-layout-strong);
}
th a.control-inline:hover, th a.control-inline:active, th a.control-box:hover, th a.control-box:active  {
	text-decoration  : underline double;
}

/* creates hover-help with no actual action. */
a.control-info {
	cursor           : help;
	display          : inline;
}
a.control-info:hover {
	background-color : var(--colour-layout-strong);
	color            : var(--colour-text-bright);
}

/* Marks the currently-active choice in an icon-link toggle pair (e.g. the
   View/Order controls in the concordance control row) -- distinct from
   span.control-box-off, which specifically means "dead/unusable link". */
.view-toggle-active {
	display          : inline;
	font-weight      : bold;
	color            : var(--colour-text-normal);
	white-space      : nowrap;
}

/* The concordance action-icons row (print_control_row() in
   lib/concordance-lib.php) -- allow wrapping onto multiple lines rather
   than forcing a single unbreakable row of ~9 icon+label links. */
.action-icons {
	white-space      : normal;
	text-align       : center;
}
.action-icons a.control-inline, .action-icons button.control-inline, .action-icons span.control-inline {
	display          : inline-block;
	margin           : 0.15rem 0.75rem 0.15rem 0;
}
.action-icons button.control-inline:disabled {
	cursor           : default;
	color            : var(--colour-text-faint);
}

/* pagination rows (print_pagination_row() and its per-file equivalents)
   mix icon links with one or more literal <form> elements (a "Show Page:"
   jump box, a "Rows per page"/View/Order form, etc.) inside the same
   .action-icons row -- <form> is block-level by default (nothing in the
   site-wide reset changes that), so each one broke onto its own line
   below the icon links instead of sitting inline with them. Same
   margin-right as the icon links above, so the gap is consistent
   regardless of whether the next/previous item is a link or a form. */
.action-icons form {
	display          : inline-block;
	vertical-align    : middle;
	margin           : 0.15rem 0.75rem 0.15rem 0;
}

/* some pagination rows (e.g. print_collocation_pagination_row(),
   print_freqlist_pagination_row()) don't use a literal <form> at all --
   their button/input/select instead use form="changeDisplayForm" to
   submit to a form declared elsewhere, so the "Show Page: ... of N" bits
   and the following "Rows per page:"/"View:" <label> are bare siblings of
   .action-icons with no wrapping element to hang a margin off of (unlike
   the form-based case above). Without any gap, "Rows per page:" reads as
   a continuation of the "of N" text right before it. Give every <label>
   in this row its own left margin so there's always a visible break
   before it, regardless of what precedes it (bare text, a link, a form). */
.action-icons label {
	display          : inline-block;
	margin-left       : 0.75rem;
}

/* the categorise autosave status text ("No changes made"/"Unsaved changes!")
   sits right before the save/discard action buttons in the same merged
   .action-icons row -- give it the same gap the icons/buttons/forms use
   between each other, so it doesn't read as glued onto the first button. */
#autosaveStatusDisplay {
	display          : inline-block;
	margin-right      : 0.75rem;
}

/* A row of label+control pairs laid out horizontally instead of stacked
   as separate .settings-rows -- for a handful of short, closely-related
   settings (e.g. the collocation-controls span/stat/freq dropdowns in
   lib/collocation-ui.php) where one setting per line wastes vertical
   space without adding clarity. Wraps onto more lines on a narrow
   viewport rather than overflowing. Goes inside a .settings-full cell. */
.control-bar {
	display          : flex;
	flex-wrap        : wrap;
	align-items      : center;
	gap              : 2rem;
	margin-top       : 0.3rem;
}
.control-group {
	display          : flex;
	align-items      : center;
	gap              : 0.4rem;
	white-space      : nowrap;
}

/* "Extra information" disclosure on the collocation results page --
   term/definition pairs (one per metric), styled deliberately rather
   than left to un-styled browser dl/dt/dd defaults. */
.colloc-extra-info {
	margin           : 0;
}
.colloc-extra-info dt {
	font-family      : var(--font-ui);
	font-weight      : bold;
	color            : var(--colour-text-strong);
	margin-top       : 1.8rem;
}
.colloc-extra-info dt:first-child {
	margin-top       : 0;
}
.colloc-extra-info dd {
	margin           : 0.2rem 0 0 0;
	padding-left     : 0.9rem;
	border-left      : var(--border-width-hairline) solid var(--colour-layout-strong);
}

/* Folded-by-default "Extra information" disclosure at the bottom of the
   collocation results table (collocation-ui.php) -- and any other future
   use of a plain <details>/<summary> pair. */
summary {
	cursor           : pointer;
	padding          : 0.2rem 0;
}
details[open] summary {
	margin-bottom    : 0.4rem;
}


/*
 * ===========
 * Menu layout
 * ===========
 */
nav {
	width            : 14rem;
	border-style     : solid;
	border-color     : var(--colour-layout-outline); 
	border-width     : var(--border-width-hairline); 
	                  /* cos 1px = 0.0625em  */
}
/* .menuItem (not just a.menuItem): the group-heading buttons built by print_menu_group()
   (see below) share this same look, via <button class="menuItem header menu-group-toggle">
   rather than an <a> -- so these base rules must also match plain elements, not just anchors. */
.menuItem {
	display          : block;
	width            : 100%;
	box-sizing       : border-box;
	/* header items (.menuItem.header) use a different, smaller padding than plain items --
	   without border-box, that padding difference makes width:100% resolve to a different
	   rendered width for each, so headers and items no longer line up. */
	white-space      : nowrap;
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-fg);
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
	transition       : background-color 0.15s ease, color 0.15s ease;

	font-size        : 0.8rem;
	font-family      : var(--font-ui);
	text-align       : left;
	cursor           : pointer;
}
a.menuItem:link, a.menuItem:visited {
	background-color : var(--colour-layout-fg);
	color            : var(--colour-text-normal);
	text-decoration  : none;
}
.menuItem:hover, .menuItem:active {
	background-color : var(--colour-layout-bg);
	color            : var(--colour-text-bright);
	text-decoration  : none;
}

/* Currently-selected menu items & header items will not usually have an href;
 * ergo, no visited/hover, and colour always = normal */
.menuItem.current {
	background-color : var(--colour-layout-bg);
	color            : var(--colour-text-normal);
	text-decoration  : none;
	cursor           : default;
}
.menuItem.header {
	padding          : 0.5rem;
	background-color : var(--colour-layout-strong);
	color            : var(--colour-text-strong);
	text-align       : center;
	font-weight      : bold;
	font-size        : 1rem;
	text-decoration  : none;
}

/* Foldable sidebar sections (print_menu_group() in html-lib.php): collapsed by default, the
   group containing the page's current item starts open (see print_sidebar_menu()), and the
   ".menu-group-toggle" click handler in jsc/always.js flips ".open" on click. The arrow is a
   single glyph that rotates via aria-expanded, rather than swapping characters in JS. */
.menu-group-items {
	display          : none;
}
.menu-group.open .menu-group-items {
	display          : block;
}
.menu-group-toggle {
	display          : flex;
	align-items      : center;
	justify-content  : flex-start;
	gap              : 0.4rem;
	margin           : 0;
	appearance       : none;
	-webkit-appearance : none;
	color            : inherit;
	line-height      : normal;
}
.menu-group-toggle::before {
	content          : "\25B8";
	display          : inline-block;
	transition       : transform 0.15s ease;
}
.menu-group-toggle[aria-expanded="true"]::before {
	transform        : rotate(90deg);
}

/* The "menu | content" page shell, built by print_page_shell_begin()/
   print_page_shell_end() in html-lib.php -- replaces the old two-column
   <table class="layout-frame"> shell. Each <nav> and inner content table
   already carries its own border/shadow, so the shell itself is left
   unframed, consistent with the flat/minimal look. */
.page-shell {
	display          : flex;
	align-items      : flex-start;
	gap              : 0.9rem;
}
.page-shell-menu {
	flex             : 0 0 14rem;
	/* only the width changes on collapse -- animating it is cheap and makes
	   the collapse/expand read as a deliberate action, not a jump-cut. */
	transition       : flex-basis 0.15s ease;
}
.page-shell-content {
	flex             : 1 1 auto;
	min-width        : 0;
}

/* the "Menu" heading row: same look as a.menuItem.header (the other
   headings throughout the sidebar), but a flex row holding both the
   collapse toggle and the "Menu" label together -- and, unlike the rest
   of the menu, always visible (see print_page_shell_begin()), so this bar
   is what a collapsed sidebar actually shows: a coloured strip, not a
   bare floating button on the page background. */
.page-shell-menu-heading {
	display          : flex;
	align-items      : center;
	gap              : 0.5rem;
	padding          : 0.5rem;
	background-color : var(--colour-layout-strong);
	color            : var(--colour-text-strong);
	font-family      : var(--font-ui);
	font-weight      : bold;
	font-size        : 1rem;
	/* match the <nav> immediately below it (same border-width/colour, no
	   margin -- the two sit flush, like the old "Menu" heading nav used to
	   sit directly above the "Corpus queries" nav). */
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-hairline);
	margin           : 0;
}
.page-shell-toggle {
	/* reset native button chrome, same technique as button.control-inline --
	   this is meant to look like plain text/icon, not a boxed button. */
	display          : block;
	background       : none;
	border           : none;
	padding          : 0;
	margin           : 0;
	color            : inherit;
	font-size        : 1.1rem;
	line-height      : 1;
	cursor           : pointer;
}

/* collapsed: shrink the flex-basis down to just the heading row's own
   width, and hide the actual menu content -- min-width:0 on the item
   above already lets the track shrink to whatever this width ends up
   being, exactly the same mechanism used for the .settings-panel columns.
   The heading row (and its background colour) stays visible either way. */
.page-shell-menu.collapsed {
	flex-basis       : 2.5rem;
}
.page-shell-menu.collapsed .page-shell-menu-inner {
	display          : none;
}
.page-shell-menu.collapsed .page-shell-menu-heading {
	justify-content  : center;
}
.page-shell-menu.collapsed .page-shell-menu-label {
	display          : none;
}

@media (max-width: 48rem) {
	.page-shell {
		flex-direction : column;
	}
	.page-shell-menu {
		flex-basis     : auto;
		width          : 100%;
	}
	.page-shell-menu nav {
		width          : 100%;
	}
	.page-shell-menu.collapsed {
		flex-basis     : auto;
		width          : auto;
	}
}

/* Query form (print_search_box() in lib/query-forms.php) label/control
   rows -- replaces the old <table><td class="basicbox"> row layout.
   Every id/name the JS in jsc/queryhome.js and jsc/keyboard.js relies on
   (#qmode, #searchBox, #qstrategy, #searchBoxAttributeInfo, #ceqlManLink,
   #resetQueryButton) is unchanged; only this wrapping markup is new. */
.query-form-grid {
	display          : flex;
	flex-direction   : column;
	gap              : 0.6rem;
	margin           : 0.9rem 0;
}
.query-form-row {
	display          : flex;
	align-items      : center;
	flex-wrap        : wrap;
	gap              : 0.6rem;
}
.query-form-row > label {
	flex             : 0 0 12rem;
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
}

/* The p-/s-/a-attribute reference table in print_search_box() -- first
   column narrowed to match the query-form label width instead of the old
   inline width="40%" (which was much too wide). */
.attribute-info-table td:first-child:not([colspan]) {
	width            : 12rem;
}

/* Inline list of an attribute's actual distinct values (e.g. a POS tagset),
   shown in the p-/s-/a-attribute reference table -- see print_search_box()
   in lib/query-forms.php. */
.tag-list {
	display          : inline-block;
	margin-top       : 0.2rem;
	font-family      : monospace;
	font-size        : 0.75rem;
	color            : var(--colour-text-faint);
}



/*
 * =============================
 * Styles for concordance layout
 * =============================
 */

/* kwic layout concordance line */
td.kwic {
	padding          : 0.35rem 0.5rem;
	background-color : var(--colour-layout-fg);
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
}

td.kwic.before {
	border-width     : var(--border-width-strong)  0rem  var(--border-width-strong)  var(--border-width-strong);
	text-align       : right;
}

td.kwic.after {
	border-width     : var(--border-width-strong)  var(--border-width-strong)  var(--border-width-strong)  0rem;
	text-align       : left;
}

td.kwic.node {
	background-color : var(--colour-layout-data2);
	border-width     : var(--border-width-strong)  var(--border-width-hairline);
	text-align       : center;
}

td.lineview {
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-fg);
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
}

/* TODO note that parallel-line repeats lineview. So: td.lineview.parallel instead, likewise td.kwic.parallel? --- which only implement overrides? */
td.parallel-line {
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-data2);
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
}
td.parallel-kwic {
	padding          : var(--boxpad-default);
	background-color : var(--colour-layout-data2);
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
	text-align       : center;
}

td.text_id, td.conc_ln {
	padding          : 0.35rem 0.5rem;
	background-color : var(--colour-layout-fg);
	border-style     : solid;
	border-color     : var(--colour-layout-outline);
	border-width     : var(--border-width-strong);
	text-align       : center;
}

	/* TODO this style seems not to be used ........... but should be? */
span.hit {
	color            : var(--colour-text-bright);
	font-weight      : bold;
}
span.highlight {
	font-weight      : bold;
}
div.node {
	font-weight      : bold;
}

/*
 * nothing is yet done with the next two classes, just laying down a marker 
 */
span.cqp-target {
	font-weight      : bold;
}
span.cqp-keyword {
	font-weight      : bold;
}

span.time-report {
	background-color : var(--colour-layout-fg); /* TODO this is a HAAAAAAAAAACK */
	color            : var(--colour-text-faint);
	font-size        : 0.83333rem;
	font-weight      : normal;
}



/*
 * ====================================
 * Extra styles for keywords/wordclouds
 * ====================================
 *
 * "wordcloudQuery" is used for links in a Wmatrix-style wordcloud.
 */
a.wordcloudQuery {
	/* 1rem because 16px = middle for the font keywords. The different <a> elements in the cloud override the size as needed. */
	font             : bold 1rem Arial, Helvetica, sans-serif;
	color            : blue;
}
a.wordcloudQuery:visited {
	color            : blue;
}
a.wordcloudQuery:hover {
	color            : red;
}


/*
 * ===========================
 * Extra styles for gloss view
 * ===========================
 */

/* the table for right or left or node */
.glossbox-frame {
	display          : inline-block;
	margin           : 0.125rem;
}

.glossbox {
	text-align       : left;
	padding          : 0.125rem;
	margin           : 0.0625rem; 
	white-space      : nowrap;
}

/* not needed yet. Might be needed later. 
.glossbox.line1 {
	
}
.glossbox.line2 {
	
}
*/


/* 
 * =================
 * Styles for footer
 * =================
 */
/* replaces the old 3-cell <table> footer: three equal-width flex items,
   one per algL/algC/algR alignment, instead of table columns. */
.footer-row {
	display          : flex;
}

.footbox {
	flex             : 1 1 0;
	padding          : 0.6rem 0.9rem;
	background-color : transparent;
	border           : none;

	font-family      : var(--font-ui);
	font-size        : 0.75rem;
	color            : var(--colour-text-faint);
}
a.copynote:link, a.copynote:visited {
	color            : var(--colour-text-faint);
	text-decoration  : none;
}
a.copynote:hover {
	color            : var(--colour-text-bright);
	text-decoration  : underline;
}


/*
 * ===================================
 * Popup UI overlays: begin invisible. 
 * ===================================
 */
.popup-ui { 
	display          : none; 
}


/* 
 * ==============================================================================================
 * latedata: non-rendered nodes that add variables to the global app datastore at initialisation. 
 * ==============================================================================================
*/ 
.latedata { 
	display          : none; 
}

/*
 * ===================================
 * Greyout overlay: positioning 
 * ===================================
 */
.greyout-content {
	position         : absolute;
	left             : 50%;
	top              : 50%;
	transform        : translate(-50%, -50%);
	background-color : var(--colour-layout-outline);
	/* i.e. provide a "white" backdrop over the greyout, like the base layer of the page. */
}


/* 
 * ==================================================
 * the next three classes support the tooltip system. 
 * ==================================================
 */


/* TODO    Possibly variable-ise the tooltip colors? And other appearance stuff?
	   then, the  "configurable" things would be settable in a custom CSS file     */
div.floatingToolTip  {
	/* configurable */
	width            : 20rem;                        /* initial width of each tooltip box. */ 
	background-color : var(--colour-tooltip-frame);  /* colour parameter -- colour of border */
	padding          : 0.125rem;                     /* padding controls width of "border", which is 1 + padding */
	opacity          : 1.0;                          /* should the floating tooltip box be opaque ? */
	/* end configurable */

	/* these are part of the system: should not be changed. */
	visibility       : hidden;
	position         : absolute;
	z-index          : -1010;
	left             : 0;
	top              : 0;
}

table.floatingToolTipFrame {
	width            : 100%;
	opacity          : inherit;
}

td.floatingToolTipTarget {
	/* configurable */
	background-color : var(--colour-tooltip-bg);     /* colour parameter -- colour of background */
	color            : var(--colour-tooltip-text);   /* colour parameter -- colour of tooltip text */
	font-family      : var(--font-ui);
	font-size        : 0.6666rem;
	font-weight      : normal;
	text-align       : left;
	/* end configurable */
	padding          : 0.125rem;
	opacity          : inherit;
}


/*
 * ==========================================================
 * corpus card grid -- "corpora available on this server" on
 * the main homepage (replaces the old fixed 3-column table).
 * ==========================================================
 */

.corpus-cat-heading {
	margin           : 1rem 0 0.5rem 0;
	font-family      : var(--font-ui);
	font-size        : 0.85rem;
	font-weight      : bold;
	text-transform   : uppercase;
	letter-spacing   : 0.05em;
	color            : var(--colour-text-faint);
}

.corpus-grid {
	display              : grid;
	grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
	gap                  : 0.75rem;
	margin               : 0.5rem 0 1rem 0;
}

a.corpus-card {
	display          : flex;
	flex-direction   : column;
	gap              : 0.3rem;
	padding          : 0.9rem 1rem;
	border-style     : solid;
	border-width     : var(--border-width-hairline);
	border-color     : var(--colour-layout-strong);
	border-radius    : 0.25rem;
	background-color : var(--colour-layout-fg);
	box-shadow       : 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.08);
	text-decoration  : none;
	transition       : box-shadow 0.15s ease, border-color 0.15s ease;
}

a.corpus-card:link, a.corpus-card:visited {
	color            : var(--colour-text-normal);
}

a.corpus-card:hover, a.corpus-card:active {
	border-color     : var(--colour-text-bright);
	box-shadow       : 0 0.125rem 0.375rem rgba(0, 0, 0, 0.12);
}

.corpus-card-title {
	font-family      : var(--font-ui);
	font-weight      : bold;
	color            : var(--colour-text-bright);
}

.corpus-card-meta {
	font-family      : var(--font-ui);
	font-size        : 0.75rem;
	color            : var(--colour-text-faint);
}


/*
 * ==========================================================
 * main homepage: welcome banner / recent corpora / quick
 * links (replaces the old nested "basicbox" checkered
 * tables above the corpus card grid).
 * ==========================================================
 */

/* Height of the header-bar logos, hardcoded as height="80" on the <img> in
   main-home-ui.php (see the $logo_divs loop). Kept as a variable so the bar
   and the welcome text stay in step if that ever changes. */
:root {
	--mainhome-logo-height : 80px;
}

.mainhome-header {
	text-align       : center;

	/* The two logos are float:left / float:right, and floats don't contribute
	   to their parent's height -- so without a block formatting context this
	   bar collapses to a single line of text and the logos hang out below it.
	   flow-root establishes that context, making the bar as tall as the logos
	   whatever their height. */
	display          : flow-root;
}

.mainhome-header > span {
	/* Centre the welcome message against the logos instead of leaving it on
	   the first text line. inline-flex leaves the parent's text-align:center
	   handling the horizontal axis, while align-items handles the vertical,
	   and it still grows correctly if the message wraps on a narrow screen. */
	display          : inline-flex;
	align-items      : center;
	min-height       : var(--mainhome-logo-height);
}

.mainhome-section {
	/* the section itself (background/border from .layout-fg) stays full
	   width, matching the .mainhome-header bars; only its inner wrapper
	   (.mainhome-section-inner) is capped/centred, so text and cards
	   don't stretch edge-to-edge on a wide display. */
}

.mainhome-section-inner {
	max-width        : 60rem;
	margin           : 0 auto;
}


/*
 * ==========================================================
 * settings panel -- generic div-based replacement for the
 * "layout-frame table full of label/control/button rows"
 * pattern used throughout the admin screens (corpus settings,
 * user settings, cache control, etc). Reuses .layout-frame/
 * .layout-strong/.layout-bg/.layout-fg for box styling; these
 * classes just add the row layout on top.
 *
 * ----------------------------------------------------------
 * DESIGN RULE -- when to use which row shape
 * ----------------------------------------------------------
 * Every .settings-row is either a 3-COLUMN FIELD ROW (label +
 * control [+ action]) or a FLAT ROW (a single .settings-full
 * cell spanning all 3 columns). Which one to use is decided by
 * one question:
 *
 *     Is there a label phrase that NAMES a setting?
 *
 *   - YES -> 3-column. .settings-label states what the field
 *     is; .settings-control holds the input/select/textarea for
 *     it; .settings-action (if that field submits on its own)
 *     holds the button. Sub-cases:
 *       - No action needed for this row -> leave out
 *         .settings-action entirely. The control automatically
 *         expands into columns 2-3 (the `:last-child` rule
 *         below) -- do NOT add an empty placeholder div.
 *       - One action serves several stacked field rows (e.g. a
 *         multi-field "Create new X" form) -> put the button in
 *         the FIRST row's .settings-action with
 *         `style="grid-row: span N;"` (N = number of field
 *         rows), and pin every one of those rows' lone
 *         .settings-control to `style="grid-column: 2;"` --
 *         otherwise the `:last-child` auto-span rule expands
 *         each of them into column 3 too, silently overlapping
 *         the spanning action button.
 *
 *   - NO (the row is just a block, not a named field) -> flat:
 *     one .settings-full cell, no separate control/action.
 *     Covers:
 *       - instructional/message/warning text
 *       - a genuine per-record data table (kept as a real
 *         <table>, just wrapped in .settings-full for chrome)
 *       - a chip-list of related action links
 *       - a standalone action with nothing to name (e.g. a
 *         lone "Submit"/"Create" button under a form with no
 *         other fields in its row) -> `class="... algC
 *         settings-full"`, NOT a lone .settings-action. algC is
 *         needed because .settings-full itself has no default
 *         centring (removed deliberately, see below).
 *
 * A row like "Select a group: [dropdown] [button]" is 3-column
 * (there's a label naming the field), even though the whole
 * row reads like "one action" -- the label is what decides it,
 * not how many interactive elements the row has.
 * ==========================================================
 */

/* .settings-panel is the grid: all its .settings-row children are made
   "invisible" (display:contents) so their label/control/action divs become
   direct grid items sharing ONE set of column tracks -- this is what keeps
   the label|control divider a straight line down the whole panel, the way
   a <table> automatically aligns columns across all its rows. Independent
   per-row flexboxes can't do this: each row would size its columns from
   only its own content, so the divider drifts row to row. */
.settings-panel {
	display              : grid;
	/* the action column's max used to be `auto`, which the grid spec defines
	   as equivalent to max-content -- i.e. the track grows to fit the WIDEST
	   unwrapped button/link label among every row sharing this panel. A
	   percentage max-width (or white-space:normal) on the button can't
	   override that: percentage max-widths don't participate in intrinsic
	   track-size calculation, so they're ignored during this step. That's
	   why long button labels (e.g. "Run group regex against existing
	   users") kept overflowing/forcing the column wide no matter what CSS
	   was tried on the button itself -- the fix has to be on the track's
	   sizing function, not the button. `fr` tracks size from the panel's
	   available space instead of any item's content, so long labels are
	   forced to wrap within the column's share instead of stretching it. */
	grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr);
}

.settings-row {
	display          : contents;
}

.settings-heading {
	grid-column      : 1 / -1;
	text-align       : center;
}

/* NOTE: these are plain classes, not scoped to ".settings-row >" -- they're
   reused both as grid items inside a multi-row .settings-panel (via
   .settings-row's display:contents) AND as plain flex-row children inside
   a standalone single-row .confirm-row. The box styling is identical
   either way; only the parent decides row-vs-grid placement. */
.settings-label,
.settings-control,
.settings-action,
.settings-full {
	/* grid items default to min-width:auto, which refuses to shrink below
	   the content's natural width -- that's what let long labels/dropdowns
	   overflow their column instead of wrapping. min-width:0 lets the
	   browser actually shrink the item to the track width and wrap text. */
	min-width        : 0;
	overflow-wrap     : break-word;
}

/* Explicit grid-column per cell type (ignored outside a grid, e.g. inside
   .confirm-row's flexbox, so this is safe to declare unconditionally).
   Needed because .settings-row is display:contents: that flattens every
   row's items into ONE sequence for the grid's auto-placement, which fills
   left-to-right by column COUNT, not by which PHP loop iteration an item
   came from. A row with only label+control (no action) would otherwise
   get auto-placed into whatever columns happen to be next in the flat
   sequence, drifting out of alignment with 3-item rows. Pinning each
   class to a fixed column keeps every row's label under every other
   row's label, etc, regardless of how many cells that particular row has. */
.settings-label {
	grid-column      : 1;
}
.settings-control {
	grid-column      : 2;
}
.settings-action {
	grid-column      : 3;
}

/* a row with no action cell: let the control cell take over that space
   (via :last-child, i.e. no .settings-action sibling follows it) instead
   of leaving column 3 as an empty gap. */
.settings-row > .settings-control:last-child {
	grid-column      : 2 / -1;
}

.settings-label,
.settings-control,
.settings-action {
	/* flex-direction:column matters here: several labels/controls have more
	   than one block child (e.g. two <p> tags) -- without it, flex's
	   default row direction lays those children out side by side instead
	   of stacked, blowing the box far wider than its grid column. */
	display          : flex;
	flex-direction   : column;
	gap              : 0.5rem;
	align-items      : center;
	justify-content  : center;
	text-align       : center;
}

/* Every direct child of these three is a flex item -- but because
   align-items is center (not stretch), each child's cross-axis (width)
   size is its own shrink-to-fit/natural size, not stretched to fill the
   container. .settings-control select/textarea/input and .settings-action/
   -control button already cap themselves directly (below), but a plain
   <p> wrapper (used to group multi-line text/controls, e.g. a <p> around
   a wide <input size="50">) has no width of its own: its natural size is
   its content's preferred width, so it can size itself past the column's
   actual width regardless of any max-width on what's inside it -- it's
   the <p> box itself that's oversized, not its contents. width:100% (not
   max-width:100%) is used deliberately, forcing a DEFINITE size instead
   of leaving the <p> to shrink-to-fit sizing, which isn't reliably capped
   by the column width on its own. box-sizing:border-box is needed
   alongside it since there's no site-wide border-box reset: without it, a
   padded/bordered element (not <p> itself today, but possible on other
   direct-child wrappers later) would overflow its own 100% box by exactly
   its padding+border. */
.settings-label > p,
.settings-control > p,
.settings-action > p {
	width            : 100%;
	box-sizing       : border-box;
}

/* a <select>/<textarea>/<input> sizes to its widest option/content by
   default, which can force it past the edge of its column -- cap it with
   max-width (min-width:0 alone isn't enough: that lets the box shrink,
   this actually tells it to). Needed here too and not just on the > p
   rule above because these can be nested inside a <p> wrapper (see
   above), so they aren't always themselves the direct flex-item child
   that rule targets. box-sizing:border-box matters for the same reason
   it was added to the > p rule: there's no site-wide border-box reset, so
   an element's padding+border are added ON TOP of a content-box
   max-width:100% -- for a <select>/<input> with visible padding+border
   (see the flat-styling rule near the top of the file), that was enough
   on its own to poke a few pixels past the edge of an otherwise correctly
   -capped column, even after the % width itself was resolving right. */
.settings-control select,
.settings-control textarea,
.settings-control input {
	min-width        : 0;
	max-width        : 100%;
	box-sizing       : border-box;
}

/* A <table> used as a mini layout grid inside one settings-panel cell (e.g. the plugin-admin
   "extra configuration" key/value rows, admin-home-forms.php) is its own special case, distinct
   from the select/textarea/input rule above: percentage max-width on the <input>s inside it
   doesn't stop the TABLE ITSELF from contributing its unshrunk content width (driven by each
   <input>'s size="n" attribute) to the settings-panel grid column's own intrinsic sizing --
   percentage widths are ignored during that "how wide does this content want to be" pass, so the
   inputs' own max-width:100% never gets a chance to matter until AFTER the column has already
   been forced wide by them. table-layout:fixed sidesteps the whole problem: column widths no
   longer depend on cell content at all, so the table can't force its container wider than
   available space -- and once the table itself is correctly capped, the existing input rule
   above correctly shrinks each <input> to fit its now-constrained cell. */
.settings-label > table,
.settings-control > table,
.settings-action > table {
	width            : 100%;
	table-layout     : fixed;
	box-sizing       : border-box;
}

/* a <button> with a long label (e.g. "Run group regex against existing
   users") otherwise sizes to its content and forces the action column
   wider than its track -- cap it and let the label wrap instead. Needs
   min-width:0 too: the button is itself a flex item of its
   .settings-action/.settings-control parent, and flex items default to
   min-width:auto (not 0), which refuses to shrink below the button's
   unwrapped content width regardless of max-width. */
.settings-action button,
.settings-control button {
	min-width        : 0;
	max-width        : 100%;
	white-space      : normal;
}

/* a settings-row with only a label + a full-width control (no separate
   action column) -- e.g. an instructional/message row spanning the row. */
.settings-row > .settings-full {
	grid-column      : 1 / -1;
}

/* only the instructional/message variant (paired with .layout-bg) gets the
   data2 tint -- the full-width button row (paired with .layout-fg) keeps
   its normal background. */
.layout-bg.settings-full {
	background-color : var(--colour-layout-data2);
}

/* a genuine per-record data table (kept as a real <table>, see the design
   rule above) sits directly inside .settings-full for chrome -- but the
   layout-*'s own padding then doubles up with the table's own cell
   padding, framing it with an odd extra gap on every side. Remove it
   specifically for this shape (table as the direct child, or the
   .table-scroll wrapper used around a table of unbounded width -- see
   print_sql_result_dump(), sql-lib.php) so the table sits flush, without
   affecting any layout-*.settings-full padding elsewhere. Not scoped to
   .layout-fg specifically: .settings-full is combined with layout-fg/-bg/
   -contrast depending on context, and this shape needs the same treatment
   regardless of which one. */
.settings-full:has(> table),
.settings-full:has(> .table-scroll) {
	padding          : 0;
}

/* Safety net for every OTHER results table across the app (collocation, keywords, freqlist,
   breakdown, distribution, concordance, etc.) that sits directly inside .settings-full, the same
   shape as the rule above but without a dedicated .table-scroll wrapper of its own: long content
   in any cell (a long collocate/token, a long query-match phrase, ...) could otherwise force the
   table -- and via it the whole settings-panel grid track, and the page -- wider than the
   viewport, the same failure mode fixed for the admin SQL-table dump (print_sql_result_dump(),
   sql-lib.php). .settings-full already has min-width:0 (see above), so combined with overflow-x
   here, an overlong table now scrolls WITHIN its own cell instead of pushing the page outward --
   invisible/inactive when the table already fits, exactly like .table-scroll. */
.settings-full:has(> table) {
	overflow-x       : auto;
}

/* a short vertical list of radio/checkbox + label pairs inside a
   settings-control cell (replaces a small layout-only inner table). */
.settings-radio-list {
	display          : flex;
	flex-direction   : column;
	gap              : 0.3rem;
}

/* space between adjacent radio/checkbox + label pairs when several are
   grouped inline inside one settings-control cell (e.g. "Start tag" /
   "End tag", or "Yes" / "No") -- without this, the pairs run straight
   into each other with only a single space between them. */
.settings-control input[type="radio"] + label,
.settings-control input[type="checkbox"] + label {
	margin-right     : 1.5rem;
}

/* a standalone single flex row for a "confirm + action" pair, when the
   surrounding box is just one row rather than a full multi-row
   .settings-panel grid (e.g. a one-off "are you sure? [checkbox] [Delete]"
   panel). Reuses .settings-control/.settings-action for their own
   internal stacking/centring. */
.confirm-row {
	display          : flex;
	flex-wrap        : wrap;
	align-items      : stretch;
}
.confirm-row > .settings-label,
.confirm-row > .settings-control {
	flex             : 2 1 16rem;
}
.confirm-row > .settings-action {
	flex             : 0 0 auto;
}

.mainhome-welcome {
	text-align       : center;
	font-family      : var(--font-ui);
	font-size        : 1.1rem;
	margin           : 0.5rem 0 1.5rem 0;
}

.mainhome-account-links {
	display          : flex;
	justify-content  : center;
	gap              : 1.5rem;
}

/* generic flex-wrap multi-column layout (was mainhome-specific; reused
   anywhere a couple of boxes should sit side by side and wrap on narrow
   screens, e.g. the per-scheme panels in corpus-admin-forms.php). */
.flex-columns {
	display          : flex;
	flex-wrap        : wrap;
	gap              : 1.5rem;
	margin           : 0.5rem 0 1rem 0;
}

.flex-column {
	flex             : 1 1 16rem;
	min-width        : 16rem;
}

.flex-column-heading {
	margin           : 0 0 0.5rem 0;
	font-family      : var(--font-ui);
	font-size        : 0.85rem;
	font-weight      : bold;
	text-transform   : uppercase;
	letter-spacing   : 0.05em;
	color            : var(--colour-text-faint);
}

/* generic flex-wrap "chip" list of pill-shaped links -- used for the
   homepage's recently-used corpora and for plain link grids elsewhere
   (e.g. the "users with access" listing in corpus-admin-forms.php)
   that used to be arranged with a layout-only table. */
.chip-list {
	display          : flex;
	flex-wrap        : wrap;
	gap              : 0.5rem;
}

a.chip {
	display          : inline-block;
	padding          : 0.4rem 0.9rem;
	border-style     : solid;
	border-width     : var(--border-width-hairline);
	border-color     : var(--colour-layout-strong);
	border-radius    : 999px;
	background-color : var(--colour-layout-fg);
	color            : var(--colour-text-bright);
	font-family      : var(--font-ui);
	font-size        : 0.8rem;
	text-decoration  : none;
	transition       : background-color 0.15s ease, box-shadow 0.15s ease;
}

a.chip:hover, a.chip:active {
	background-color : var(--colour-layout-contrast);
	box-shadow       : 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.08);
}

.mainhome-linklist {
	list-style       : none;
	margin           : 0;
	padding          : 0;
	display          : flex;
	flex-direction   : column;
	gap              : 0.4rem;
}

