/*
 * Course & Schedule Connector for iSport
 *
 * Deliberately small. The plugin owns the shape of a listing — what is a row,
 * what is a heading, what folds where — and leaves the look to the theme: no
 * fonts, no brand colours, no spacing scale. Everything colourish is a custom
 * property with a quiet default, so a theme overrides one line rather than
 * fighting a stylesheet.
 *
 * The rule that folds the table onto one column below the chosen width is not
 * here. It depends on a setting, and a media query takes a number rather than a
 * custom property, so it is printed alongside this file.
 */

.cscs {
	--cscs-border: #e0e0e0;
	--cscs-muted: #666;
	--cscs-accent: currentColor;
}

/*
 * Said to a screen reader and shown to nobody. Not `display:none`, which is not
 * said either.
 */
.cscs-visually-hidden,
.cscs-status {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * Where the keyboard is. The theme usually draws this and usually draws it
 * well, but a link inside a table whose colours somebody has designed can end
 * up with an outline the same colour as what is behind it — so the plugin draws
 * its own in the colour of the text, which is legible against whatever that
 * text is legible against by definition.
 */
.cscs :focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

/*
 * A timetable of eight columns is wider than a narrow content column, and a
 * table that overflows its page is a table whose last column nobody can read.
 * It scrolls sideways inside this instead — with a tab stop of its own, because
 * a region somebody has to scroll is a region somebody has to be able to reach
 * without a mouse.
 */
.cscs-table-scroll {
	overflow-x: auto;
	max-width: 100%;
}

.cscs-table {
	width: 100%;
	border-collapse: collapse;
}

.cscs-table th,
.cscs-table td {
	padding: 0.5rem 0.75rem;
	text-align: left;
	vertical-align: top;
	border-bottom: 1px solid var(--cscs-border);
}

.cscs-table th {
	font-weight: 600;
}

.cscs-col-price,
.cscs-col-places,
.cscs-col-lessons,
.cscs-col-day,
.cscs-col-hours {
	white-space: nowrap;
}

/* A cancelled class is still information: it says do not come on Tuesday. */
.cscs-row--cancelled {
	opacity: 0.65;
}

.cscs-row--cancelled .cscs-col-name,
.cscs-row--cancelled .cscs-col-course,
.cscs-row--cancelled .cscs-col-activity,
.cscs-row--cancelled .cscs-col-time,
.cscs-row--cancelled .cscs-col-date {
	text-decoration: line-through;
}

.cscs-cancelled {
	font-weight: 600;
	text-transform: uppercase;
	font-size: 0.85em;
	letter-spacing: 0.03em;
}

.cscs-row--full .cscs-col-places {
	color: var(--cscs-muted);
}

.cscs-row--few .cscs-col-places {
	font-weight: 600;
}

.cscs-button {
	display: inline-block;
	white-space: nowrap;
}

/*
 * The same way in, as a link in the text rather than a button. Deliberately
 * almost nothing: a link should look like the theme's links, and a theme that
 * has an opinion about `a` already has one about this.
 */
.cscs-signup-link {
	display: inline;
}

.cscs-empty,
.cscs-notice {
	color: var(--cscs-muted);
}

/*
 * The area a table piloting the column-children mechanism builds its columns
 * from, in the block editor's own canvas. Never seen on the page itself: a
 * column child renders nothing there, so nothing here reaches the front end
 * either.
 */
.cscs-columns-editor {
	margin-bottom: 1em;
}

@media (prefers-color-scheme: dark) {
	.cscs {
		--cscs-border: #3a3a3a;
		--cscs-muted: #a0a0a0;
	}
}

/* A course's own page. The plugin owns the shape; the theme owns the look. */

.cscs-course__facts th {
	width: 40%;
	text-align: left;
	font-weight: 600;
}

.cscs-course__image img {
	max-width: 100%;
	height: auto;
}

.cscs-course__booking {
	margin: 1rem 0;
}

.cscs-course__contact-list {
	list-style: none;
	margin: 0.25rem 0;
	padding: 0;
}

.cscs-course__contact-note {
	color: var(--cscs-muted);
}

.cscs-course__schedule,
.cscs-course__makeup {
	margin-top: 2rem;
}

/* A make-up class is an exception to the timetable, and reads as one. */
.cscs-course__makeup .cscs-table {
	border-left: 3px solid var(--cscs-border);
}

/* Controls above and below a listing. Links first, script second. */

.cscs-controls {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	align-items: center;
	margin-bottom: 1rem;
}

.cscs-weeks,
.cscs-rooms,
.cscs-pager {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	align-items: center;
}

.cscs-weeks__current {
	font-weight: 600;
}

.cscs-rooms__label {
	font-weight: 600;
}

.cscs-rooms__select {
	max-width: 100%;
}

/*
 * The button beside the room list is there for a visitor whose browser never
 * ran the script. Once the script has run, choosing a room is enough, and a
 * button that does what already happened is only a thing to wonder about.
 */
.cscs-js .cscs-rooms__go {
	display: none;
}

.cscs-pager {
	margin-top: 1rem;
}

/* While a listing is being fetched it is still readable, only quieter. */
.cscs[aria-busy="true"] {
	opacity: 0.6;
	transition: opacity 0.15s ease-in-out;
}

/*
 * A trainer's page.
 *
 * Deliberately thin. The page is built from the theme's own typography, and
 * everything here is either a thing no theme has an opinion about — the shape
 * of a photograph, the spacing between two lists — or a thing the blocks below
 * will override anyway. A plugin that styled a person's page in full would be
 * making a design decision that belongs to whoever owns the design.
 */
.cscs-trainer__photo {
	/*
	 * A portrait at its full width is a wall, not a photograph of a person.
	 * This is the plugin's own page, which exists so that a trainer has one
	 * before anybody has designed one; the blocks below override it entirely.
	 */
	max-width: 20rem;
	margin: 0 0 1rem;
}

.cscs-trainer__photo-image {
	max-width: 100%;
	height: auto;
}

.cscs-trainer__motto {
	font-style: italic;
	margin: 0 0 1rem;
}

.cscs-trainer > section {
	margin-top: 1.5rem;
}

.cscs-list {
	margin: 0;
	padding-left: 1.25rem;
}

.cscs-list > li + li {
	margin-top: 0.25rem;
}

/*
 * Day and time are printed one term to a line so that the two columns can be
 * read across. Without this the browser would join them back into a sentence
 * and undo the whole point of separating them.
 */
.cscs-course__facts td {
	white-space: normal;
}

/*
 * The field blocks and modules.
 *
 * A heading and a value, and almost nothing else. Everything a designer would
 * want to change is set in the editor and arrives as an inline style, so what
 * is left here is the shape: how the two sit relative to each other, and what a
 * list looks like before anybody has an opinion about it.
 */
.cscs-field {
	--cscs-field-gap: 0.25rem;
}

.cscs-field--stack .cscs-field__label {
	margin: 0 0 var(--cscs-field-gap);
}

.cscs-field--stack .cscs-field__value {
	margin: 0;
}

.cscs-field--inline {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--cscs-field-gap);
}

