/*
Theme Name: The Security Grind
Theme URI: https://thesecuritygrind.com
Description: Child theme of Twenty Twenty-Five for The Security Grind — an open-table IT security meetup at coffee shops. The "Organic" system: Caprasimo and Figtree, cream and terracotta with a sage second voice, soft radii and pill buttons.
Author: Craig Carrigan
Template: twentytwentyfive
Version: 0.17.0
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: securitygrind
Tags: blog, one-column, custom-colors, custom-menu, block-patterns, full-site-editing
*/

/* -------------------------------------------------------------------------
   Tokens theme.json cannot express, plus the components the approved design
   needs that have no core-block equivalent: the two-band header, the round
   date bubbles, the washed photo treatment.
   ---------------------------------------------------------------------- */

:root {
	--sg-radius-sm: 8px;
	--sg-radius-md: 16px;
	--sg-radius-lg: 28px;
	--sg-pill: 999px;
	--sg-shadow-sm: 0 1px 2px color-mix(in srgb, #2e2b25 14%, transparent);
	--sg-shadow-md: 0 3px 10px color-mix(in srgb, #2e2b25 16%, transparent);
	--sg-shadow-lg: 0 12px 32px color-mix(in srgb, #2e2b25 22%, transparent);
	--sg-divider: color-mix(in srgb, #201e1d 16%, transparent);
	--sg-navbox-h: 82px;
}

/* Caprasimo is a heavy display face with a large x-height; it needs negative
   tracking and tight leading so the big sizes do not read as bloated. */
h1, h2, h3,
.wp-block-post-title {
	letter-spacing: -0.02em;
}

/* Focus rings are terracotta everywhere — never browser-default blue. */
:where(a, button, input, textarea, select, summary, .wp-block-button__link):focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta);
	outline-offset: 2px;
}

/* -------------------------------------------------------------------------
   Header band 1 — announcement strip
   ---------------------------------------------------------------------- */
.sg-announce {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--base);
	font-size: 0.8125rem;
}

.sg-announce .sg-announce__label {
	color: var(--wp--preset--color--terracotta);
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	font-size: 0.75rem;
}

.sg-announce a {
	color: var(--wp--preset--color--base);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	font-size: 0.75rem;
	text-decoration: none;
	border-bottom: 2px solid var(--wp--preset--color--terracotta);
	padding-bottom: 1px;
}

.sg-announce a:hover {
	color: var(--wp--preset--color--terracotta);
}

/* -------------------------------------------------------------------------
   Header band 2 — brand band: nav | logo | nav
   The two nav groups sit in a fixed-height box ruled top and bottom, so the
   hairlines run out to both edges and line up across the logo.
   ---------------------------------------------------------------------- */
.sg-brand-band > .wp-block-group {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: 0;
}

/* Same flow-layout margin problem one level up: the three grid items (nav,
   logo, nav) each get a margin-block-start after the first, which offsets the
   two nav boxes from each other vertically. */
.sg-brand-band > .wp-block-group > * {
	margin-block-start: 0 !important;
	margin-block-end: 0 !important;
}

/* Pull each nav group toward the logo rather than centring it in its half.
   The hairline rules still span the full column, so the lines either side of
   the logo are unchanged. */
/* Shorten each ruled bar from its OUTER edge so the bar itself sits closer to
   the logo, while the links stay centred within the bar. Shifting the links
   inside a full-width bar would move them nearer the logo but leave them
   visibly off-centre against their own rules. */
.sg-brand-band > .wp-block-group > .sg-nav-col {
	position: relative;
	margin-left: 5rem;
}

/* The standing-invitation pill hangs below the left nav bar, centred on it.
   Absolute so it sits in the whitespace beside the tall logo instead of
   growing the left grid cell — which would push that nav bar up and break
   its alignment with the one on the right. */
.sg-pill--header {
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-top: 1.1rem;
	white-space: nowrap;
}

.sg-brand-band > .wp-block-group > .sg-navbox:last-child {
	justify-content: center;
	margin-right: 5rem;
}

/* The hero band is the next sibling after the header and picks up the global
   block gap, adding ~27px above the fold for no reason. */
.sg-brand-band + * {
	margin-block-start: 0 !important;
}

.sg-navbox {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 2.2rem;
	min-height: var(--sg-navbox-h);
	border-top: 1px solid var(--sg-divider);
	border-bottom: 1px solid var(--sg-divider);
}

/* The links are separate paragraph blocks, and WordPress's flow layout gives
   every sibling after the first a margin-block-start. Inside a flex row that
   drops each one below the first, staggering the nav and knocking the two
   hairline rules out of alignment with each other. */
.sg-navbox > * {
	margin-block-start: 0 !important;
	margin-block-end: 0 !important;
}

.sg-navbox a {
	font-family: var(--wp--preset--font-family--body);
	font-weight: 700;
	font-size: 13px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	white-space: nowrap;
	text-decoration: none;
	color: var(--wp--preset--color--ink);
	border-bottom: 2px solid transparent;
	padding-bottom: 3px;
}

.sg-navbox a:hover,
.sg-navbox a[aria-current="page"],
.sg-navbox .current-menu-item > a {
	border-bottom-color: var(--wp--preset--color--terracotta);
}

/* The logo column: mark above wordmark, 16px apart. */
.sg-brandmark {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	padding: 0 1rem;
}

.sg-brandmark img {
	display: block;
	height: auto;
}

.sg-brandmark .sg-brandmark__mark img { width: auto; height: 104px; }
.sg-brandmark .sg-brandmark__word img { width: 212px; }

@media (max-width: 900px) {
	.sg-brand-band > .wp-block-group {
		grid-template-columns: 1fr;
		justify-items: center;
	}

	.sg-navbox {
		min-height: 0;
		padding: 1.1rem 0;
		flex-wrap: wrap;
		gap: 1.4rem;
	}

	/* On one column the rules would stack into a double line between groups. */
	.sg-brand-band .sg-navbox + .sg-brandmark { padding-top: 1.6rem; }
	.sg-brand-band .sg-navbox:first-child { border-top: 0; }
}

/* -------------------------------------------------------------------------
   Cards and containers — 28px, soft, no sharp corners anywhere
   ---------------------------------------------------------------------- */
.sg-card {
	border: 1px solid var(--sg-divider);
	border-radius: var(--sg-radius-lg);
	background-color: var(--wp--preset--color--base);
	transition: transform 140ms ease, box-shadow 140ms ease;
}

.sg-card:hover {
	transform: translateY(-2px);
	box-shadow: var(--sg-shadow-md);
}

/* Stretch to equal height only when the card is the sole occupant of its
   column (the three-across rows). The FAQ grid puts two cards in a column,
   where height:100% each would total 200% and overflow the section. */
.wp-block-column > .sg-card:only-child {
	display: flex;
	flex-direction: column;
	height: 100%;
}

/* Constrained layout puts `margin-inline: auto` on every child. Inside a flex
   card that centres each child as a flex item, which is wrong.

   `!important` is deliberate and load-bearing: Twenty Twenty-Five declares
   that layout rule with `!important` itself, so a plain reset loses to it no
   matter how specific this selector is. */
.wp-block-column > .sg-card:only-child > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
	max-width: none !important;
}

