/* CSS file for module related styles */

.category-page-content-container {
	box-sizing: border-box;
	margin: 0 auto;
	max-width: 1200px;
	padding: 24px;
}

/* The columns are filled rather than fitted, so a card is the same size whether the catalog offers one
   category or a dozen. Fitting them collapses the empty columns and stretches a lone card across the
   page, which reads as a banner rather than as one of several things to choose between. */
.category-card-grid {
	display: grid;
	gap: 24px;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	margin-top: 24px;
}

.category-card {
	background: #ffffff;
	border: 1px solid #dce3eb;
	border-radius: 12px;
	box-shadow: 0 4px 14px rgb(23 63 107 / 10%);
	color: inherit;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	text-decoration: none;
	transition: box-shadow 150ms ease, transform 150ms ease;
}

.category-card:hover,
.category-card:focus-visible {
	box-shadow: 0 8px 22px rgb(23 63 107 / 18%);
	transform: translateY(-2px);
}

.category-card-image {
	display: block;
	height: 150px;
	object-fit: cover;
	width: 100%;
}

/* The icon of a category on its detail page is shown as tall as the button that uploads a new one. Its width follows
   its shape, so a wide image is not shrunk to fit a square. */
.category-icon-upload {
	align-items: center;
	display: flex;
	gap: 10px;
	justify-content: space-between;
	width: 100%;
}

.category-icon-current {
	display: block;
	height: 40px;
	max-width: 120px;
	object-fit: contain;
	width: auto;
}

/* The uploader is only its button here, pushed to the right edge of the field. */
.category-icon-upload .psfileuploader-root {
	margin-left: auto;
	width: auto;
}

.category-icon-upload .psfileuploader-main-container {
	margin-top: 0;
	width: auto;
}

.category-card-content {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: 18px;
}

.category-card-name {
	color: #173f6b;
	font-size: 1.1rem;
	line-height: 1.4;
	margin: 0 0 10px;
	text-align: center;
}

.category-card-name:last-child {
	margin-bottom: 0;
}

.category-card-description {
	color: #5d6875;
	font-size: 0.95rem;
	line-height: 1.5;
	margin: 0;
	text-align: center;
}

.category-card-document-count {
	color: #173f6b;
	font-size: 0.9rem;
	font-weight: 600;
	margin: auto 0 0;
	padding-top: 12px;
	text-align: center;
}

.category-empty-message {
	color: #5d6875;
	margin-top: 24px;
}

.documents-by-category-page {
	box-sizing: border-box;
	margin: 0 auto;
	max-width: 1000px;
	padding: 24px;
}

.documents-by-category-back {
	display: inline-block;
	margin-bottom: 12px;
}

.document-list {
	display: grid;
	gap: 16px;
	margin-top: 24px;
}

.document-list-item {
	background: #ffffff;
	border: 1px solid #dce3eb;
	border-radius: 10px;
	padding: 20px;
}

.document-list-item h2 {
	font-size: 1.2rem;
	margin: 0 0 8px;
}

.document-list-item time {
	color: #687483;
	font-size: 0.9rem;
}

.document-list-item p {
	line-height: 1.6;
	margin: 12px 0 0;
}

/* Shown under a search result that lists fewer documents than matched. */
.document-list-limit {
	color: #687483;
	font-size: 0.9rem;
	margin: 16px 0 0;
}

/* DocumentUpload wizard (Pages/Home/Wizard/DocumentUpload_Step1.cshtml):
   #hdactions exists only so callBackForFileUploaderSuccess() has something
   to replace via $("#hdactions").html(...) after an upload. It has no
   layout purpose of its own, but wrapping the _UploadActions partial's
   psformitem elements in a plain div takes them out of
   psformcontainer's direct-child layout, so the status/action content
   renders out of alignment with the txtUploadDocument row above it.
   display:contents drops the wrapper from the box model so its
   children line up as if they were direct children of
   psformcontainer again. */
#hdactions {
	display: contents;
}

/* Page one published document is read on (Pages/Catalog/DocumentViewer.cshtml).
   The document is a complete page with a stylesheet of its own, so it is shown
   in a frame: nothing here reaches inside it, and its own rules cannot restyle
   the portal around it. The page fills the space between the top bar and the
   footer exactly, the header takes what it needs at the top, and the frame takes
   the rest and scrolls by itself. That frame is the only scrollbar, and a link
   inside the document to a heading scrolls the frame, so the heading arrives at
   the top of the frame and never under the header. How wide the text runs is
   decided by the stylesheet of the document, which lays it out as a printed page. */
