/*
 * ═════════════════════════════════════════════════════════════════════════════
 * SINGLE EVENT — the invitation and the registration form
 *
 * Loaded only on single-event.php (see fluent_commerce_ds_enqueue()), after
 * blog.css, which is where .fc-prose comes from. That order matters: this file
 * re-sets the prose column from the article's 17/1.65 reading setting to this
 * page's 18/1.55, and several of those rules meet blog.css at equal or lower
 * specificity, so they are scoped inside .fc-event__body rather than left to
 * load order.
 *
 * The layout is the Gartner report page's, and knowingly so: one section,
 * 1.35fr / 1px / 1fr, the copy left, a hairline down the middle, the form sticky
 * on the right. Two pages whose job is "read this, then fill this in" should look
 * like the same page. What differs is the form — seven controls instead of one, so
 * the two-up grid is doing real work here — and the fields themselves, which are
 * white on the bone rather than transparent, which is the export's own call and the
 * right one at seven boxes: a column of outlines with nothing in them reads as a
 * form, a column of white wells reads as one you are meant to fill.
 *
 * No JavaScript. Every state below — the marks, the error line, the confirmation —
 * is drawn by the server. See inc/ds-event.php.
 * ══════════════════════════════════════════════════════════════════════════ */

/*
 * padding-top 54 rather than --pad-section: the nav is light here and sits on the
 * same bone one hairline away, so the full 120 would read as empty page rather than
 * as air above a headline. The export's own number, and the same reduction both
 * report pages make.
 */
body.fc-ds .fc-event-page__section {
	padding-top: var(--sp-54);
	background: var(--surface-light);
}

/*
 * 1.35fr 1px 1fr: the middle track IS the hairline, so the 54 gap falls on both
 * sides of it and the rule sits at the optical centre of the gutter rather than
 * hanging off one column's edge.
 */
body.fc-ds .fc-event {
	display: grid;
	grid-template-columns: 1.35fr 1px 1fr;
	gap: var(--sp-54);
	align-items: start;
}

body.fc-ds .fc-event > * {
	min-width: 0;
}

/*
 * The hairline, as a ::before rather than the export's empty aria-hidden <div> — a
 * decorative element in the markup is one more thing a template has to explain. The
 * negative margins take it to the section's own edges: up through the 54 of padding
 * to the nav's rule, and down through --pad-section to the footer, so it reads as a
 * division of the page rather than a box around the copy. align-self overrides the
 * grid's align-items: start.
 */
body.fc-ds .fc-event::before {
	content: "";
	grid-column: 2;
	grid-row: 1;
	align-self: stretch;
	background: var(--border-on-light);
	margin-top: calc(var(--sp-54) * -1);
	margin-bottom: calc(var(--pad-section) * -1);
}

/*
 * Both columns are placed explicitly, so the ::before cannot take column 1 from the
 * copy by being first in source order.
 */
body.fc-ds .fc-event__copy {
	grid-column: 1;
	grid-row: 1;
	display: flex;
	flex-direction: column;
	gap: var(--sp-32);
	max-width: 720px;
}

/*
 * 120 of clearance, which is the nav's height plus its air — the form must never
 * stick to a position the bar is already occupying.
 */
body.fc-ds .fc-event__form {
	grid-column: 3;
	grid-row: 1;
	position: sticky;
	top: var(--sp-120);
}

/*
 * 1100 and not 820: the form is a two-up field grid, so it stops being usable beside
 * 720px of copy well before the copy stops being readable. Below this the page is the
 * invitation, then the form — which is the order it is read in anyway.
 */
@container page (max-width: 1100px) {
	body.fc-ds .fc-event {
		grid-template-columns: 1fr;
	}

	body.fc-ds .fc-event::before {
		display: none;
	}

	body.fc-ds .fc-event__copy,
	body.fc-ds .fc-event__form {
		grid-column: 1;
		grid-row: auto;
	}

	body.fc-ds .fc-event__form {
		position: static;
	}
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE INVITATION
 * ────────────────────────────────────────────────────────────────────────── */

/*
 * The key graphic, in the export's 675:575 box. A ratio box and `contain` rather than
 * width plus height:auto, which is what the Gartner cover uses: that file is a fixed
 * theme asset at one known size, and this is a featured image an editor uploads, so
 * the ratio has to be reserved before anything is known about the file. `contain`
 * because event artwork has its own margins and cropping it to fill would cut a
 * composition somebody made.
 *
 * align-self keeps it at its own width in a flex column that otherwise stretches.
 */
body.fc-ds .fc-event__art {
	align-self: flex-start;
	width: 100%;
	max-width: 420px;
	aspect-ratio: 675 / 575;
}

body.fc-ds .fc-event__art-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
	/* Left, not centred: the graphic aligns with the headline under it, and `contain`
	   on a file that is not 675:575 would otherwise float it in the middle of a box
	   nothing else on the page can see. */
	object-position: left center;
}