/* -------------------------------------------------------------------------
   Meetup rows — round date bubble, title, café, going count, CTA
   ---------------------------------------------------------------------- */
.sg-row {
	border: 1px solid var(--sg-divider);
	border-radius: var(--sg-radius-lg);
	background-color: var(--wp--preset--color--surface);
	transition: transform 140ms ease, box-shadow 140ms ease;
}

.sg-row:hover {
	transform: translateY(-2px);
	box-shadow: var(--sg-shadow-md);
}

/* The title column takes the slack so the going-count and CTA are pushed to
   the right edge. WordPress can express this as the block's own selfStretch,
   but a class is deterministic and survives the block being edited. */
.sg-row__body {
	flex: 1 1 260px;
	min-width: 0;
}

.sg-bubble {
	flex: 0 0 auto;
	width: 78px;
	height: 78px;
	border-radius: var(--sg-pill);
	background-color: var(--wp--preset--color--base);
	border: 1px solid var(--sg-divider);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	line-height: 1;
	text-align: center;
}

.sg-bubble .sg-bubble__day {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.75rem;
	color: var(--wp--preset--color--ink);
}

.sg-bubble .sg-bubble__month {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	margin-top: 3px;
}


/* -------------------------------------------------------------------------
   Meetup rows rendered by [sg_next_tables]
   These come from PHP, not the block editor, so they carry no is-layout-*
   classes and have to bring their own flex.
   ---------------------------------------------------------------------- */