.document-reader-page {
	/* The working area of the portal is a centering flex column, which sizes its
	   children to their own content instead of to the area. A document is not a
	   card that finds its own width or height: it takes the area it is given, so
	   this stretches back over that centering and grows to the height of the area.
	   The minimum height lets it be smaller than what it holds, so what it holds
	   scrolls inside it rather than stretching the working area into scrolling.

	   That working area also insets its content by 20px on the sides and below. A
	   document arrives with margins of its own, designed into the stylesheet it is
	   published with, so that inset is given back and the frame runs from edge to
	   edge and down to the footer, and the document is read the way it was made. */
	align-self: stretch;
	box-sizing: border-box;
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	margin-bottom: -20px;
	margin-inline: -20px;
	min-height: 0;
	width: calc(100% + 40px);
}

/* The header never moves: it sits above the frame rather than over it, naming the
   version being read and the ways of taking it away, which stay true wherever
   the reader has got to in a document that can be hundreds of pages long. */
/* Three sections: where the reader came from, what they are reading, and how to
   take it away. The outer columns share what is left over, so the middle one is
   centred on the page however long the two sides happen to be. */
.document-reader-header {
	align-items: center;
	background: #ffffff;
	border-bottom: 1px solid #dce3eb;
	box-sizing: border-box;
	column-gap: 16px;
	display: grid;
	flex: 0 0 auto;
	grid-template-columns: 1fr auto 1fr;
	padding: 12px 24px;
	row-gap: 8px;
	width: 100%;
}

.document-reader-header-left {
	justify-self: start;
}

.document-reader-header-middle {
	color: #687483;
	display: flex;
	flex-wrap: wrap;
	font-size: 0.9rem;
	gap: 16px;
	justify-content: center;
	justify-self: center;
}

.document-reader-header-right {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: flex-end;
	justify-self: end;
}

.document-reader-header-right > span {
	color: #687483;
	font-size: 0.9rem;
}

/* How large the document is read: three levels beside each other, the one in use
   pressed in. The zoom itself is written into the frame by Atlas.js. */
.document-reader-zoom {
	align-items: center;
	display: flex;
	gap: 4px;
}

.document-reader-zoom > span {
	color: #687483;
	font-size: 0.9rem;
	margin-right: 4px;
}

.document-reader-zoom-button {
	background: #ffffff;
	border: 1px solid #dce3eb;
	border-radius: 4px;
	color: inherit;
	cursor: pointer;
	font: inherit;
	font-size: 0.85rem;
	padding: 2px 8px;
}

.document-reader-zoom-button:hover {
	background: #f2f5f8;
}

.document-reader-zoom-button[aria-pressed="true"] {
	background: #dce3eb;
	border-color: #687483;
	font-weight: 600;
}

/* The languages a document is published in: the one being read is pressed in, the others are links to
   the same document in that language. */
.document-reader-languages {
	align-items: center;
	display: flex;
	gap: 4px;
}

.document-reader-language {
	border: 1px solid #dce3eb;
	border-radius: 4px;
	color: inherit;
	font-size: 0.85rem;
	padding: 2px 8px;
	text-decoration: none;
}

a.document-reader-language:hover {
	background: #f2f5f8;
}

.document-reader-language[aria-current="true"] {
	background: #dce3eb;
	border-color: #687483;
	font-weight: 600;
}

/* The header of the documents list has the left section only. It runs edge to edge like the
   viewer header, giving back the inset of the working area, and the one section takes the
   whole width instead of a third of it. */
.documents-header {
	grid-template-columns: 1fr;
	margin-inline: -20px;
	width: calc(100% + 40px);
}

/* Too narrow for three sections beside each other: they stack and read in order. */
@media screen and (max-width: 720px) {
	.document-reader-header {
		grid-template-columns: 1fr;
	}

	.document-reader-header-middle,
	.document-reader-header-right {
		justify-content: flex-start;
		justify-self: start;
	}
}

.document-reader-download-size {
	color: #687483;
	font-size: 0.85rem;
}

/* The frame takes all the height the header leaves, and scrolls by itself. The
   minimum height lets the page shrink it below the height of the document it
   holds, which is what makes it scroll instead of growing. */
.document-reader-frame {
	border: 0;
	display: block;
	flex: 1 1 auto;
	min-height: 0;
	width: 100%;
}

.document-reader-notice {
	box-sizing: border-box;
	margin: 0 auto;
	max-width: 1000px;
	padding: 24px;
}