body.fc-ds .fc-event__head {
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
}

/*
 * Not .fc-eyebrow — the same 16px slot, but sentence case, semibold and untracked.
 * See the note on the Gartner page's kicker: violet type is always surface-dependent,
 * and on bone it takes the brand violet itself.
 */
body.fc-ds .fc-event__kicker {
	margin: 0;
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: var(--type-eyebrow-16);
	line-height: 1.45;
	letter-spacing: normal;
	color: var(--fc-violet);
}

/* .fc-display-section already carries the face, the ramp, the flush 1 and the
   -0.01em tracking, which is the export's headline exactly. */
body.fc-ds .fc-event__title {
	margin: 0;
	color: var(--text-on-light);
}

/*
 * The date line. 1.25 rather than a line-height token because this is one line of
 * 24px type and not a paragraph — the tokens exist for copy that wraps.
 */
body.fc-ds .fc-event__when {
	margin: 0;
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: var(--type-h5-24);
	line-height: 1.25;
	color: var(--text-on-light);
}

/*
 * The body, written in the block editor. blog.css sets .fc-prose to the article
 * column's 17/1.65 at 80% ink; this page is the primary body size at 1.55, which is
 * the export's own rounding of --lh-loose. --sp-flow is already 32 on .fc-prose and
 * is restated here so the flow gap matches .fc-event__copy's own gap explicitly
 * rather than by coincidence.
 */
body.fc-ds .fc-event__body {
	font-size: var(--type-body-18);
	font-weight: var(--fw-medium);
	line-height: 1.55;
	color: var(--text-on-light-muted);
	--sp-flow: var(--sp-32);
}

/*
 * The opening and closing lines: full ink at semibold, against the 500 of the
 * argument between them. Both are classNames on ordinary paragraphs, so an editor
 * adds or drops them per event and the page is correct either way — see the note in
 * single-event.php.
 */
body.fc-ds .fc-event__body .fc-event__lead,
body.fc-ds .fc-event__body .fc-event__close {
	font-weight: var(--fw-semibold);
	color: var(--text-on-light);
}

/*
 * The ticked list. Scoped inside .fc-event__body on purpose: blog.css's
 * `.fc-prose ul` and `.fc-prose li + li` carry one more element in their selectors
 * than a bare class does, so an unscoped rule here would lose to them on specificity
 * rather than winning on load order. The extra class settles it outright.
 *
 * The tick is a mask on ::before and not an <svg>, because an svg inside a core
 * <li> is invalid block content. currentColor is what makes one asset serve ink on
 * bone here and bone on ink elsewhere.
 */
body.fc-ds .fc-event__body .fc-event__ticks {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--sp-16);
}

body.fc-ds .fc-event__body .fc-event__ticks li {
	display: flex;
	align-items: baseline;
	gap: var(--sp-16);
	font-weight: var(--fw-medium);
	line-height: var(--lh-body);
	color: var(--text-on-light);
}

/* The gap above does the spacing; blog.css's 12px would stack on top of it. */
body.fc-ds .fc-event__body .fc-event__ticks li + li {
	margin-top: 0;
}

body.fc-ds .fc-event__body .fc-event__ticks li::before {
	content: "";
	flex: none;
	width: 14px;
	height: 14px;
	/* An empty inline box baselines on its bottom edge, exactly as the export's inline
	   <svg> does; the 2px is the export's own optical nudge. */
	position: relative;
	top: 2px;
	background-color: currentColor;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'%3E%3Cpath d='M1 7.5 L5 11.5 L13 2.5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 14px 14px no-repeat;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE FORM
 * Seven controls at .fc-btn's own 48/10px geometry, white on the bone. The button
 * is a real .fc-btn, so every field has to be the same height as one.
 * ────────────────────────────────────────────────────────────────────────── */

/* .fc-eyebrow carries the face; this only places it. It renders in BOTH states — the
   confirmation appears under the same words the visitor was answering. */
body.fc-ds .fc-eventform__heading {
	margin: 0 0 var(--sp-32);
	color: var(--text-on-light);
}

body.fc-ds .fc-eventform__form {
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
}

body.fc-ds .fc-eventform__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--sp-24);
}

/* Two-up until the column itself is phone-width. The page has already stacked at
   1100, so this is the second stage, not the first. */
@container page (max-width: 820px) {
	body.fc-ds .fc-eventform__grid {
		grid-template-columns: 1fr;
	}
}