.sg-rows {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
}

.sg-rows .sg-row {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 2.2rem;
	padding: 1.65rem 2.2rem;
}

.sg-rows .sg-row__body h3 {
	margin: 0 0 0.35rem;
	font-size: var(--wp--preset--font-size--large);
}

.sg-rows .sg-row__body h3 a {
	color: inherit;
	text-decoration: none;
}

.sg-rows .sg-row__body h3 a:hover {
	color: var(--wp--preset--color--terracotta-text);
}

.sg-rows .sg-row__detail {
	margin: 0;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

.sg-rows .sg-bubble span {
	display: block;
}

.sg-rows .sg-row__actions {
	display: flex;
	align-items: center;
	gap: 1.1rem;
	margin-left: auto;
}

.sg-rows .sg-row__ical {
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	color: var(--wp--preset--color--muted);
	white-space: nowrap;
}

.sg-rows .sg-row__cta {
	display: inline-block;
	background-color: var(--wp--preset--color--terracotta-button);
	color: var(--wp--preset--color--cream-bright);
	border-radius: var(--sg-pill);
	padding: 0.7rem 1.4rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.875rem;
	text-decoration: none;
	white-space: nowrap;
}

.sg-rows .sg-row__cta:hover {
	background-color: var(--wp--preset--color--terracotta-text);
	color: var(--wp--preset--color--cream-bright);
}

.sg-rsvp-thanks {
	background-color: var(--wp--preset--color--sage-tint);
	border-radius: var(--sg-radius-md);
	padding: 1.1rem 1.65rem;
	margin-bottom: 1.65rem;
	font-weight: 600;
}

.sg-rows__empty {
	color: var(--wp--preset--color--muted);
}

/* -------------------------------------------------------------------------
   Small type treatments
   ---------------------------------------------------------------------- */
.sg-pill {
	display: inline-block;
	border-radius: var(--sg-pill);
	padding: 0.5em 1.1em;
	background-color: var(--wp--preset--color--sage-tint);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
}

.sg-pill--terracotta {
	/* Button-grade terracotta, not brand terracotta: the light label needs
	   4.5:1 and brand #c67139 only reaches 3.30. */
	background-color: var(--wp--preset--color--terracotta-button);
	color: var(--wp--preset--color--cream-bright);
}

.sg-count {
	display: inline-block;
	border-radius: var(--sg-pill);
	padding: 0.4em 0.9em;
	background-color: var(--wp--preset--color--sage-tint);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	white-space: nowrap;
}

.sg-step {
	font-family: var(--wp--preset--font-family--display);
	font-size: 2.25rem;
	line-height: 1;
	color: var(--wp--preset--color--terracotta);
}

.sg-stat__figure {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2rem, 1.4rem + 2vw, 2.75rem);
	line-height: 1;
	color: var(--wp--preset--color--terracotta);
}

/* -------------------------------------------------------------------------
   Photos — washed treatment: desaturated, lower contrast, always rounded
   ---------------------------------------------------------------------- */
.sg-washed img {
	filter: saturate(0.72) contrast(0.92);
	border-radius: var(--sg-radius-lg);
}

.sg-washed--circle img {
	border-radius: var(--sg-pill);
}

/* Placeholder blocks standing in for photography not yet shot. */
.sg-photo-placeholder {
	background-color: var(--wp--preset--color--surface);
	background-image: repeating-linear-gradient(
		135deg,
		color-mix(in srgb, #201e1d 4%, transparent) 0 8px,
		transparent 8px 16px
	);
	border-radius: var(--sg-radius-lg);
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
}

/* The approved design's hero art is about 425px across. An uncapped 45%
   column overshoots that on wide screens and pushes the whole hero taller. */
.sg-photo-placeholder--circle {
	border-radius: var(--sg-pill);
	aspect-ratio: 1;
	max-width: 440px;
}

/* The floating "61 coffees" card that overlaps the hero portrait. It has to
   shrink to its content and sit left; the parent's constrained layout would
   otherwise stretch and centre it (and does so with !important). */
.sg-float-card {
	background-color: var(--wp--preset--color--base);
	border-radius: var(--sg-radius-lg);
	box-shadow: var(--sg-shadow-lg);
	padding: 0.9rem 1.3rem;
	width: max-content;
	max-width: 100%;
	margin-left: 0 !important;
	margin-right: auto !important;
	position: relative;
}

/* The About band's heading is a feature size in the approved design — larger
   than the section headings elsewhere on the page. */
.sg-dark h2 {
	font-size: clamp(2.125rem, 1.6rem + 1.8vw, 2.875rem);
}

/* -------------------------------------------------------------------------
   Dark band (About) — sage and cream have to lift off #201e1d
   ---------------------------------------------------------------------- */
.sg-dark {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--base);
}