.document-reader-withdrawn {
	line-height: 1.6;
}

.document-reader-facts {
	display: grid;
	gap: 4px 16px;
	grid-template-columns: max-content 1fr;
	margin: 16px 0;
}

.document-reader-facts dt {
	font-weight: 600;
}

.document-reader-facts dd {
	margin: 0;
}
/* Metadata contract (Pages/Admin/MetadataContract.cshtml).

   The contract is read rather than filled in, so it is drawn as the vocabulary it states: a block per
   dimension, a chip per value. One drawing serves both the contract standing on its own and one about
   to be imported, because a contract compared against its own vocabulary marks nothing. */

/* The colours are those of the portal rather than of this page: orange is what the vocabulary gains, dark
   red what an import would write over, and a value neither touches is dimmed rather than coloured. They
   are stated on the root because the legend, the section notes and the result banners are drawn outside
   the contract container and are marked the same way. */
:root {
	--atl-new: #f48220;
	--atl-new-soft: #fbf2e9;
	--atl-changed: #a32b21;
	--atl-changed-soft: #f7e4e2;
	--atl-absent: #7a7676;
	--atl-line: #d8d6d5;
	--atl-surface: #f5f5f5;
	--atl-text-soft: #5b5654;
}

.atl-contract {
	display: grid;
	gap: 12px;
	margin: 12px 0 24px 0;
}

.atl-contract-dimension {
	border: 1px solid var(--atl-line);
	border-left: 4px solid var(--atl-line);
	border-radius: 4px;
	padding: 10px 14px;
}

.atl-contract-dimension.is-new {
	border-color: var(--atl-new);
	background: var(--atl-new-soft);
}

.atl-contract-dimension.is-changed {
	border-color: var(--atl-changed);
	background: var(--atl-changed-soft);
}

.atl-contract-dimension.is-absent {
	opacity: 0.55;
}