.cscs-field--inline .cscs-field__label,
.cscs-field--inline .cscs-field__value {
	margin: 0;
}

/*
 * A field inside Divi. Divi's Layout group writes its CSS at this element —
 * `.cscs_divi_field_course_price_0 .cscs-field`, read off the stylesheet the
 * page emits — because the module's only child is this element, and a flex
 * container arranges what is inside it.
 *
 * What it writes is not quite a whole rule, and these three declarations are
 * what make up the difference.
 *
 * It never writes `display` — not for flex and not for grid, where it writes
 * `grid-template-columns` and leaves it at that. Divi says the display mode in
 * a class on the module instead: `et_flex_module`, or `et_grid_module` when the
 * panel says grid. The rules below are the only place those two are turned into
 * a display, one element further down, on the element the rest of the group is
 * written at.
 *
 * It writes a gap as `--horizontal-gap` and `--vertical-gap`, which Divi's own
 * flex classes read. This element is not one of them, so it reads them itself.
 * They are re-declared here first because both inherit from the module wrapper,
 * where they are the gutter between modules — without that, a field nobody has
 * set a gap on would take the gutter.
 *
 * And it writes at two classes' worth of specificity, so everything here is
 * wrapped in `:where()` and weighs nothing. Whatever the panel says wins, in
 * either order the two stylesheets happen to arrive.
 */
.cscs_divi_field :where(.cscs-field) {
	--horizontal-gap: var(--cscs-field-gap);
	--vertical-gap: var(--cscs-field-gap);

	display: flex;
	flex-direction: var(--flex-direction, column);
	column-gap: var(--horizontal-gap);
	row-gap: var(--vertical-gap);
}

.cscs_divi_field:where(.et_grid_module) :where(.cscs-field) {
	display: grid;
}

/*
 * What a page saved before the Layout group existed still asks for: the same
 * picture it had, overridden the moment the panel says otherwise.
 */
.cscs_divi_field :where(.cscs-field--inline) {
	--flex-direction: row;

	flex-wrap: wrap;
	align-items: baseline;
}