.sg-dark .sg-stat__figure {
	color: var(--wp--preset--color--terracotta);
}

.sg-dark a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--sage-light);
}

.sg-footer {
	border-top: 1px solid var(--sg-divider);
}

.sg-footer img {
	height: 104px;
	width: auto;
	display: block;
}

/* Respect users who have asked for less motion. */
@media (prefers-reduced-motion: reduce) {
	.sg-card,
	.sg-row {
		transition: none;
	}

	.sg-card:hover,
	.sg-row:hover {
		transform: none;
	}
}

/* -------------------------------------------------------------------------
   The Events Calendar — /meetups/

   TEC ships its own design system (tribe-common): its own font stack, a blue
   accent, 4px corners and a white card ground. None of that is themeable
   through settings, and overriding its templates would mean new PHP files
   that fight the plugin at every update. So the whole archive is restyled
   here, in CSS only.

   The !important flags below are measured, not guessed. Each one marks a
   place where a tribe-common rule out-specifies a plain class selector —
   its button stayed rgb(51,74,255), its bar stayed white, its date tag
   stretched to 163px as a flex item, and its generic link colour beat the
   title rule. Overriding a third-party design system is what !important is
   for. Re-measure before removing any of them.
   ---------------------------------------------------------------------- */

/* 1. Type. tribe-common sets "Helvetica Neue" on a great many of its own
      classes, so the family is reset across the subtree and the display face
      then re-applied to the things that should carry it. */
.tribe-common,
.tribe-common *,
.tribe-events,
.tribe-events * {
	font-family: var(--wp--preset--font-family--body);
}

.tribe-events .tribe-events-calendar-list__event-title,
.tribe-events .tribe-events-calendar-list__event-title a,
.tribe-events .tribe-events-calendar-list__month-separator-text,
.tribe-events .tribe-events-c-top-bar__datepicker-button,
.tribe-events .tribe-events-calendar-list__event-date-tag-daynum,
.tribe-events .tribe-common-c-btn {
	font-family: var(--wp--preset--font-family--display);
}

/* 2. Ground. Drop TEC's white cards and its 96px lead-in, which pushed the
      first row most of a screen below the header. */
.tribe-events .tribe-events-l-container {
	padding-top: var(--wp--preset--spacing--40);
	padding-bottom: var(--wp--preset--spacing--50);
}

body .tribe-events .tribe-events-c-events-bar,
body .tribe-events .tribe-events-c-events-bar__search-container,
body .tribe-events .tribe-events-c-view-selector__content,
body .tribe-events .tribe-events-header,
body .tribe-events .tribe-events-calendar-list__event-row {
	background-color: transparent !important;
	box-shadow: none;
}

/* 3. Search field and its button — one pill lockup. */
body .tribe-events .tribe-events-c-search__input-control {
	background-color: var(--wp--preset--color--surface) !important;
	border: 1px solid var(--sg-divider) !important;
	border-radius: var(--sg-pill) !important;
}

body .tribe-events .tribe-events-c-search__input {
	background-color: transparent !important;
	color: var(--wp--preset--color--ink);
}

body .tribe-events .tribe-common-c-btn,
body .tribe-events .tribe-common-c-btn-border,
body .tribe-events .tribe-common-c-btn-border-small {
	border-radius: var(--sg-pill) !important;
	font-weight: 400;
	letter-spacing: 0.01em;
}

body .tribe-events .tribe-common-c-btn {
	background-color: var(--wp--preset--color--terracotta-button) !important;
	color: var(--wp--preset--color--cream-bright) !important;
	border: 0 !important;
}

body .tribe-events .tribe-common-c-btn:hover,
body .tribe-events .tribe-common-c-btn:focus {
	background-color: var(--wp--preset--color--terracotta-text) !important;
}

/* Outline buttons — "Today", "Subscribe to calendar". */
body .tribe-events .tribe-common-c-btn-border,
body .tribe-events .tribe-common-c-btn-border-small {
	background-color: transparent !important;
	color: var(--wp--preset--color--terracotta-text) !important;
	border: 1px solid var(--wp--preset--color--terracotta-text) !important;
}