/* A <p> per field, so the hidden <label> and its control are one grid cell. */
body.fc-ds .fc-eventform__field {
	margin: 0;
	display: flex;
	min-width: 0;
}

body.fc-ds .fc-eventform__field--wide {
	grid-column: 1 / -1;
}

body.fc-ds .fc-eventform__input {
	width: 100%;
	min-width: 0;
	height: 48px;
	padding: 0 16px;
	background: var(--fc-white);
	/*
	 * Full ink, not --border-on-light. The Gartner form's single field is a 20% edge
	 * because it sits alone under a headline; seven of those on a warm bone read as a
	 * faint grid rather than as controls, and the export draws them at full strength.
	 */
	border: var(--stroke-1) solid var(--fc-ink-12);
	border-radius: var(--radius-10);
	font-family: var(--font-core);
	/* The form size — flat 16, and the reason is on the token. See layout.css. */
	font-size: var(--fc-field-size);
	font-weight: var(--fw-medium);
	color: var(--text-on-light);
}

body.fc-ds .fc-eventform__input::placeholder {
	color: var(--fc-ink-a40);
}

/*
 * :focus and not :focus-visible, which is the export's own choice and the right one
 * for a text field: a click into an input is a request to type, so it should show
 * where the caret went. Outline outside the border, both violet — the edge reads as
 * one 2px line rather than two rings.
 */
body.fc-ds .fc-eventform__input:focus {
	outline: var(--stroke-1) solid var(--fc-violet);
	border-color: var(--fc-violet);
}

/*
 * data-invalid, not :invalid — the server decides what is wrong and says so once, on
 * submit. Seven required fields are all :invalid from the moment the page loads, so
 * styling the error off that would draw the whole form in red before anyone had done
 * anything.
 */
body.fc-ds .fc-eventform__input[data-invalid="true"] {
	border-color: var(--fc-red);
}

/*
 * The country select. appearance:none is the export's, and the chevron is ours: the
 * export removes the browser's own indicator and draws nothing in its place, which
 * leaves a control that looks exactly like a text box and does not respond to typing.
 * That is a mock omission rather than a decision, so the arrow is drawn back — as a
 * mask in currentColor, so it follows the placeholder state below.
 *
 * padding-right clears it. 44 = 16 of edge, 12 of arrow, 16 of gap.
 */
body.fc-ds .fc-eventform__select {
	appearance: none;
	padding-right: 44px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 L6 6.5 L11 1.5' fill='none' stroke='%23121212' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 12px 8px;
}

/*
 * The unchosen state, which the export gets from a bound colour. An attribute the
 * server sets rather than :invalid or :has, because both of those would either need
 * the empty option disabled — removing the visitor's ability to unset it — or would
 * grey the control before they had done anything wrong. See inc/ds-event.php.
 */
body.fc-ds .fc-eventform__select[data-empty="true"] {
	color: var(--fc-ink-a40);
}

/* The list itself is never greyed, only the closed control's own line. */
body.fc-ds .fc-eventform__select option {
	color: var(--text-on-light);
}

/*
 * The dinner question. display:block and a margin rather than flex and a gap: a
 * <legend> is taken out of a flex fieldset's flow by the browser and lands on the
 * border edge, so gap would never reach it. min-width:0 because a fieldset defaults
 * to min-content and would refuse to narrow inside the grid.
 */
body.fc-ds .fc-eventform__ask {
	grid-column: 1 / -1;
	display: block;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
}

/*
 * The question. Set exactly as the fields it sits over — same size, same weight —
 * and not as the export's own line, which was semibold at --type-body-18 and
 * resolves to 20px here, so the question read as a heading over the controls it
 * belongs to. Nothing needs to set it apart: it is the only line in the row, and it
 * ends in a question mark. Its own position is what says it is a label.
 */
body.fc-ds .fc-eventform__ask-label {
	display: block;
	padding: 0;
	margin-bottom: 12px;
	font-family: var(--font-core);
	font-weight: var(--fw-medium);
	font-size: var(--fc-field-size);
	line-height: var(--lh-body);
	color: var(--text-on-light);
}

body.fc-ds .fc-eventform__ask-options {
	display: flex;
	align-items: center;
	gap: var(--sp-32);
}

body.fc-ds .fc-eventform__radio {
	display: flex;
	align-items: center;
	/* 10px is the export's, and it is tighter than the checkbox's 12 on purpose: a
	   radio label is one word, not a sentence. */
	gap: 10px;
	cursor: pointer;
	font-family: var(--font-core);
	font-weight: var(--fw-medium);
	/* Yes and No are answers, so they take the field size the same way the question
	   above them does — a radio's label is the control's own text. */
	font-size: var(--fc-field-size);
	color: var(--text-on-light);
}