/*
 * Two opinions about the space between a heading and a value, one of them in a
 * panel and one of them not, is what makes a gap setting look broken. Under
 * Divi the gap is the panel's, so the arrangement above keeps its margins to
 * itself.
 *
 * This one is not wrapped in `:where()`, and the two classes are the point.
 * Divi writes the heading's own spacing at `.cscs_divi_field_course_price_0
 * .cscs-field__label` — two classes, exactly what the arrangement above weighs
 * — so anything lighter would lose to it and the margin would come back. Two
 * classes here ties with both and is settled by order: later than the
 * arrangement in this file, earlier than Divi's, which the page prints
 * seventeen stylesheets further down.
 */
.cscs_divi_field .cscs-field__label,
.cscs_divi_field .cscs-field__value {
	margin: 0;
}

.cscs-field__list {
	margin: 0;
	padding-left: 1.25rem;
}

.cscs-field__list > li + li {
	margin-top: 0.25rem;
}

.cscs-field__list[style*="list-style-type:none"] {
	padding-left: 0;
}

.cscs-field__contact-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.cscs-field__empty {
	opacity: 0.7;
}

/*
 * Animation.
 *
 * Nothing is hidden by the markup. The armed class is added by the script, so
 * an element is only ever invisible once something is certainly going to bring
 * it back — a page whose JavaScript failed shows everything, as it should.
 */
.cscs-animate--armed {
	opacity: 0;
	will-change: opacity, transform;
}

.cscs-animate--armed[data-cscs-animation="slide-up"] {
	transform: translateY(1.5rem);
}

.cscs-animate--armed[data-cscs-animation="slide-down"] {
	transform: translateY(-1.5rem);
}

.cscs-animate--armed[data-cscs-animation="slide-left"] {
	transform: translateX(-1.5rem);
}

.cscs-animate--armed[data-cscs-animation="slide-right"] {
	transform: translateX(1.5rem);
}

.cscs-animate--armed[data-cscs-animation="zoom"] {
	transform: scale(0.94);
}

.cscs-animate--in {
	opacity: 1;
	transform: none;
	transition:
		opacity var(--cscs-animation-duration, 600ms) ease-out var(--cscs-animation-delay, 0ms),
		transform var(--cscs-animation-duration, 600ms) ease-out var(--cscs-animation-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
	.cscs-animate--armed,
	.cscs-animate--in {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/*
 * A picture field.
 *
 * The image fills the box it is given and no more. Everything else about it —
 * its width, its border, its corners, its shadow — is set in the editor, on the
 * picture rather than on the box around it, which is where a designer looks
 * for it and where Divi's own image module puts it.
 */
.cscs-field__image {
	display: block;
	max-width: 100%;
	height: auto;
}

.cscs-field__image-link {
	display: inline-block;
	max-width: 100%;
}

/*
 * A grid of trainer cards.
 *
 * The photograph fills its box and the name sits under it, both linked to
 * the trainer's own page. Row or column and the gap are Gutenberg's own
 * settings — see `FieldRenderer::card_rules()` — and under Divi they are
 * this shape's fallback, overridden by Divi's own Layout group below the
 * moment it says otherwise. The photograph's ratio and its margin work the
 * same way, one field's worth of margin aside — Divi's own Spacing group
 * on the photograph replaces it there, and Gutenberg keeps the setting.
 */
.cscs-cards {
	display: flex;
	flex-direction: column;
	flex-wrap: wrap;
	gap: 1.5rem;
}

.cscs-cards--row {
	flex-direction: row;
}

.cscs-card {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.cscs-card--row {
	flex-direction: row;
}

.cscs-card__image {
	display: block;
	max-width: 100%;
	height: auto;
}

.cscs-card__image-link {
	display: inline-block;
	max-width: 100%;
}

.cscs-card__name {
	font-weight: 600;
}

/*
 * Unlike `.cscs-field` above, a grid of cards and one card inside it need
 * nothing Divi-specific here. Both are asked through a plain select now —
 * {@see `designCardsLayout` and `designCardLayout` in
 * `tools/build-divi-modules.php`} — because Divi's own Layout group answers
 * for the module as a whole and no other attribute reaches it: read off
 * Divi's own module-classname source (`Module.php`,
 * `_get_layout_module_classname`), a second or third copy of that group
 * elsewhere on the same module is read, generates nothing, and styles
 * nothing. So the choice arrives the same way it always has for Gutenberg —
 * as the `cscs-cards--row` and `cscs-card--row` classes above, written by
 * `FieldRenderer::card_rules()` — and this stylesheet needs no separate,
 * higher-specificity copy of those rules to make Divi agree with itself.
 */