body .tribe-events .tribe-common-c-btn-border:hover,
body .tribe-events .tribe-common-c-btn-border-small:hover {
	background-color: var(--wp--preset--color--surface) !important;
}

/* 4. Top bar — view selector, date picker, arrows. */
body .tribe-events .tribe-events-c-view-selector__list-item-link:hover,
body .tribe-events .tribe-events-c-view-selector__list-item--active
	.tribe-events-c-view-selector__list-item-text {
	color: var(--wp--preset--color--terracotta-text) !important;
}

body .tribe-events .tribe-events-c-view-selector__list-item--active::after,
body .tribe-events .tribe-events-c-top-bar__datepicker-button::after {
	background-color: var(--wp--preset--color--terracotta) !important;
}

body .tribe-events .tribe-events-c-top-bar__datepicker-button {
	color: var(--wp--preset--color--ink);
	font-size: 1.5rem;
}

body .tribe-events .tribe-events-c-top-bar__nav-link svg path,
body .tribe-events .tribe-events-c-view-selector__button-icon-svg path {
	fill: var(--wp--preset--color--ink);
}

/* 5. Month separator — a hairline in the theme's rule colour. */
body .tribe-events .tribe-events-calendar-list__month-separator::after {
	background-color: var(--sg-divider) !important;
}

body .tribe-events .tribe-events-calendar-list__month-separator-text {
	color: var(--wp--preset--color--muted);
	font-size: 1rem;
	text-transform: none;
	letter-spacing: 0;
}

/* 6. Each event becomes one of the theme's ruled cards. */
body .tribe-events .tribe-events-calendar-list__event-row {
	margin-bottom: 1.1rem;
}

body .tribe-events .tribe-events-calendar-list__event-wrapper {
	background-color: var(--wp--preset--color--surface);
	border: 1px solid var(--sg-divider);
	border-radius: var(--sg-radius-lg);
	padding: 1.65rem 2.2rem;
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

body .tribe-events .tribe-events-calendar-list__event-wrapper:hover {
	transform: translateY(-2px);
	box-shadow: var(--sg-shadow-md);
}

/* Date tag becomes the round bubble. Without the flex reset it stretches to
   the full height of the row. */
body .tribe-events .tribe-events-calendar-list__event-date-tag-datetime {
	width: 78px !important;
	height: 78px !important;
	flex: 0 0 78px;
	align-self: center;
	border-radius: var(--sg-pill);
	background-color: var(--wp--preset--color--base);
	border: 1px solid var(--sg-divider);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	line-height: 1;
}

body .tribe-events .tribe-events-calendar-list__event-date-tag-daynum {
	font-size: 1.75rem;
	color: var(--wp--preset--color--ink);
}

body .tribe-events .tribe-events-calendar-list__event-date-tag-weekday {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

body .tribe-events .tribe-events-calendar-list__event-title a {
	color: var(--wp--preset--color--ink) !important;
	text-decoration: none;
}

body .tribe-events .tribe-events-calendar-list__event-title a:hover {
	color: var(--wp--preset--color--terracotta-text) !important;
}

body .tribe-events .tribe-events-calendar-list__event-datetime,
body .tribe-events .tribe-events-calendar-list__event-description p,
body .tribe-events .tribe-events-calendar-list__event-venue {
	color: var(--wp--preset--color--muted);
}

/* 7. Everything else that links. */
body .tribe-events a:not(.tribe-common-c-btn):not(
	.tribe-events-calendar-list__event-title-link) {
	color: var(--wp--preset--color--terracotta-text);
}

/* 8. TEC's own h1 is screen-reader-only, so the archive arrives with no
      visible title. The theme supplies one above the bar. */
.sg-events-title {
	text-align: center;
	margin: 0;
}


/* -------------------------------------------------------------------------
   Hero media — circular washed photo with the loyalty card overlapping its
   lower-left, per section 3 of the brief.

   Rendered by [sg_hero_media] rather than typed into the page, so the card
   can be positioned against the photo and the numbers stay editable as
   shortcode attributes. The card sits on cream-bright, not surface: the
   brief calls for a card lighter than the ground, and muted text on
   surface measures 4.48:1 — a hair under AA. On cream-bright it is 6.02:1.
   ---------------------------------------------------------------------- */
.sg-hero-media {
	position: relative;
	padding-bottom: 40px;
}

.sg-hero-media__photo {
	width: 100%;
	max-width: 440px;
	margin-left: auto;
	aspect-ratio: 1;
	border-radius: var(--sg-pill);
	overflow: hidden;
}

.sg-hero-media__photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	/* Same washed treatment as .sg-washed, applied here because the image
	   is generated by the shortcode rather than wrapped in a figure. */
	filter: saturate(0.72) contrast(0.92);
}

.sg-hero-media__credit {
	margin: 0.6rem 0 0;
	text-align: right;
	font-size: 0.75rem;
	color: var(--wp--preset--color--muted);
}

/* The loyalty card. 262px and -2.5deg are from the approved mockup. */
.sg-loyalty {
	position: absolute;
	/* Overhangs the column to the left, into the hero's gutter, so the card
	   clears the photo's lower-left corner. Both numbers are the mockup's. */
	left: -46px;
	bottom: 52px;
	width: 262px;
	max-width: 100%;
	background-color: var(--wp--preset--color--cream-bright);
	border-radius: 24px;
	padding: 20px 24px;
	box-shadow: var(--sg-shadow-lg);
	transform: rotate(-2.5deg);
}

.sg-loyalty__head {
	display: flex;
	align-items: center;
	gap: 10px;
}

.sg-loyalty__head img {
	width: 30px;
	height: 30px;
	object-fit: contain;
	flex: 0 0 30px;
}

.sg-loyalty__label {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-weight: 700;
	font-size: 9.5px;
	line-height: 1.35;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--wp--preset--color--terracotta-text);
}