.atl-contract-dimension-head {
	align-items: baseline;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.atl-contract-dimension-head .atl-contract-name {
	font-weight: 600;
}

/* A value is one of many under its dimension, so it is named without competing with it. */
.atl-contract-option .atl-contract-name {
	font-weight: 400;
}

.atl-contract-meta {
	color: var(--atl-absent);
	font-size: 0.85em;
	margin-left: auto;
}

.atl-contract-meta-separator {
	padding: 0 4px;
}

.atl-contract-description {
	color: var(--atl-text-soft);
	margin: 6px 0 0 0;
}

.atl-contract-empty {
	color: var(--atl-absent);
	font-style: italic;
	margin: 6px 0 0 0;
}

.atl-contract-options {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	list-style: none;
	margin: 10px 0 0 0;
	padding: 0;
}

.atl-contract-option {
	align-items: baseline;
	background: var(--atl-surface);
	border: 1px solid var(--atl-line);
	border-radius: 12px;
	display: flex;
	gap: 6px;
	padding: 2px 10px;
}

.atl-contract-option.is-new {
	background: var(--atl-new-soft);
	border-color: var(--atl-new);
}

.atl-contract-option.is-changed {
	background: var(--atl-changed-soft);
	border-color: var(--atl-changed);
}

.atl-contract-option.is-absent {
	opacity: 0.55;
}

/* One property the arriving contract writes differently, marked inside an entry that is otherwise the
   same. Without this a changed entry says only that something changed and leaves the reader hunting. */
.is-changed-field {
	font-weight: 700;
	text-decoration: underline;
	text-decoration-style: dotted;
}

.atl-contract-legend {
	display: flex;
	gap: 8px;
	margin-top: 12px;
}

.atl-contract-mark {
	border: 1px solid var(--atl-line);
	border-radius: 12px;
	font-size: 0.85em;
	padding: 1px 10px;
}

.atl-contract-mark.is-new {
	background: var(--atl-new-soft);
	border-color: var(--atl-new);
}

.atl-contract-mark.is-changed {
	background: var(--atl-changed-soft);
	border-color: var(--atl-changed);
}

.atl-contract-mark.is-absent {
	color: var(--atl-absent);
}


.atl-contract-result {
	border-left: 4px solid var(--atl-line);
	border-radius: 4px;
	margin-top: 12px;
	padding: 8px 14px;
}

.atl-contract-result.is-accepted {
	background: var(--atl-new-soft);
	border-color: var(--atl-new);
}

.atl-contract-result.is-refused {
	background: #fdecea;
	border-color: #ee3a3a;
}

.atl-contract-result-title {
	font-weight: 600;
}

.atl-contract-result-body {
	margin: 4px 0 0 0;
}

.atl-contract-errors {
	background: #fdecea;
	border-left: 4px solid #ee3a3a;
	border-radius: 4px;
	margin-top: 12px;
	padding: 8px 14px;
}

.atl-contract-errors-title {
	font-weight: 600;
}

/* The contract uploader stands in the header beside the export button, so it shows a button and nothing
   else. The control always renders a readonly box for the chosen filename, which has no attribute to
   suppress it; here the file it selected is answered by the contract that appears below, so the box
   states nothing the page does not already show and is hidden locally. */
.atl-contract-uploader {
	display: inline-flex;
}

.atl-contract-uploader .psfileuploader-input-container {
	background: none;
	border: none;
	flex: 0 0 auto;
	min-width: 0;
	padding: 0;
	width: auto;
}

.atl-contract-uploader .psfileuploader-input {
	display: none;
}


/* The contract states two things that are not the same: properties a document is described by, which are
   columns administered elsewhere, and dimensions, which are the vocabulary this page takes back. The
   first is shown plainly so nothing invites an edit that an import would ignore. */
.atl-contract-section {
	font-size: 1em;
	margin: 20px 0 0 0;
}

.atl-contract-section-note {
	color: var(--atl-absent);
	margin: 2px 0 0 0;
}

.atl-contract-dimension.is-stated {
	background: #fafafa;
	border-left-color: var(--atl-line);
}


/* Values narrowed by another answer, shown once under what they belong to: the product on the left,
   its modules beside it. Repeating the product on every chip is what made a flat list unreadable. */
.atl-contract-group {
	align-items: baseline;
	display: flex;
	gap: 10px;
	margin-top: 8px;
}

.atl-contract-group-name {
	color: var(--atl-text-soft);
	flex: 0 0 auto;
	font-weight: 600;
	min-width: 110px;
}

.atl-contract-group .atl-contract-options {
	margin-top: 0;
}

/* What a chosen description would do to the document, stated beside the uploader that took it. Saving
   can take an answer away, and this line is where a reader finds that out while it is still undone. */
.atl-metadata-summary {
	border-left: 4px solid var(--atl-line);
	border-radius: 4px;
	margin-top: 12px;
	padding: 8px 14px;
}

/* A description that will be stored, drawn as an imported contract is: the two are the same act read
   at different sizes, and one of them looking decided while the other looks undecided is only noise. */
.atl-metadata-summary.is-accepted {
	background: var(--atl-new-soft);
	border-color: var(--atl-new);
}

/* Something the document carries now will be gone. Marked apart from the ordinary case, because it is
   the one outcome a reader might want to stop before saving. */
.atl-metadata-summary.is-warning {
	background: var(--atl-changed-soft);
	border-color: var(--atl-changed);
}

.atl-metadata-summary.is-refused {
	background: #fdecea;
	border-color: #ee3a3a;
}

/* A command of the more button that submits a form is a button, and a button centres its text. The row keeps
   the start of its text where the controls put it, but a label long enough to wrap, such as the HTML5 template,
   then has its lines centred beneath each other instead of starting at the left like every other row. */
.psbuttonmore-dropdowncontent-div {
	text-align: left;
}

/* A command of the more button with others under it (atlMore.initSubmenu in Atlas.js). The portal controls
   offer one flat list, so the rows under the parent row are rows of that list: hidden until the parent row
   is clicked, and then the only ones shown, beside the back row, while the rows around them are hidden.
   The first and last visible row are no longer the first and last of the list, so the space the controls
   give them is given by the list itself instead. */
.atl-more-with-submenu .psbuttonmore-dropdowncontent {
	padding: 5px 0;
}

.atl-more-with-submenu .psbuttonmore-dropdowncontent > .psbuttonmore-dropdowncontent-div {
	margin: 0;
}

.psbuttonmore-dropdowncontent-div.atl-more-sub {
	display: none;
}

.atl-more-sub-open .psbuttonmore-dropdowncontent-div.atl-more-sub {
	display: flex;
}

.atl-more-sub-open .psbuttonmore-dropdowncontent-div:not(.atl-more-sub) {
	display: none;
}

/* The parent row says that more lies behind it, in the colour of the row, so it follows the hover of it. */
.psbuttonmore-dropdowncontent-div.atl-more-parent::after {
	content: "\203A";
	font-size: 20px;
	margin-left: auto;
	margin-right: 14px;
}
