/* GDV Client Reviews — public.css */

/* ================================================
   Review panel

   The shortcode draws a panel: a score at the head saying what every published
   review averages and how many there are, then the reviews themselves. The
   score is the credibility: a visitor reading three quotes has no way to know
   whether they are three out of four or three out of forty, and the head of
   the panel answers that before the first quote is read.

   The audience is professional, and the panel is drawn for it. The stars, the
   figure and the count appear once, in the head. A card carries the quote in
   the site's serif, and under it the person: the name, what they do and where,
   and which talk or course the review is about. No stars per card, no badge,
   no avatar, no shadow and no hover: those are the anatomy of a marketplace
   listing, and on a page of considered testimonials they read as a scoreboard.

   Colours come from gdv-public-ui's --gdv-ui-* tokens, each with its light-mode
   value as the fallback for a page where the library is absent. The tokens
   declared on the panel are the plugin's own, because gdv-public-ui publishes
   no star colour and no quote face.
   ================================================ */

.gdv-cr-panel {
	/* The filled star's edge. The brand yellow is 2.04:1 on white, which is
	   below the 3:1 a meaningful graphic needs, so the star carries a darker
	   gold outline that does the contrast work: #8a6100 is 5.54:1 on white.
	   In dark mode the yellow itself is 7.89:1 on #212121 and needs no help,
	   so the edge becomes the fill colour and disappears. */
	--gdv-cr-star:        var(--gdv-ui-primary, #e1ad4e);
	--gdv-cr-star-edge:   #8a6100;
	--gdv-cr-star-empty:  var(--gdv-ui-border-strong, #797979);

	/* The quote's face. A theme that has a heading serif sets this token on
	   the panel, and the quote then matches the page's titles; without it
	   the quote falls back to the system serif. */
	--gdv-cr-quote-font:  Georgia, "Times New Roman", serif;

	margin: 0 0 2rem;
	color: var(--gdv-ui-text, #444444);
}

@media (prefers-color-scheme: dark) {
	.gdv-cr-panel {
		--gdv-cr-star-edge:   var(--gdv-ui-primary, #e1ad4e);
	}
}

/* Panel head: below 48rem the score and the invitation are a column, each one
   the full width of the panel. A wrapping row looks like the same thing and is
   not. The two would fall onto separate lines as shrink-to-fit items, the
   invitation would be exactly as wide as its longest line (the question), and
   its own centring would then land on that box instead of on the panel, which
   is what put the two buttons left of centre on a phone. */

.gdv-cr-panel__head {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	padding-bottom: 1.25rem;
	margin-bottom: 1.5rem;
	border-bottom: 1px solid var(--gdv-ui-border, #d6d6d6);
}

/* The three lines of the head are paragraphs, and on an article the theme gives
   every paragraph in the content 1.2em of bottom margin at a weight a single
   class cannot beat. Their spacing is the flex gap above, so the margin is put
   back to zero here rather than in each rule below. */
.gdv-cr-panel .gdv-cr-panel__head p.gdv-cr-score__figure,
.gdv-cr-panel .gdv-cr-panel__head p.gdv-cr-score__count,
.gdv-cr-panel .gdv-cr-panel__head p.gdv-cr-invite {
	margin: 0;
}

/* The figure, the stars and the count on one line: a fact stated once, not a
   hero number. They wrap to two lines only where the width forces it. */
.gdv-cr-score {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.25rem 0.75rem;
}

.gdv-cr-score__figure {
	display: flex;
	align-items: baseline;
	gap: 0.375rem;
	margin: 0;
}

/* 1.5rem at 600 is large text, and 9.74:1 on white. */
.gdv-cr-score__value {
	font-size: 1.5rem;
	font-weight: 600;
	line-height: 1;
	color: var(--gdv-ui-text, #444444);
}

.gdv-cr-score__max,
.gdv-cr-score__count {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.4;
	color: var(--gdv-ui-text-faint, #666666);
}

/* The invitation: the question as a line, then the two ways on as gdv-public-ui
   buttons in its button row, which centres them and wraps them. Buttons rather
   than links in the text because on a phone and in the installed app the
   control has to look like one and give 44px to the thumb; both --secondary so
   neither outranks the reviews under them.

   The block is right-aligned only where it sits beside the score. Below that
   the head has stacked, and everything centres under the score. */

.gdv-cr-invites {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.625rem;
}

/* From 48rem up the pair sits beside the score, and there the two anchors
   shed the button and render as underlined links, one under the other, as
   the head was first designed: a button beside the score would outrank the
   reviews under it, which a link in the text does not. Same two elements;
   the width decides the dress. The selector carries four classes to beat
   the library's doubled .gdv-ui-btn and its :is() hover rule. */
@media (min-width: 48rem) {
	/* The head becomes the row it reads as: score at the left, invitation at
	   the right, wrapping if a long question needs the space. */
	.gdv-cr-panel__head {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		gap: 0.75rem 2rem;
	}

	.gdv-cr-invites {
		align-items: flex-end;
		gap: 0.25rem;
	}

	.gdv-cr-invites .gdv-cr-invites__row {
		flex-direction: column;
		align-items: flex-end;
		gap: 0.25rem;
	}

	.gdv-cr-panel .gdv-cr-invites__row .gdv-ui-btn.gdv-ui-btn,
	.gdv-cr-panel .gdv-cr-invites__row .gdv-ui-btn.gdv-ui-btn:is(:hover, :focus, :active) {
		display: inline;
		width: auto;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: 0;
		background: none;
		box-shadow: none;
		font-size: 1rem;
		font-weight: 400;
		line-height: 1.5;
		color: var(--gdv-ui-text, #444444);
		text-decoration: underline;
	}

	.gdv-cr-panel .gdv-cr-invites__row .gdv-ui-btn.gdv-ui-btn:focus-visible {
		outline: 2px solid var(--gdv-ui-focus, #8a6100);
		outline-offset: 2px;
	}
}

.gdv-cr-invite {
	margin: 0;
	font-size: 1rem;
	text-align: center;
	color: var(--gdv-ui-text, #444444);
}

/* The ring is its own token because the brand yellow is 2.04:1 on white and
   cannot serve as one. --gdv-ui-focus is 5.54:1 light and 7.89:1 dark. */
.gdv-cr-readmore:focus-visible {
	outline: 2px solid var(--gdv-ui-focus, #8a6100);
	outline-offset: 2px;
}

/* The cards. A grid rather than a flex row: every card in a row is the height
   of the tallest, so the names line up across the row whatever the length of
   the quotes above them, and a lone card does not stretch to a shape no other
   card ever takes. minmax(min(100%, 17.5rem), 1fr) is what keeps that true at
   320px, where 17.5rem alone would overflow the viewport.

   **Why these selectors name the element.** A shortcode in page content renders
   inside .nv-content-wrap, and the theme styles the lists in there by element:

     .nv-content-wrap ul      padding-left: 1em; margin: 1em 0
     .nv-content-wrap ul li   margin-top: 3px, and 1em under 767px

   Both are one class plus one element, which outranks a single class of ours.
   Left as a single class, the list took the theme's 1em left padding and the
   whole row of cards sat inset from the score above it on the left and flush on
   the right. Adding the element here lifts these two rules above the theme's
   without an !important and without naming the theme. */

.gdv-cr-panel ul.gdv-cr-list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17.5rem), 1fr));
	gap: 1.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* A plain white surface with a hairline edge. No shadow, no lift on hover:
   the card is a page, not a tile. */
.gdv-cr-panel li.gdv-cr-card {
	display: flex;
	flex-direction: column;
	margin: 0;
	/* A grid item's default minimum is its content, so one long word, URL or
	   e-mail address in a review would push the card wider than the column and
	   the page sideways with it. This pair is what holds at 320px. */
	min-width: 0;
	overflow-wrap: anywhere;
	padding: 1.5rem 1.625rem;
	color: var(--gdv-ui-text, #444444);
	background: var(--gdv-ui-surface, #ffffff);
	border: 1px solid var(--gdv-ui-border, #d6d6d6);
	border-radius: 4px;
	box-sizing: border-box;
}

/* A featured review is the one in a row of equals with a gold hairline.
   Nothing about the card's shape changes, so the row still reads as a row. */
.gdv-cr-panel li.gdv-cr-card--featured {
	border-color: var(--gdv-cr-star);
}

/* The quote itself, in the serif and a step above body size: the serif is what
   says "somebody said this", which the gold quote mark used to do.

   A <blockquote> is the right element and the theme paints one heavily: bare
   `blockquote` carries 1.3em type, 35px/45px padding, a 5% side margin and a
   giant green ::before quote mark, and Neve under it adds a 4px left border and
   max-width: 90%. Every one of those is reset here by name.

   The selector carries the element for the same reason the list above does: on
   an article the theme sets .single-gdv_article .nv-content-wrap blockquote to
   1.15em, which is one class more than a single class of ours can beat. */

.gdv-cr-panel .gdv-cr-card blockquote.gdv-cr-card__quote {
	display: block;
	position: static;
	flex: 1 1 auto;
	max-width: none;
	margin: 0 0 1.25rem;
	padding: 0;
	border: 0;
	font-family: var(--gdv-cr-quote-font);
	font-size: 1.0625rem;
	font-style: normal;
	font-weight: 400;
	line-height: 1.6;
	color: var(--gdv-ui-text, #444444);
}

.gdv-cr-panel .gdv-cr-card blockquote.gdv-cr-card__quote::before {
	content: none;
}

/* The dots and the link travel together and disappear together. An underline
   cannot be switched off on a descendant, so the dots sit outside the anchor
   rather than inside it wearing text-decoration: none. */
.gdv-cr-readmore-wrap[hidden] {
	display: none;
}

.gdv-cr-readmore {
	color: inherit;
	font-family: inherit;
	font-size: inherit;
	text-decoration: underline;
	white-space: nowrap;
}

/* Who said it, pushed to the foot of the card: the name, then what they do
   and where, then the caption line with the item reviewed and the date. */

.gdv-cr-card__by {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	margin-top: auto;
	padding-top: 1rem;
	border-top: 1px solid var(--gdv-ui-border, #d6d6d6);
}

.gdv-cr-by__name {
	font-size: 1rem;
	font-weight: 600;
	color: var(--gdv-ui-text, #444444);
}

/* 0.9375rem is 15px, above the 13px floor for secondary text still read. */
.gdv-cr-by__role {
	font-size: 0.9375rem;
	line-height: 1.4;
	color: var(--gdv-ui-text, #444444);
}

.gdv-cr-by__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.125rem 0.75rem;
	margin-top: 0.25rem;
	font-size: 0.875rem;
	line-height: 1.4;
	color: var(--gdv-ui-text-faint, #666666);
}

/* Stars, drawn once in the head. An outline star with a filled copy clipped
   over it, so a half comes out as a half rather than as a rounded whole. The
   outline is what carries the empty state: 4.35:1 on white and 3.70:1 on
   #212121, both over the 3:1 a graphic needs.

   The star itself is drawn with rounded tips and notches (icons/star.svg), and
   the dark edge below is kept to a hairline. The gap gives the five room so
   they read as a rating rather than as a block. */

.gdv-cr-stars {
	display: inline-flex;
	align-items: center;
	gap: 0.1875rem;
	font-size: 1.125rem;
	line-height: 1;
	color: var(--gdv-cr-star-empty);
}

.gdv-cr-star {
	position: relative;
	display: block;
	width: 1em;
	height: 1em;
}

.gdv-cr-star svg {
	display: block;
	width: 1em;
	height: 1em;
}

.gdv-cr-star__fill {
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	width: 100%;
	overflow: hidden;
	color: var(--gdv-cr-star);
}

/* A hairline, not a rim: its job is to give the fill an edge that carries the
   3:1 a graphic needs, since the brand yellow alone is 2.04:1 on white. Any
   heavier and the star reads as outlined rather than as gold. */
.gdv-cr-star__fill svg {
	stroke: var(--gdv-cr-star-edge);
	stroke-width: 1.25;
}

.gdv-cr-star--half .gdv-cr-star__fill {
	width: 50%;
}

@media (max-width: 480px) {
	.gdv-cr-panel li.gdv-cr-card {
		padding: 1.25rem;
	}
}

/* ================================================
   Submit form

   Same card, sizes and field anatomy as gdv-event-manager's subscription
   form. Colours come from gdv-public-ui's --gdv-ui-* tokens (site-wide, with
   dark mode), each with the light-mode value as fallback for a site where
   the library is absent. The two tint tokens below are the plugin's own,
   because gdv-public-ui publishes no light tints.
   ================================================ */

.gdv-cr-form-wrapper {
	--gdv-cr-success-light: #e8f1f1;
	--gdv-cr-danger-light:  #fceceb;

	max-width: 40rem;
	/* The shortcode is the last thing on its page, so the card carries the
	   space between itself and the footer: nothing below it would. */
	margin: 0 auto 3rem;
	padding: 1.75rem;
	font-size: 1rem;
	line-height: 1.5;
	color: var(--gdv-ui-text, #444444);
	background: var(--gdv-ui-surface, #ffffff);
	border-radius: 8px;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 4px 12px rgba(0, 0, 0, 0.06);
	box-sizing: border-box;
}

@media (prefers-color-scheme: dark) {
	.gdv-cr-form-wrapper {
		--gdv-cr-success-light: #1e3232;
		--gdv-cr-danger-light:  #3a2120;

		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.20);
	}
}

.gdv-cr-form-fieldset {
	border: 0;
	margin: 0;
	padding: 0;
	min-width: 0;
}

.gdv-cr-form-fieldset:disabled {
	opacity: 0.6;
}

/* Fields */

.gdv-cr-form__field {
	margin-bottom: 1.125rem;
}

.gdv-cr-form__field label,
.gdv-cr-form__label {
	display: block;
	font-size: 1rem;
	font-weight: 600;
	color: var(--gdv-ui-text, #444444);
	margin-bottom: 0.375rem;
}

.gdv-cr-required {
	color: var(--gdv-ui-danger, #b32d2e);
	margin-left: 2px;
}

.gdv-cr-form__field input[type="text"],
.gdv-cr-form__field input[type="email"],
.gdv-cr-form__field select,
.gdv-cr-form__field textarea {
	width: 100%;
	padding: 0.6875rem 0.875rem;
	border: 1px solid var(--gdv-ui-border-strong, #797979);
	border-radius: 4px;
	font-size: 1rem;
	font-family: inherit;
	line-height: 1.4;
	color: var(--gdv-ui-text, #444444);
	background: var(--gdv-ui-surface, #ffffff);
	box-sizing: border-box;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.gdv-cr-form__field input[type="text"]:focus,
.gdv-cr-form__field input[type="email"]:focus,
.gdv-cr-form__field select:focus,
.gdv-cr-form__field textarea:focus {
	outline: 2px solid var(--gdv-ui-focus, #8a6100);
	outline-offset: 2px;
	border-color: var(--gdv-ui-primary, #e1ad4e);
}

.gdv-cr-form__field textarea {
	resize: vertical;
	min-height: 9rem;
}

.gdv-cr-form__field select {
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='7' viewBox='0 0 12 7'%3E%3Cpath fill='%23797979' d='M6 7L0 0h12z'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.875rem center;
	padding-right: 2.25rem;
	cursor: pointer;
}

.gdv-cr-field-hint,
.gdv-cr-char-counter {
	font-size: 0.875rem;
	color: var(--gdv-ui-text-faint, #666666);
	margin: 0.375rem 0 0;
	line-height: 1.4;
}

.gdv-cr-char-counter {
	text-align: right;
}

.gdv-cr-char-counter.gdv-cr-over-limit {
	color: var(--gdv-ui-danger, #b32d2e);
	font-weight: 600;
}

/* Error line: always in the flow, collapsed while empty, so a message
   appearing does not shift the field below it more than one line. */
.gdv-cr-field-error {
	display: block;
	min-height: 1.25rem;
	font-size: 0.9375rem;
	line-height: 1.25rem;
	color: var(--gdv-ui-danger, #b32d2e);
	margin-top: 0.25rem;
}

.gdv-cr-field-error:empty {
	min-height: 0;
	margin-top: 0;
}

/* Rating widget */

.gdv-cr-rating-widget {
	display: flex;
	gap: 0.15rem;
	margin: 0.15rem 0;
}

/* Each star is a <button>, so the theme's bare button rules reach it. Every
   rule below carries the widget class to outrank them.

   The star is the same lucide SVG the list draws, so one star shape serves the
   whole plugin. 44 x 44 is the front-end activation area: at the 2rem glyph and
   no padding this control used to render 32px tall, which is under the floor on
   a phone, and five of them at 44 still fit a 320px viewport. */
.gdv-cr-rating-widget .gdv-cr-rating-star {
	display: flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: none;
	box-shadow: none;
	width: auto;
	min-width: 44px;
	min-height: 44px;
	cursor: pointer;
	font-size: 2rem;
	color: var(--gdv-ui-border-strong, #797979);
	padding: 0;
	margin: 0;
	line-height: 1;
	transition: color 0.1s;
}

.gdv-cr-rating-widget .gdv-cr-rating-star svg {
	display: block;
	width: 1em;
	height: 1em;
}

.gdv-cr-rating-widget .gdv-cr-rating-star.gdv-cr-rating-star--active {
	color: var(--gdv-ui-primary, #e1ad4e);
}

/* Hover preview, CSS only: every star up to the hovered one lights up, the
   ones after it go grey. Limited to devices with a real pointer so a touch
   does not leave a sticky preview behind. */
@media (hover: hover) {
	.gdv-cr-rating-widget:hover .gdv-cr-rating-star {
		color: var(--gdv-ui-primary, #e1ad4e);
	}

	.gdv-cr-rating-widget .gdv-cr-rating-star:hover ~ .gdv-cr-rating-star {
		color: var(--gdv-ui-border-strong, #797979);
	}
}

.gdv-cr-rating-widget .gdv-cr-rating-star:focus-visible {
	outline: 2px solid var(--gdv-ui-focus, #8a6100);
	outline-offset: 2px;
	border-radius: 2px;
}

/* Consent checkbox: inline layout, and a reset of the theme's toggle-switch
   styling so it renders as a plain checkbox. */
.gdv-cr-form .gdv-cr-checkbox-field {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 0.5rem;
}

.gdv-cr-form .gdv-cr-checkbox-field .gdv-cr-field-error {
	flex-basis: 100%;
}

/* The label shrinks and wraps beside the box instead of dropping under it. */
.gdv-cr-form .gdv-cr-checkbox-field label {
	display: block;
	flex: 1 1 0;
	min-width: 0;
	font-weight: 400;
	font-size: 1rem;
	line-height: 1.4;
	margin-bottom: 0;
	cursor: pointer;
}

.gdv-cr-form .gdv-cr-checkbox-field input[type="checkbox"] {
	appearance: checkbox;
	-webkit-appearance: checkbox;
	width: 16px;
	height: 16px;
	border-radius: 2px;
	background-color: transparent;
	position: static;
	cursor: pointer;
	transition: none;
	flex-shrink: 0;
	margin: 0.15rem 0 0;
	accent-color: var(--gdv-ui-primary, #e1ad4e);
}

.gdv-cr-form .gdv-cr-checkbox-field input[type="checkbox"]::before {
	display: none;
}

.gdv-cr-form .gdv-cr-checkbox-field label a {
	color: var(--gdv-ui-primary, #e1ad4e);
}

.gdv-cr-form .gdv-cr-checkbox-field label a:hover {
	color: var(--gdv-ui-primary-hover, #f0605c);
}

.gdv-cr-form .gdv-cr-checkbox-field input[type="checkbox"]:focus-visible {
	outline: 2px solid var(--gdv-ui-focus, #8a6100);
	outline-offset: 2px;
}

/* Submit row: the shared .gdv-ui-btn, content-width and centred, with the
   mandatory-field note under it. */
.gdv-cr-form__actions {
	margin-top: 1.5rem;
	text-align: center;
}

.gdv-cr-mandatory-label {
	display: block;
	margin-top: 6px;
	font-size: 0.875rem;
	color: var(--gdv-ui-text-faint, #666666);
}

.gdv-cr-submit-info {
	margin: 0.75rem 0 0;
	font-size: 0.875rem;
	color: var(--gdv-ui-text-faint, #666666);
	text-align: center;
	line-height: 1.4;
}

/* Form-level error and the success block that replaces the form */

.gdv-cr-form__error {
	padding: 1rem 1.25rem;
	margin-bottom: 1.5rem;
	border-radius: 4px;
	border-left: 4px solid var(--gdv-ui-danger, #b32d2e);
	background: var(--gdv-cr-danger-light);
	color: var(--gdv-ui-text, #444444);
	font-size: 1rem;
	line-height: 1.6;
}

.gdv-cr-form__error[hidden],
.gdv-cr-form__success[hidden] {
	display: none;
}

.gdv-cr-form__success {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	padding: 1.5rem 1.75rem;
	background: var(--gdv-cr-success-light);
	border-radius: 6px;
	border-left: 4px solid var(--gdv-ui-success, #427a7b);
}