.sg-loyalty__grid {
	display: grid;
	grid-template-columns: repeat(8, 1fr);
	gap: 7px;
	margin-top: 16px;
}

.sg-loyalty__dot {
	aspect-ratio: 1;
	border-radius: var(--sg-pill);
	background-color: var(--wp--preset--color--terracotta);
}

.sg-loyalty__dot--sage {
	background-color: var(--wp--preset--color--sage);
}

/* The empty slot waiting for the next stamp. */
.sg-loyalty__dot--next {
	background-color: transparent;
	border: 2.5px dashed color-mix(in srgb, var(--wp--preset--color--terracotta) 55%, transparent);
}

.sg-loyalty__rule {
	height: 1px;
	background-color: var(--sg-divider);
	margin: 16px 0;
}

.sg-loyalty__count {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 23px;
	line-height: 1;
	color: var(--wp--preset--color--ink);
}

.sg-loyalty__note {
	margin: 3px 0 0;
	font-size: 12.5px;
	color: var(--wp--preset--color--muted);
}

/* Narrow: the overlap stops working once the column is full width, so the
   card drops below the photo, square on and centred. */
@media (max-width: 781px) {
	.sg-hero-media {
		padding-bottom: 0;
	}

	.sg-hero-media__photo {
		margin-inline: auto;
	}

	.sg-loyalty {
		position: static;
		transform: none;
		margin: 1.6rem auto 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.sg-loyalty {
		transform: none;
	}
}

/* Both hero columns are vertically centred, so the left column's top edge
   moves with its own height — shrink the type and the text sinks. Pin the
   text column to the top of the row instead. The media column keeps its
   centring, so the photo and card do not move, and further type changes on
   the left no longer shift anything vertically.

   :has() picks the hero out without needing a class on the block, so this
   costs no page edit. Browsers without :has() simply keep the old centring. */
.wp-block-columns:has(> .wp-block-column .sg-hero-media)
	> .wp-block-column:not(:has(.sg-hero-media)) {
	align-self: flex-start;
}

/* With both hero columns starting at the same height, the row sat too close
   to the brand band. Padding rather than margin: the constrained-layout
   margin rules would otherwise fight it. */
.wp-block-columns:has(> .wp-block-column .sg-hero-media) {
	padding-top: 48px;
}

/* -------------------------------------------------------------------------
   Mobile — the header, and The Events Calendar's list rows

   The desktop header is a 1fr auto 1fr grid with the standing-invitation pill
   absolutely positioned under the left nav. Collapsed to one column that pill
   lands on top of the logo, and the 5rem insets that shorten the rules either
   side of the logo knock the two hairlines out of alignment.
   ---------------------------------------------------------------------- */
@media (max-width: 900px) {
	/* Dissolve the nav column so the logo, both nav groups and the pill are
	   all grid items and can be ordered independently of the source order,
	   which is nav / logo / nav. */
	.sg-brand-band > .wp-block-group > .sg-nav-col {
		display: contents;
	}

	/* Stretch so both hairlines run the same width; the logo and pill centre
	   themselves instead of stretching. */
	.sg-brand-band > .wp-block-group { justify-items: stretch; }
	.sg-brand-band .sg-brandmark { order: 1; justify-self: center; }
	.sg-brand-band .sg-nav-col > .sg-navbox { order: 2; }
	.sg-brand-band > .wp-block-group > .sg-navbox { order: 3; }
	.sg-brand-band .sg-pill--header { order: 4; }

	.sg-brand-band > .wp-block-group > .sg-nav-col,
	.sg-brand-band > .wp-block-group > .sg-navbox:last-child {
		margin-left: 0;
		margin-right: 0;
	}

	/* Both nav groups read as one block: one rule above, one below, and no
	   double hairline where they meet. */
	.sg-brand-band .sg-navbox {
		justify-content: center;
		padding-top: 0;
		padding-bottom: 0;
	}

	.sg-brand-band .sg-nav-col > .sg-navbox {
		border-top: 1px solid var(--sg-divider);
		border-bottom: 0;
		margin-top: 1.4rem;
	}

	.sg-brand-band > .wp-block-group > .sg-navbox {
		border-top: 0;
	}

	.sg-brand-band .sg-pill--header {
		position: static;
		transform: none;
		justify-self: center;
		margin: 1.2rem 0 0;
	}

	.sg-brandmark img { width: 164px; }

	/* 13px uppercase links are a small tap target; pad them out to ~44px. */
	.sg-navbox p a {
		display: inline-block;
		padding: 0.7rem 0;
	}
}

@media (max-width: 781px) {
	/* TEC narrows its date column to 54px on mobile, but the theme's bubble is
	   78px, so it spilled out of the card. Move the card onto the row itself so
	   the bubble sits inside it, and size the bubble to the narrower column. */
	body .tribe-events .tribe-events-calendar-list__event-row {
		/* !important because the desktop block above zeroes this row's
		   background with !important to beat TEC. */
		background-color: var(--wp--preset--color--surface) !important;
		border: 1px solid var(--sg-divider);
		border-radius: var(--sg-radius-lg);
		padding: 1.2rem 1.3rem;
		align-items: center;
		gap: 1rem;
	}

	body .tribe-events .tribe-events-calendar-list__event-wrapper {
		background-color: transparent;
		border: 0;
		border-radius: 0;
		padding: 0;
	}

	body .tribe-events .tribe-events-calendar-list__event-wrapper:hover {
		transform: none;
		box-shadow: none;
	}

	body .tribe-events .tribe-events-calendar-list__event-date-tag {
		flex: 0 0 66px;
		width: 66px;
		padding: 0;
	}

	body .tribe-events .tribe-events-calendar-list__event-date-tag-datetime {
		width: 66px !important;
		height: 66px !important;
		flex: 0 0 66px;
	}

	body .tribe-events .tribe-events-calendar-list__event-date-tag-daynum {
		font-size: 1.4rem;
	}
}

/* -------------------------------------------------------------------------
   Opt out of algorithmic dark mode.

   This design is light-only. Chrome's Auto Dark Theme on Android and
   Samsung Internet's dark mode repaint arbitrary light pages by inverting
   lightness while preserving hue — which turns a warm cream ground into
   dark brown and a terracotta accent into mud. Declaring the scheme tells
   those browsers the page has already made its choice and to leave it be.
   A matching meta tag is emitted in wp_head so it applies before CSS loads.
   ---------------------------------------------------------------------- */
:root {
	color-scheme: only light;
}

/* -------------------------------------------------------------------------
   Contact form — rendered by [sg_contact] in the footer.
   ---------------------------------------------------------------------- */
.sg-contact {
	/* The nav links to #contact, and the header is not sticky, so a small
	   offset is all that is needed to stop the heading sitting flush against
	   the top of the viewport. */
	scroll-margin-top: 2rem;
	max-width: 30rem;
}

.sg-contact__heading {
	margin: 0 0 0.3rem;
	font-size: var(--wp--preset--font-size--large);
}

.sg-contact__intro {
	margin: 0 0 1.2rem;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

.sg-contact__form {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.8rem;
}

.sg-contact__field {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}

.sg-contact__field--wide,
.sg-contact__actions {
	grid-column: 1 / -1;
}

.sg-contact__field label {
	font-size: 0.8125rem;
	font-weight: 600;
	color: var(--wp--preset--color--muted);
}

.sg-contact__field input,
.sg-contact__field textarea {
	font-family: var(--wp--preset--font-family--body);
	font-size: 1rem;
	color: var(--wp--preset--color--ink);
	background-color: var(--wp--preset--color--cream-bright);
	border: 1px solid var(--sg-divider);
	border-radius: var(--sg-radius-md);
	padding: 0.7rem 0.9rem;
	width: 100%;
}

.sg-contact__field textarea {
	resize: vertical;
	min-height: 5.5rem;
}

.sg-contact__field input:focus-visible,
.sg-contact__field textarea:focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta);
	outline-offset: 2px;
	border-color: transparent;
}