body.fc-ds .fc-eventform__radio input {
	flex: none;
	width: 18px;
	height: 18px;
	accent-color: var(--fc-violet);
}

/*
 * The consent statement was styled here at 18px. It is now .fc-consent in layout.css at
 * the contact page's 14 — deliberately smaller than this form's fields, because three
 * lines of legal copy set at body size competes with the fields above it. The light
 * surface is the shared block's default, so this form passes no variant.
 * See inc/ds-consent.php.
 */
body.fc-ds .fc-eventform__error {
	display: flex;
	align-items: center;
	gap: var(--sp-8);
	margin: 0;
	font-family: var(--font-core);
	font-weight: var(--fw-medium);
	font-size: var(--type-label-12);
	letter-spacing: var(--ls-eyebrow);
	text-transform: uppercase;
	color: var(--fc-red);
}

/*
 * The alert region is in the DOM at all times and carries `hidden` when there is
 * nothing to say, so this is not optional: the browser's own [hidden] rule is a
 * single attribute selector and loses to the class above it, which would leave a red
 * "[ ! ]" under the form on every idle page load.
 */
body.fc-ds .fc-eventform__error[hidden] {
	display: none;
}

/* The mono face exists for exactly this: a machine's own punctuation. */
body.fc-ds .fc-eventform__mark {
	font-family: var(--font-mono);
	font-variant-ligatures: none;
}

/* .fc-btn--dark already supplies the geometry and the colourway. This only strips
   what a UA gives a real <button> and a <div> never had. */
body.fc-ds .fc-eventform__submit {
	appearance: none;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE CONFIRMATION
 * A bordered panel where the form was, at the same width — so the column does not
 * change shape between the two states and the page never jumps.
 * ────────────────────────────────────────────────────────────────────────── */
body.fc-ds .fc-eventform__done {
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
	padding: var(--sp-32);
	border: var(--stroke-1) solid var(--border-on-light);
}

/* Green, and the only green on the page. It is the eyebrow role in another colour,
   which is why it is bold and tracked rather than semibold like the kicker. */
body.fc-ds .fc-eventform__done-title {
	display: flex;
	align-items: center;
	gap: var(--sp-8);
	margin: 0;
	font-family: var(--font-core);
	font-weight: var(--fw-bold);
	font-size: var(--type-eyebrow-16);
	letter-spacing: var(--ls-eyebrow);
	text-transform: uppercase;
	color: var(--fc-green);
}

/* --lh-body, not --lh-loose: two lines of confirmation, not a paragraph of copy. */
body.fc-ds .fc-eventform__done-body {
	margin: 0;
	font-family: var(--font-core);
	font-weight: var(--fw-medium);
	font-size: var(--type-body-18);
	line-height: var(--lh-body);
	color: var(--text-on-light-muted);
}

/* The reference is a machine string, so it is set as one. It is also the one string
   on the page somebody may be asked to read back at a door. */
body.fc-ds .fc-eventform__ref {
	margin: 0;
	font-family: var(--font-mono);
	font-variant-ligatures: none;
	font-size: 16px;
	color: var(--text-on-light);
}

/* ─────────────────────────────────────────────────────────────────────────────
 * WHEN THE FORM IS PARDOT'S — SINCE 2026-08-26
 *
 * An event whose "Pardot form URL" box is filled in draws an iframe here instead of the
 * form above. Everything above still applies to every event that has not been switched,
 * which is all of them by default — see the section head in inc/ds-event.php.
 *
 * ── WHY A FLOOR AND NOT A HEIGHT ────────────────────────────────────────────
 *
 * The iframe carries a height attribute AND an inline height from PHP, and
 * assets/ds/pardot-frame.js overwrites the inline one with what the frame measures of
 * itself. So this is neither of those: it is the number below which the frame may not
 * shrink, which matters because the correction can arrive with a number measured before
 * the frame's webfont loaded. Too tall costs whitespace in a column that has nothing
 * under it; too short puts a scrollbar inside a form.
 *
 * 880 is the same figure fluent_commerce_ds_event_frame_height() opens at, and the two
 * are meant to agree — if one moves, move the other. It is the form's own tallest
 * measured height (875, at the 350–362px column widths a phone and a 1200px desktop
 * both produce), not a guess: the 640 this shipped with was one, and it cut the
 * Register button off until the resize message arrived.
 *
 * The styling INSIDE the frame is not here and cannot be: that document is served by
 * go.fluentcommerce.com. It is assets/ds/pardot-form-event.css, which is pasted into
 * Pardot by hand and is enqueued by nothing.
 * ────────────────────────────────────────────────────────────────────────── */

body.fc-ds .fc-eventform__frame {
	min-height: 880px;
}