.sg-contact__actions {
	margin: 0.2rem 0 0;
}

.sg-contact__submit {
	background-color: var(--wp--preset--color--terracotta-button);
	color: var(--wp--preset--color--cream-bright);
	border: 0;
	border-radius: var(--sg-pill);
	font-family: var(--wp--preset--font-family--display);
	font-size: 1rem;
	padding: 0.85rem 1.9rem;
	cursor: pointer;
}

.sg-contact__submit:hover {
	background-color: var(--wp--preset--color--terracotta-text);
}

.sg-contact__notice {
	border-radius: var(--sg-radius-md);
	padding: 0.8rem 1.1rem;
	margin: 0 0 1.1rem;
	font-size: var(--wp--preset--font-size--small);
}

.sg-contact__notice--ok {
	background-color: var(--wp--preset--color--sage-tint);
	color: var(--wp--preset--color--sage-text);
}

.sg-contact__notice--bad {
	background-color: color-mix(in srgb, var(--wp--preset--color--terracotta) 16%, transparent);
	color: var(--wp--preset--color--terracotta-text);
}

/* The honeypot. Off-screen rather than display:none — some bots skip hidden
   fields, and screen readers are told to ignore it via aria-hidden. */
.sg-contact__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

@media (max-width: 600px) {
	.sg-contact__form {
		grid-template-columns: 1fr;
	}
}

/* Anchored nav targets. The header is not sticky, so this is only breathing
   room, not clearance for an overlay. */
#about,
#faq {
	scroll-margin-top: 1.5rem;
}

/* Three corrections to the contact form, all measured on the live page:
   the inputs came out content-box so width:100% plus padding overflowed the
   field by 30px; the constrained layout centred the whole block with
   margin-inline:auto (Twenty Twenty-Five declares that with !important, so
   the override needs one too). */
.sg-contact__field input,
.sg-contact__field textarea,
.sg-contact__submit {
	box-sizing: border-box;
}

.sg-footer .sg-contact {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* wpautop also injects a bare empty <p> into the form, which becomes a grid
   item and swallows the first cell — measured: 34px tall, no content, and it
   pushed the Name field into the right-hand column. Hide any paragraph with
   nothing in it; every real field here carries a class. */
.sg-contact p:empty {
	display: none;
}

/* -------------------------------------------------------------------------
   A placeholder that has had a real image dropped into it

   Once there is an actual image inside, the striped placeholder should stop
   behaving like one. Measured before this rule: the About circle rendered
   395x522 — an oval — because the image's natural height overrode the 1:1
   aspect ratio, and the group carries is-content-justification-left, which
   pushed the art off centre.
   ---------------------------------------------------------------------- */
.sg-photo-placeholder:has(img) {
	background-image: none;
	background-color: var(--wp--preset--color--base);
	padding: 0 !important;
	overflow: hidden;
	justify-content: center !important;
	align-items: center;
}

.sg-photo-placeholder--circle:has(img) {
	aspect-ratio: 1;
	width: 100%;
}

.sg-photo-placeholder:has(img) .wp-block-image {
	margin: 0 !important;
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Line art on a transparent ground — beard-coffee-mark.png measures 61%
   transparent — so contain and inset it rather than cropping. If this is
   ever swapped for a real photograph, change contain to cover and drop the
   padding, which is how the hero photo is handled. */
.sg-photo-placeholder:has(img) img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: 11%;
	box-sizing: border-box;
	border-radius: inherit;
}
