/* ==========================================================================
   SFX Acushnet Intranet — Custom Theme CSS
   ========================================================================== */

/* --------------------------------------------------------------------------
   Global layout — footer always reaches bottom of viewport
   -------------------------------------------------------------------------- */

html {
	height: 100%;
	font-size: 112.5%; /* 18px base — improves legibility for parent/grandparent demographic */
}

body {
	min-height: 100vh;
	min-height: 100dvh;
}

.wp-site-blocks {
	min-height: 100vh;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
}

.wp-site-blocks > footer {
	margin-top: auto !important;
}

/*
 * Let full-width blocks actually reach the viewport edges.
 *
 * Core breaks .alignfull out of a .has-global-padding container with negative
 * margins equal to the root padding, expecting the element to grow by that
 * much on each side. Ollie's `img, figure { max-width: 100% }` caps it at the
 * parent's content box instead, so the element shifts left by the root padding
 * but never widens -- leaving a gap of exactly 2x the root padding on the
 * right. Affects any figure or image set to full width.
 */
.has-global-padding > .alignfull {
	max-width: none;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

/*
 * Where no classroom subheader follows it, the header ends on a gold rule.
 * On most templates the tinted subheader band gives the maroon header
 * something to end against; the pages without one -- the network landing page,
 * the login page -- had it stopping dead, which the full bleed featured image
 * made obvious.
 *
 * Keyed to the absence of the subheader in the markup, deliberately, rather
 * than to anything about who is looking. Debug mode lets a logged in super
 * admin view these same pages, so a rule hanging off body.logged-in or a
 * logged-out template class would come and go with the viewer.
 *
 * 8px rather than the 6 that also reads well: the theme's accent rules are
 * 4px (the post card and pull quote borders, and the gold announcement variant
 * of the same 4px rule), with 3px for lesser indicators and 1px for hairlines.
 * 8px is that accent at double weight, which suits a rule spanning the full
 * viewport under a 122px header; 6px sits off the scale entirely.
 */
body:not(:has(.sfx-classroom-subheader)) .sfx-header {
	border-bottom: 8px solid var(--wp--preset--color--sfx-gold);
}


/*
 * Suppress the flow-layout block gap between topbar and main nav bar.
 * blockGap:"0" was removed from the block attribute because WP 6.9 no
 * longer serializes it as an inline custom property. We target children
 * directly to beat WordPress's :where()-based layout margin rules.
 */
.sfx-header.is-layout-flow > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

.sfx-header-topbar {
	background-color: var(--wp--preset--color--sfx-light-gray);
	padding-block: 6px;
	padding-inline: max(20px, calc((100% - var(--wp--style--global--wide-size)) / 2));
}

.sfx-header-topbar a,
.sfx-header-topbar .wp-block-navigation a {
	color: var(--wp--preset--color--sfx-maroon) !important;
	font-weight: 700;
	text-decoration: none;
	font-size: 0.75rem;
}

.sfx-header-topbar a:hover,
.sfx-header-topbar .wp-block-navigation a:hover {
	text-decoration: underline;
}

/* Logged-out variant: topbar centered */
.sfx-header-topbar--centered {
	justify-content: center;
}

.sfx-header-main {
	background-color: var(--wp--preset--color--sfx-maroon);
	padding-block: 24px;
	padding-inline: max(20px, calc((100% - var(--wp--style--global--wide-size)) / 2));
}

/* Size the logo in the main nav bar */
.sfx-header-main img {
	height: 70px;
	width: auto;
}

/*
 * The logo is a wide wordmark — 4.7:1, so 70px tall is 327px across. That
 * only leaves room for the nav beside it once the bar is about 780px wide;
 * below that the flex row wraps and the nav drops under the logo, doubling
 * the header's height. Hold the logo near its old size until there is room,
 * with the breakpoint set clear of the 768px edge rather than on it.
 */
@media (max-width: 799px) {
	.sfx-header-main img {
		height: 44px;
	}
}

/*
 * Hide the top bar on small screens. The breakpoint matches the one core's
 * navigation block uses to collapse into the hamburger overlay (600px), so the
 * topbar links are never gone without the overlay being there to hold their
 * mobile copies (see the secondary links below). Hiding at 767px, as this once
 * did, left a 600-767px band with neither.
 */
@media (max-width: 599px) {
	.sfx-header-topbar {
		display: none !important;
	}
}

/* Navigation: bold white links in the main nav bar */
.sfx-header-main .wp-block-navigation a {
	color: var(--wp--preset--color--sfx-white) !important;
	font-weight: 700;
	font-size: 0.9rem;
}

/* Navigation overlay: full-width maroon */
.sfx-header-main .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--sfx-maroon);
}

/*
 * Overlay logo. The first item in the main navigation block is a link to the
 * network home carrying the site logomark, shown only inside the open overlay,
 * on the same row as the close button. The item's row is the close button's
 * height and replaces the top padding core gives the overlay content, so the
 * rest of the list keeps its usual position. Ollie sizes and pads every overlay
 * link and paints a hover background, so the link rule repeats enough ancestors
 * to outrank those. The link text stays for screen readers.
 */
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item.sfx-nav-overlay-logo {
	display: none;
}

.sfx-header-main .wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: 0;
}

.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item.sfx-nav-overlay-logo {
	align-items: center;
	justify-content: center;
	margin-bottom: 23px; /* 5px list gap + this = 28px between the logo and the first link */
}

.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .sfx-nav-overlay-logo .wp-block-navigation-item__content {
	flex: none; /* without this the link shrinks to the column flex box */

	/*
	 * Matches the footer's 60px once there is room for it. The close button
	 * is absolutely positioned in the dialog's top right, so it does not
	 * share this row and cannot be pushed aside — the logo is centred in a
	 * content box that is always the viewport less 54px, which leaves it
	 * `100% - 88px` before it runs into the button's 32px plus a 12px gap.
	 * Narrow phones therefore scale it down rather than overlapping: 280px
	 * from 368px up, 233px at 375px, and 178px — the size it replaced — at
	 * 320px. Height follows from the ratio so it never distorts.
	 */
	width: min(280px, calc(100% - 88px));
	aspect-ratio: 560 / 120;
	padding: 0;
	background: center / contain no-repeat;

	/*
	 * The overlay logo is painted, not marked up, so the srcset the img tags
	 * get from sfxi_add_logo_srcset() cannot reach it. image-set() is the
	 * background-image equivalent; the plain url() above it is the fallback
	 * for engines that do not parse image-set, which would otherwise leave
	 * the overlay with no logo at all.
	 */
	background-image: url(../images/frankie-connect-inverted.png);
	background-image: image-set(
		url(../images/frankie-connect-inverted.png) 1x,
		url(../images/frankie-connect-inverted@2x.png) 2x,
		url(../images/frankie-connect-inverted@3x.png) 3x,
		url(../images/frankie-connect-inverted@4x.png) 4x
	);
}

.sfx-nav-overlay-logo .wp-block-navigation-item__label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/*
 * Mobile overlay secondary links — hidden until the overlay is open. The header
 * template part repeats the topbar links with this class, and the classroom
 * switcher block inserts a "Classrooms" submenu with it (see
 * Classroom_Switcher::inject_overlay_submenu()), so the overlay is the one place
 * on a phone that holds everything the hidden topbar had.
 *
 * Keyed on the closed responsive container rather than on the open one: core
 * sets `display` on `.wp-block-navigation .wp-block-navigation-item` (0,2,0),
 * which a bare class selector cannot beat, and in the open overlay core's own
 * flex rules for items and submenus should apply untouched.
 */
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item.sfx-nav-mobile-secondary-link {
	display: none;
}

/*
 * Ollie gives every link in the open overlay `width: 100%` plus 15px/60px
 * horizontal padding without switching to border-box, so each link is 75px
 * wider than its item. Core aligns the items to the right (both header navs
 * justify right), which pushes that overflow off the left edge of the screen
 * and clips the first characters of every label. Sizing the padding into the
 * width removes the overflow. Ollie's rule is (0,4,0) and its block styles can
 * print after this stylesheet, so the extra ancestor makes this outrank it.
 */
.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content {
	box-sizing: border-box;
}

/*
 * A rule separates the secondary section from the main links above it. Margin
 * rather than padding: Ollie zeroes padding on every overlay item.
 */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:not(.sfx-nav-mobile-secondary-link) + .sfx-nav-mobile-secondary-link {
	margin-top: 12px;
	border-top: 1px solid rgba(255, 255, 255, 0.35);
}

/*
 * The injected Classrooms submenu lists every classroom the user belongs to.
 * Core already expands submenus inside the open overlay; this just indents the
 * list under its label and marks the classroom being viewed.
 */
.wp-block-navigation__responsive-container.is-menu-open .sfx-nav-mobile-secondary-link .wp-block-navigation__submenu-container {
	padding-inline-start: 16px;
}

.wp-block-navigation__responsive-container.is-menu-open .sfx-nav-classroom-link--current > a {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* --------------------------------------------------------------------------
   Classroom Subheader
   -------------------------------------------------------------------------- */

.sfx-classroom-subheader {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
	padding-block: 10px;
	padding-inline: max(20px, calc((100% - var(--wp--style--global--wide-size)) / 2));
	font-weight: 700;
	color: var(--wp--preset--color--sfx-maroon);
	font-size: 0.9rem;
}

/*
 * The subheader sits flush against the content below it. Core's
 * `:where(.wp-site-blocks) > *` block gap adds a `margin-block-start` to every
 * top level block, so it is zeroed out on the block immediately following the
 * subheader template part. Blocks that set their own top margin inline (the
 * search template's main, for example) are unaffected, and the ones that do not
 * carry enough padding of their own to keep the spacing from collapsing.
 */
.wp-block-template-part:has(> .sfx-classroom-subheader) + * {
	margin-block-start: 0;
}

/*
 * The same gap, in a template the rule above cannot reach. The logged out
 * landing page has no classroom subheader, so its header template part is
 * followed straight by the next top level block and core's block gap leaves
 * 36px between them.
 * That went unnoticed while everything under the header was white; a full bleed
 * featured image turns it into a white band across the top of the page.
 *
 * This deliberately matches the next element rather than the next visible one.
 * With no featured image set, the element after the header is the collapsed
 * .sfx-page-title-wrap, so <main> keeps the block gap it has always had.
 */
.wp-block-template-part:has(> .sfx-header--logged-out) + * {
	margin-block-start: 0;
}

/*
 * The same gap once more, this time below the banner. The subheader rule above
 * only reaches the block right after the subheader, which is the banner part
 * itself -- so the block after the banner still takes core's 36px top level
 * block gap and a white band sits between the image and the content.
 *
 * This matches the banner whether or not a featured image is set, because
 * either way the gap is unwanted. With an image the content should sit flush
 * against it. Without one .sfx-page-title-wrap collapses to display:none, and
 * the gap is then stacked on top of the following block's own padding for no
 * visible reason -- 36px of block gap plus 36px of padding left My Account 72px
 * below the subheader, and Log In 90px below its header.
 *
 * Only the margin goes. Every template that follows the banner carries its own
 * top padding -- padding-block on the full-width and login mains, padding-top on
 * the content+sidebar wraps -- and that padding is the spacing that remains.
 */
.wp-block-template-part:has(> .sfx-page-title-wrap) + * {
	margin-block-start: 0;
}

.sfx-classroom-subheader .wp-block-site-title {
	margin: 0;
	white-space: nowrap;
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.sfx-classroom-subheader .wp-block-site-title a {
	color: inherit;
	text-decoration: none;
}

.sfx-classroom-subheader .wp-block-site-title a:hover {
	text-decoration: underline;
}

/*
 * The site title sits immediately to the left of this nav and already links
 * to the site's front page, so the page list's own front page entry is
 * redundant beside it. Core tags that entry `menu-item-home`, which tracks
 * whichever page each subsite has set as its front page rather than matching
 * on the title. The selector is scoped to the subheader so the sidebar and
 * site home page lists keep theirs.
 *
 * The open mobile overlay is the exception: it covers the site title, so the
 * entry is the only way home from in there and it stays. Keying on the closed
 * container rather than a width keeps that in step with whatever breakpoint
 * core opens the overlay at, and leaves core's `display: flex` for open
 * overlay items to apply on its own.
 */
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-page-list > .menu-item-home {
	display: none;
}

.sfx-classroom-subheader .wp-block-navigation a {
	color: var(--wp--preset--color--sfx-maroon) !important;
	font-size: 0.82rem;
	font-weight: 600;
	text-decoration: none;
}

.sfx-classroom-subheader .wp-block-navigation a:hover,
.sfx-classroom-subheader .wp-block-navigation .current-menu-item > a {
	text-decoration: underline;
}

.sfx-classroom-subheader .wp-block-navigation__submenu-icon svg {
	fill: currentColor;
	transition: transform 0.2s ease;
}

/*
 * The dropdown a classroom page with child pages opens.
 *
 * Two stylesheets have already had their say about this panel before this one
 * loads. Core gives it a white background and a 15%-black hairline. Ollie then
 * takes the hairline away -- `border: none !important` in its core-navigation
 * block stylesheet -- and puts a shadow preset in its place whose heaviest
 * layer is 3% black at 3px. On the white page below the subheader that leaves
 * the panel with no edge at all.
 *
 * Ollie sets the row padding from the same file, also with !important, at
 * `spacing--small spacing--medium`. Against this theme's 18px root those
 * clamps settle at 18px and 36px on a desktop viewport, which is a 54px row
 * for a 15px label. Add the further padding Ollie puts on the first and last
 * rows and five links run to a 322px panel.
 *
 * So two declarations here carry !important, and only those two. It is not a
 * shortcut past specificity -- these rules are already a class more specific
 * than Ollie's -- but the only way past its own !important. The rest cascade
 * normally, and the panel ends up with what the classroom switcher's menu in
 * the header above already uses: white, a light gray border, a soft shadow,
 * the card radius, so the two dropdowns in the header stack read as one thing.
 *
 * Ollie's negative left margin on the panel is left alone. It is what tucks a
 * left-aligned menu back under its parent, and this nav is right-aligned,
 * where core anchors the box by its right edge and the browser absorbs the
 * margin into the offset it solves for. The panel lands in the same place with
 * or without it.
 *
 * Every rule is scoped to the closed responsive container, the way Ollie
 * scopes its own. Opened as the mobile overlay this submenu is not a floating
 * panel at all: core and Ollie both unfold it inline and strip its border, and
 * neither has anything to say about a shadow or a radius, so the scoping is
 * what keeps those out rather than a reset.
 */
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container {
	background-color: var(--wp--preset--color--sfx-white);
	border: 1px solid var(--wp--preset--color--sfx-light-gray) !important;
	border-radius: var(--wp--custom--border-radius--card);
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
	gap: 0;
	max-width: 280px;
	padding-block: 4px;
}

/*
 * The rows. 1.3 and 8px takes a 54px row to 35px, and the 4px on the panel
 * above keeps the first and last rows off its rounded corners -- which is also
 * why Ollie's own padding on those two rows is cleared here rather than left
 * to stack on top of it.
 *
 * The padding is set on the link rather than the list item so the hover tint
 * covers the whole row: core gives the link `flex-grow: 1` inside a flex item,
 * so it already fills the row's width.
 */
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	line-height: 1.3;
	padding: 8px 14px !important;
}

.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container > li:first-child,
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container > li:last-child {
	padding-block: 0;
}

/*
 * A whole row lighting up is the clearer signal in a panel this tight, and the
 * tint is the one the subheader band itself is painted in, so the dropdown
 * reads as part of the band it came from. Maroon on it is 7.10:1. The
 * underline the band's links take on hover -- and the one Ollie's theme.json
 * puts on every navigation link on hover -- would be noise on top of it.
 */
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
	text-decoration: none;
}

/* The page being read takes the same tint, and bold on top of it so it is
   still the marked row while a neighbouring row is under the cursor. */
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .current-menu-item > .wp-block-navigation-item__content,
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .current_page_item > .wp-block-navigation-item__content {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
	font-weight: 700;
	text-decoration: none;
}

/* Inset so the ring is not clipped by the panel's own edge on the first and
   last rows. */
.sfx-classroom-subheader .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible {
	outline: 2px solid var(--wp--preset--color--sfx-maroon);
	outline-offset: -2px;
}

/*
 * The open overlay takes the subheader band's own tint. Core paints a white
 * default overlay on any navigation block without an explicit overlay
 * background, using a five-class selector, so this repeats those classes to
 * outrank it. It is CSS rather than an `overlayBackgroundColor` attribute on
 * the block so it also reaches subsites whose subheader part is overridden in
 * the database.
 */
.sfx-classroom-subheader .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
	color: var(--wp--preset--color--sfx-maroon);
}

/*
 * On small screens this hamburger sits directly under the main header's
 * hamburger. A "Pages" label next to the icon tells the two apart: the top one
 * is the site menu, this one is the classroom's pages. Done in CSS so it also
 * reaches subsites whose subheader part is overridden in the database.
 */
.sfx-classroom-subheader .wp-block-navigation__responsive-container-open::before {
	content: "Pages";
	font-size: 0.82rem;
	font-weight: 600;
	margin-inline-end: 6px;
}

/* Generic nav chevron — classroom switcher toggle and subheader dropdown indicators */
.sfx-nav-chevron {
	display: block;
	flex-shrink: 0;
	transition: transform 0.15s ease;
}

.page_item_has_children:hover > a .sfx-nav-chevron,
.page_item_has_children.is-open > a .sfx-nav-chevron {
	transform: rotate(180deg);
}

/* WP core navigation block chevron SVG — header and topbar */
.sfx-header-main .wp-block-navigation__submenu-icon svg,
.sfx-header-topbar .wp-block-navigation__submenu-icon svg {
	fill: currentColor;
	transition: transform 0.2s ease;
}

.sfx-header-main .has-child:hover > a .wp-block-navigation__submenu-icon svg,
.sfx-header-main .has-child:focus-within > a .wp-block-navigation__submenu-icon svg,
.sfx-header-topbar .has-child:hover > a .wp-block-navigation__submenu-icon svg,
.sfx-header-topbar .has-child:focus-within > a .wp-block-navigation__submenu-icon svg {
	transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
   Two-column content layout (content + sidebar)
   -------------------------------------------------------------------------- */

/*
 * Core ships `:root :where(.wp-block-template-part) { margin-top: 0 !important }`,
 * which strips the block gap from every template part. That is right for the
 * header, subheader, banner and footer, which butt against what surrounds
 * them -- but wrong for a part used as content, like the recent updates feed
 * on the principal's desk and the site home, where it left the heading flush
 * against the section above it.
 *
 * Core's reset is `margin-top: 0 !important`, so no selector however specific
 * can take it back without !important of its own -- the same reason the column
 * stacking rules below carry one. Physical `margin-top` rather than logical
 * `margin-block-start`, to match the property core sets.
 *
 * Scoped to parts inside .sfx-main -- content parts -- and skipping a first
 * child, which has nothing to be separated from.
 */
.sfx-main > .wp-block-template-part:not(:first-child) {
	margin-top: var(--wp--preset--spacing--medium) !important;
}

/*
 * The separator between the sidebar's featured image and the rest of the
 * sidebar is static markup, but the Featured Image block above it renders
 * nothing at all when a page has no featured image -- leaving a rule floating
 * above the teacher cards, separating the image from nothing. Hide it unless
 * the image is actually there, the same way .sfx-page-title-wrap collapses.
 *
 * The featured image is matched as a direct child: the sidebar part below it
 * is full of teacher card portraits, so a plain :has(img) would always match.
 */
.sfx-sidebar-col:not(:has(> .wp-block-post-featured-image)) > .wp-block-separator {
	display: none;
}

/*
 * The layout itself lives in the block markup, following Ollie's lead: a
 * constrained group wrapping an alignwide columns block. Because the parent
 * theme sets useRootPaddingAwareAlignments, core tags every constrained block
 * with .has-global-padding and supplies the horizontal gutters; vertical
 * padding is a spacing-preset attribute on the group. Nothing here needs to
 * re-implement any of that.
 *
 * The one job left for CSS is the stacking breakpoint. Core stacks columns at
 * 781px, but the sidebar hides its page nav at 899px -- without this the
 * sidebar would spend 782-899px as a cramped 25% column with half its
 * contents already hidden.
 */
@media (max-width: 899px) {
	.sfx-content-sidebar-wrap .wp-block-columns {
		flex-wrap: wrap !important;
	}

	.sfx-content-sidebar-wrap .wp-block-column {
		flex-basis: 100% !important;
	}

	/*
	 * Templates that put the featured image in the sidebar want it beneath the
	 * article's heading once the columns stack, not stranded below the whole
	 * article. `order` sorts flex items only, and both the heading and the
	 * image sit two levels down -- the heading inside <main> inside the
	 * content column, the image inside the sidebar column. So both wrappers
	 * become `display: contents`, which drops their boxes and promotes their
	 * children to flex items of .wp-block-columns. Heading and image are then
	 * siblings and can be sorted directly.
	 *
	 * Scoped with :has() to the columns block that actually holds the marked
	 * sidebar column, so the templates sharing .sfx-content-sidebar-wrap
	 * without a sidebar image -- my account, the principal's desk, archives --
	 * keep the plain stacking above and never have their boxes dropped.
	 *
	 * The promoted children need their own flex-basis for the same reason the
	 * columns do: as flex items in a wrapping row they would otherwise size to
	 * content and sit side by side.
	 */
	.sfx-content-sidebar-wrap .wp-block-columns:has(> .sfx-sidebar-col) > .wp-block-column,
	.sfx-content-sidebar-wrap .wp-block-columns:has(> .sfx-sidebar-col) .sfx-main {
		display: contents;
	}

	.sfx-content-sidebar-wrap .wp-block-columns:has(> .sfx-sidebar-col) .sfx-main > *,
	.sfx-content-sidebar-wrap .sfx-sidebar-col > * {
		flex-basis: 100%;
	}

	/*
	 * Heading first, then the image, then everything else in source order.
	 * When a template has no heading the image simply sorts to the top, which
	 * is the right answer for a page with nothing to sit beneath.
	 */
	.sfx-content-sidebar-wrap .sfx-main > .wp-block-post-title {
		order: -2;
	}

	.sfx-content-sidebar-wrap .sfx-sidebar-col > .wp-block-post-featured-image {
		order: -1;
	}

	/*
	 * That separator divides the image from the sidebar. Once the image moves
	 * up it divides nothing -- it would just draw a line above the sidebar --
	 * so it goes, matching the separator inside .sfx-sidebar which is hidden
	 * at this width too.
	 */
	.sfx-content-sidebar-wrap .sfx-sidebar-col > .wp-block-separator {
		display: none;
	}

	/* Hide page nav and separator in sidebar on mobile; teacher cards remain visible */
	.sfx-sidebar .sfx-page-nav {
		display: none;
	}

	.sfx-sidebar .wp-block-separator {
		display: none;
	}

	/* Inline page-nav-only sidebars (e.g. site-home) hide completely on mobile */
	.sfx-sidebar:not(:has(.sfx-teacher-card)) {
		display: none;
	}

	/*
	 * Stacked, the sidebar runs the full page width, so a single column of
	 * teacher cards leaves most of the row empty -- lay them out two per row.
	 * The cards are siblings inside whichever group holds the block (one block
	 * renders a card per matching user, and parts/sidebar.html stacks three
	 * blocks in one group), so the grid is matched by what a group contains
	 * rather than by class: the wrapper in parts/sidebar.html carries
	 * .sfx-teacher-card itself, the same class as the cards inside it.
	 * Row spacing keeps coming from each card's own padding-bottom.
	 */
	.sfx-sidebar .wp-block-group:has(> .sfx-teacher-card) {
		display: grid;
		grid-template-columns: repeat(2, 1fr);
		column-gap: 16px;
	}

	/*
	 * Side by side, cards hold different amounts of text: a title is optional,
	 * and a long name wraps to a second line. Sized independently they drift
	 * out of step -- a card with no title lines its address up with its
	 * neighbour's title, and a wrapped name pushes everything under it down.
	 * So each card spans the same four row tracks and drops its parts into
	 * them by class, giving photo, name, title and address one shared band
	 * apiece across the row. A part a card doesn't render just leaves its band
	 * empty, still sized by the neighbour that does.
	 *
	 * Where subgrid is missing the cards size themselves, which is the ragged
	 * two-per-row layout this replaced -- worth having, just not aligned.
	 */
	@supports (grid-template-rows: subgrid) {
		.sfx-sidebar .wp-block-group:has(> .sfx-teacher-card) > .sfx-teacher-card {
			display: grid;
			grid-template-rows: subgrid;
			grid-row: span 4;
		}

		/* In render order. Only ever a grid child inside the wrapper above. */
		.sfx-sidebar .sfx-teacher-card > .sfx-teacher-card__photo {
			grid-row: 1;
		}

		.sfx-sidebar .sfx-teacher-card > .sfx-teacher-card__name {
			grid-row: 2;
		}

		.sfx-sidebar .sfx-teacher-card > .sfx-teacher-card__title {
			grid-row: 3;
		}

		.sfx-sidebar .sfx-teacher-card > .sfx-teacher-card__email {
			grid-row: 4;
		}

		/* The editor-only empty-state notice is not a card; give it its own row. */
		.sfx-sidebar .wp-block-group:has(> .sfx-teacher-card) > .sfx-teacher-card-placeholder {
			grid-column: 1 / -1;
		}
	}

	/*
	 * A fixed 160px photo overflows a half-width column on a narrow phone.
	 * Covers the no-avatar fallback too -- it is the same size as a photo.
	 */
	.sfx-sidebar .wp-block-group:has(> .sfx-teacher-card) .sfx-teacher-card__photo {
		width: min(160px, 100%);
		height: auto;
		aspect-ratio: 1;
	}

	/* Long addresses would otherwise overflow the narrower column. */
	.sfx-sidebar .wp-block-group:has(> .sfx-teacher-card) .sfx-teacher-card__email a {
		overflow-wrap: anywhere;
	}
}

/* Full-width page template */
.sfx-full-width-main {
	padding-block: var(--wp--preset--spacing--medium);
}

/* --------------------------------------------------------------------------
   Post Cards
   -------------------------------------------------------------------------- */

.sfx-post-card {
	background: var(--wp--preset--color--sfx-white);
	border: 1px solid var(--wp--custom--color--border);
	border-left: 4px solid var(--wp--preset--color--sfx-maroon);
	border-radius: var(--wp--custom--border-radius--card);
	padding: 16px;
	margin-bottom: 16px;
}

.sfx-post-card--announcement {
	border-left-color: var(--wp--preset--color--sfx-gold);
}

.sfx-post-card__body {
	flex: 1;
	min-width: 0;
}

.sfx-post-card__thumb {
	flex-shrink: 0;
	align-self: center;
	width: 100px;
}

.sfx-post-card__thumb img {
	display: block;
	width: 100px;
	height: 75px;
	object-fit: cover;
	border-radius: 3px;
}

.sfx-post-card__title {
	font-weight: 700;
	font-size: 1rem;
	margin: 0 0 6px;
}

.sfx-post-card__title a {
	color: #1a1a1a;
	text-decoration: none;
}

.sfx-post-card__title a:hover {
	text-decoration: underline;
}

.sfx-post-card__meta {
	font-size: 0.78rem;
	color: var(--wp--custom--color--text-muted);
	margin-bottom: 8px;
	gap: 8px;
	align-items: center;
}

.sfx-post-card__category {
	background: var(--wp--custom--color--border-subtle);
	border-radius: 3px;
	padding: 2px 7px;
	font-size: 0.72rem;
}

/*
 * `.sfx-post-card__category` lands on the link itself when rendered by the
 * Classroom Feed block, but on a wrapping <div> when rendered by core's
 * post-terms block (its className goes on the wrapper, not the <a> inside).
 * Cover both shapes so the category link looks and behaves the same
 * everywhere, regardless of the global link underline/hover styles.
 */
.sfx-post-card__category,
.sfx-post-card__category a {
	text-decoration: none;
}

.sfx-post-card__category:hover,
.sfx-post-card__category a:hover {
	text-decoration: underline;
}

/*
 * A school announcement's category reads as the announcement's label rather
 * than as one of a classroom's own topics, so it carries the maroon tint and
 * a bold label instead of the subtle gray pill. Both shapes are covered for
 * the same reason as above, and the link keeps the weight explicitly because
 * link styles elsewhere set one of their own.
 */
.sfx-post-card--announcement .sfx-post-card__category {
	background: var(--wp--preset--color--sfx-maroon-tint);
	font-weight: 700;
}

.sfx-post-card--announcement .sfx-post-card__category a {
	font-weight: 700;
}

.sfx-archive-title {
	font-weight: 700;
	margin-bottom: var(--wp--preset--spacing--small);
}

/* --------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */

.sfx-sidebar {
	font-size: 0.875rem;
}

.sfx-teacher-card {
	text-align: center;
	padding-bottom: 16px;
}

/*
 * Core's flow layout gives every child after the first a block-gap top
 * margin. A card brings its own spacing (the padding-bottom above), and the
 * margin actively breaks a row of them: the second card sat a block-gap
 * lower than the first, so their photos sat visibly out of line. Cards never
 * want it, in any layout.
 *
 * :not(.wp-block-group) exempts the authored wrapper in parts/sidebar.html,
 * which shares this class with the cards it holds. It also puts the selector
 * a class ahead of core's own, so this wins whichever order the two
 * stylesheets land in.
 */
.sfx-teacher-card:not(.wp-block-group) {
	margin-block-start: 0;
}

.sfx-teacher-card__photo {
	width: 160px;
	height: 160px;
	border-radius: 50%;
	object-fit: cover;
	margin: 0 auto 8px;
	display: block;
	background-color: var(--wp--preset--color--sfx-maroon);
}

.sfx-teacher-card__name {
	font-weight: 700;
	font-size: 0.8rem;
	margin: 0 0 2px;
}

.sfx-teacher-card__title {
	font-size: 0.625rem;
	color: var(--wp--preset--color--sfx-gray);
	margin: 0 0 4px;
}

.sfx-teacher-card__email {
	margin-block: 0;
}

.sfx-teacher-card__email a {
	font-size: 0.75rem;
	color: var(--wp--preset--color--sfx-maroon);
	text-decoration: underline;
}

.sfx-page-nav__label {
	font-size: 0.65rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--sfx-gray);
	margin-bottom: 8px;
}

.sfx-page-nav__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.sfx-page-nav__list li {
	margin: 0;
}

.sfx-page-nav__list a {
	display: block;
	padding: 5px 8px;
	border-left: 3px solid transparent;
	color: var(--wp--preset--color--sfx-maroon);
	text-decoration: underline;
	font-size: 0.82rem;
	line-height: 1.4;
}

.sfx-page-nav__list .current-menu-item a,
.sfx-page-nav__list .current_page_item a {
	border-left-color: var(--wp--preset--color--sfx-maroon);
	font-weight: 700;
	text-decoration: none;
}

/*
 * Shown in place of the photo when a user has no avatar, so it carries
 * .sfx-teacher-card__photo too and takes that rule's 160px and circle. It
 * used to override those with 72px, which left a card standing next to one
 * with a real photo looking misaligned -- most visible two per row on
 * mobile, but wrong wherever the two sit together. The initial is sized to
 * roughly a third of the circle, the proportion the 72px version used.
 */
.sfx-teacher-card__photo--fallback {
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background-color: var(--wp--preset--color--sfx-maroon);
	color: var(--wp--preset--color--sfx-white);
	font-weight: 700;
	font-size: 3.25rem;
	margin: 0 auto 8px;
}

.sfx-page-nav .wp-block-page-list,
.sfx-page-nav .wp-block-navigation__submenu-container {
	list-style: none;
	margin: 0;
	padding: 0;
}

.sfx-page-nav .wp-block-pages-list__item {
	list-style: none;
	margin: 0;
}

.sfx-page-nav .wp-block-pages-list__item__link {
	display: block;
	padding: 5px 8px;
	border-left: 3px solid transparent;
	color: var(--wp--preset--color--sfx-maroon);
	text-decoration: underline;
	font-size: 0.82rem;
	line-height: 1.4;
}

.sfx-page-nav .current-menu-item > .wp-block-pages-list__item__link,
.sfx-page-nav .current_page_item > .wp-block-pages-list__item__link {
	border-left-color: var(--wp--preset--color--sfx-maroon);
	font-weight: 700;
	text-decoration: none;
}

/* Indent child pages */
.sfx-page-nav .wp-block-navigation__submenu-container {
	padding-left: 16px;
	margin-top: 2px;
	margin-bottom: 2px;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.sfx-footer {
	background-color: var(--wp--preset--color--sfx-maroon);
	color: rgba(255,255,255,0.85);
}

.sfx-footer__main {
	padding-block: 36px;
	padding-inline: max(28px, calc((100% - var(--wp--style--global--wide-size)) / 2));
}

.sfx-footer__nav-groups {
	gap: 36px;
	align-items: flex-start;
}

.sfx-footer__nav-group-label.wp-block-heading {
	font-size: 0.65rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: rgba(255,255,255,0.45);
	margin-bottom: 12px;
	margin-top: 0;
}

/* Footer navigation links */
.sfx-footer__nav-group .wp-block-navigation a {
	color: rgba(255,255,255,0.9);
	text-decoration: none;
	font-size: 0.875rem;
	font-weight: 700;
}

.sfx-footer__nav-group .wp-block-navigation a:hover {
	text-decoration: underline;
}

.sfx-footer__nav-group .wp-block-navigation .wp-block-navigation__container {
	gap: 8px;
}

/* Footer contact column */
.sfx-footer__contact {
	flex-shrink: 0;
	text-align: right;
}

/* Footer logo */
.sfx-footer__logo img {
	height: 60px;
	width: auto;
	display: block;
	margin-left: auto;
	margin-bottom: 12px;
}

@media (max-width: 767px) {
	.sfx-footer__main {
		flex-direction: column;
		align-items: center;
		text-align: center;
		gap: 24px;
	}

	.sfx-footer__nav-groups {
		justify-content: center;
		padding-bottom: 24px;
		border-bottom: 1px solid rgba(255, 255, 255, 0.15);
		width: 100%;
	}

	.sfx-footer__nav-group .wp-block-navigation .wp-block-navigation__container {
		align-items: center;
	}

	.sfx-footer__contact {
		width: 100%;
		text-align: center;
	}

	.sfx-footer__logo {
		display: block;
		width: 100%;
		padding-bottom: 24px;
		border-bottom: 1px solid rgba(255, 255, 255, 0.15);
	}

	.sfx-footer__logo img {
		margin-inline: auto;
		margin-bottom: 0;
	}

	.sfx-footer__contact-lines {
		align-items: center;
	}

	.sfx-footer__bottom {
		flex-direction: column-reverse;
		align-items: center;
		gap: 6px;
		text-align: center;
	}
}

.sfx-footer__contact-lines {
	gap: 4px;
}

.sfx-footer__contact-lines p {
	font-size: 0.875rem;
	color: rgba(255,255,255,0.75);
	line-height: 1.6;
	margin: 0;
}

.sfx-footer__contact-lines a {
	color: rgba(255,255,255,0.75);
	text-decoration: underline;
}

.sfx-footer__bottom {
	background-color: var(--wp--custom--color--footer-dark);
	padding-block: 10px;
	padding-inline: max(28px, calc((100% - var(--wp--style--global--wide-size)) / 2));
}

.sfx-footer__copyright {
	font-size: 0.75rem;
	color: rgba(255,255,255,0.5);
	margin: 0;
}

/* Privacy Policy + Log Out links in the bottom bar */
.sfx-footer__bottom-links a {
	font-size: 0.75rem;
	color: rgba(255,255,255,0.5);
	text-decoration: none;
}

.sfx-footer__bottom-links a:hover {
	text-decoration: underline;
}

/*
 * The loginout block is not a navigation item. The nav block wraps its links
 * in .wp-block-navigation-item__content, which core colours with a doubled
 * class selector -- specificity core wins with, so those links inherit the
 * footer's 0.85 white and ignore the 0.5 set above. The loginout link sits
 * outside that container as a bare inline <a>, so it keeps the 0.5 and, being
 * inline, gets a box 3px shorter than its neighbour, which drops its text
 * below the same baseline.
 *
 * Match the neighbouring link rather than fight core for the 0.5: inherit the
 * same colour, and take a block box so both links are the same height in the
 * centred flex row.
 */
.sfx-footer__bottom-links .wp-block-loginout a {
	display: block;
	color: inherit;
}

/* --------------------------------------------------------------------------
   Login page
   -------------------------------------------------------------------------- */

/* Two notices share this callout style, and both print in the same place: the
   top of the page, as a wide block above the columns, so they span the same
   width as the content below them and the constrained layout's block gap
   spaces them from it. The plugin prints "please log in" there when the auth
   gate sent someone to the Log In page. It used to print inside the login
   card, where it could not be seen — the card is painted in this same maroon
   tint, and a callout cannot stand out against its own colour. The Logged Out
   Notice block prints "you have been logged out" on the home page. */
.sfx-login-notice {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
	border: 1px solid var(--wp--custom--color--border);
	border-left: 4px solid var(--wp--preset--color--sfx-maroon);
	border-radius: var(--wp--custom--border-radius--card);
	margin-bottom: 20px;
	padding: 12px 16px;
}

.sfx-login-notice--success {
	background-color: #edf7ee;
	border-left-color: #2e7d32;
}

.wp-block-sfx-logged-out-notice {
	margin-bottom: 0;
}

.sfx-login-notice__text {
	color: #1a1a1a;
	font-size: 0.875rem;
	font-weight: 700;
	margin: 0;
}

.sfx-login-page-main {
	padding-block: var(--wp--preset--spacing--medium);
}

/* The Log In page shares the home page's two-column layout: copy and sign-in
   tips on the left, the sign-in card on the right. The heading loses its top
   margin so it lines up with the top of the card beside it. */
.sfx-login-page__heading {
	margin-top: 0;
}

.sfx-login-tips li {
	margin-bottom: 0.5em;
}

/* The shortcode block runs GravityForms' markup through wpautop, which wraps
   the footer's hidden inputs in paragraphs and leaves a <br> after each one.
   GravityForms styles the footer as a flex row, so every one of those becomes
   a flex item: ~160px of empty space that squeezes the Login button down to a
   70px sliver stretched to the full height of the row. The inputs are hidden
   either way, so the wrapping is only ever damage. */
.sfx-login-form-wrap .gform_footer {
	display: block;
}

.sfx-login-form-wrap .gform_footer br,
.sfx-login-form-wrap .gchoice br {
	display: none;
}

.sfx-login-form-wrap .gform_footer p {
	margin: 0;
}

.sfx-login-card__heading {
	font-size: 1.2rem;
	font-weight: 700;
	margin-bottom: 16px;
}

.sfx-lost-password {
	font-size: 0.78rem;
	margin-top: 12px;
}

.sfx-lost-password a {
	color: var(--wp--preset--color--sfx-maroon);
}

/* --------------------------------------------------------------------------
   Featured image band (landing page, principal's desk, gallery)
   -------------------------------------------------------------------------- */

/* The Featured Image block renders nothing at all when a page has no featured
   image, but the group wrapping it still takes the top level block gap: 36px
   of empty space above the content. Every site on the network sets this image
   on its own front page, or does not, so collapse the wrapper until one is
   set. */
.sfx-page-title-wrap:not(:has(img)) {
	display: none;
}

/* --------------------------------------------------------------------------
   Logged-out landing page
   -------------------------------------------------------------------------- */

/*
 * Width and gutters come from the block markup, the same way PR #79 handled the
 * content+sidebar templates: a constrained group whose children are alignwide.
 * The parent theme sets useRootPaddingAwareAlignments, so core tags the group
 * with .has-global-padding and supplies the horizontal padding; the vertical
 * padding is a spacing-preset attribute on the group. Nothing is left for CSS.
 */

.sfx-principal-card {
	gap: 24px;
	margin-bottom: 24px;
	align-items: flex-start;
}

.sfx-principal-card .sfx-teacher-card {
	flex-shrink: 0;
	width: 200px;
}

.sfx-pull-quote {
	border-left: 4px solid var(--wp--preset--color--sfx-maroon);
	padding-inline-start: 20px;
	font-size: 1.05rem;
	font-style: italic;
}

/* Landing columns: the principal's letter on the left, sign-in on the right.
   The letter is a few hundred pixels taller than the card, so the card sticks
   and stays reachable the whole way down instead of scrolling off while
   someone reads. */
.sfx-landing-columns .sfx-login-form-wrap {
	position: sticky;
	top: 16px;
}

/* Core stacks columns at 781px. Stacked, the sign-in card leads: it is what
   people came to the page to do, and it would otherwise sit below the full
   letter and the photo. */
@media (max-width: 781px) {
	.sfx-landing-columns .sfx-login-column {
		order: -1;
	}

	.sfx-landing-columns .sfx-login-form-wrap {
		position: static;
	}
}

/* --------------------------------------------------------------------------
   Site home (logged-in landing page, all sites)
   -------------------------------------------------------------------------- */

.sfx-site-home-intro {
	gap: 24px;
	margin-bottom: 24px;
}

.sfx-site-home-intro__card {
	flex-shrink: 0;
	width: 200px;
}

.sfx-info-columns {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 20px;
	margin-top: 20px;
}

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

.sfx-faq-section {
	border: 1px solid var(--wp--custom--color--border);
	border-radius: var(--wp--custom--border-radius--card);
	padding: 16px;
}

/* Matches the .wp-block-accordion treatment below: same border color,
   same maroon-tint hover/open highlight on the heading, same 18px
   vertical rhythm. The Details block has no separate heading/panel
   elements like the newer Accordion block does, so the summary bleeds
   into the section's own 16px padding (negative margin) to get the same
   edge-to-edge highlighted row. */
.sfx-faq-section .wp-block-details {
	border-bottom: 1px solid var(--wp--custom--color--border);
}

.sfx-faq-section .wp-block-details:last-child {
	border-bottom: none;
}

.sfx-faq-section .wp-block-details summary {
	margin-inline: -16px;
	padding: 18px 16px;
	font-weight: 600;
	font-size: 0.875rem;
	cursor: pointer;
	list-style: none;
	display: flex;
	justify-content: space-between;
	align-items: center;
	transition: background-color 0.15s ease;
}

.sfx-faq-section .wp-block-details summary:hover,
.sfx-faq-section .wp-block-details[open] summary {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
}

.sfx-faq-section .wp-block-details summary::after {
	content: '›';
	font-size: 1.25rem;
	line-height: 1;
	color: var(--wp--preset--color--sfx-maroon);
	flex-shrink: 0;
	transform: rotate(90deg);
	display: inline-block;
	transition: transform 0.2s ease;
}

.sfx-faq-section .wp-block-details[open] summary::after {
	transform: rotate(270deg);
}

.sfx-faq-section .wp-block-details .wp-block-paragraph {
	font-size: 0.875rem;
	margin-top: 0;
	padding: 0 16px 18px;
	color: var(--wp--custom--color--text-muted);
}

/* Core Accordion block — card container with a clear visual boundary
   between the heading (clickable, always visible) and the panel (the
   "drawer" that expands underneath it). Applies everywhere the block is
   used, not just inside .sfx-faq-section, since core ships it with no
   borders or backgrounds at all. */
.wp-block-accordion {
	border: 1px solid var(--wp--custom--color--border);
	border-radius: var(--wp--custom--border-radius--card);
	overflow: hidden;
}

.wp-block-accordion .wp-block-accordion-item {
	border-bottom: 1px solid var(--wp--custom--color--border);
}

.wp-block-accordion .wp-block-accordion-item:last-child {
	border-bottom: none;
}

/* Core's generated block-gap gives every item a ~36px top margin, which
   stacks with the border above and looks far too spaced out. The
   border-bottom on each item already separates them, so only the first
   item (i.e. spacing above the whole block) should keep any top margin. */
.wp-block-accordion .wp-block-accordion-item + .wp-block-accordion-item {
	margin-top: 0 !important;
}

.wp-block-accordion .wp-block-accordion-heading__toggle {
	padding: var(--wp--preset--spacing--small) var(--wp--preset--spacing--medium);
	font-weight: 600;
	transition: background-color 0.15s ease;
}

.wp-block-accordion .wp-block-accordion-heading__toggle:hover,
.wp-block-accordion .wp-block-accordion-item.is-open > .wp-block-accordion-heading .wp-block-accordion-heading__toggle {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
}

.wp-block-accordion .wp-block-accordion-panel {
	/* Overrides WordPress's dynamically-generated block-gap margin between
	   the heading and panel (only reset to 0 when the panel is [hidden]),
	   which otherwise stacks with this padding for a much bigger gap than
	   intended. */
	margin-block-start: 0 !important;
	padding: 18px var(--wp--preset--spacing--medium);
	background-color: var(--wp--preset--color--sfx-white);
}

/* When collapsed, the panel carries hidden="until-found" (core's
   interactivity view.js) so it should render at zero height — but its own
   padding still counts toward the box's intrinsic size, leaving a visible
   18px sliver even while closed. Zero it out to match the [hidden]
   margin-block-start reset core already applies. */
.wp-block-accordion .wp-block-accordion-panel[hidden] {
	padding-block: 0;
}

/* Replace the default "+" icon, which rotates 45deg on open and reads as
   an "×" (close/remove) instead of a collapse indicator, with a chevron
   that flips to show open/closed state. */
.wp-block-accordion .wp-block-accordion-heading__toggle-icon {
	width: 1.2rem;
	height: 1.2rem;
	font-size: 0;
	position: relative;
}

.wp-block-accordion .wp-block-accordion-heading__toggle-icon::after {
	content: '›';
	font-size: 1.25rem;
	line-height: 1;
	color: var(--wp--preset--color--sfx-maroon);
	transform: rotate(90deg);
	transition: transform 0.2s ease-in-out;
}

.wp-block-accordion .wp-block-accordion-item.is-open > .wp-block-accordion-heading .wp-block-accordion-heading__toggle-icon {
	transform: none;
}

.wp-block-accordion .wp-block-accordion-item.is-open > .wp-block-accordion-heading .wp-block-accordion-heading__toggle-icon::after {
	transform: rotate(270deg);
}

.sfx-contact-card__label {
	font-size: 0.8rem;
	font-weight: 700;
	margin: 0 0 8px;
}

.sfx-contact-row {
	gap: 8px;
	align-items: baseline;
	padding: 6px 0;
	border-bottom: 1px solid var(--wp--custom--color--border-subtle);
	font-size: 0.85rem;
}

.sfx-contact-row:last-child {
	border-bottom: none;
}

.sfx-contact-row__label {
	font-weight: 600;
	min-width: 50px;
	color: var(--wp--custom--color--text-muted);
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   Mobile — intro section (site-home and logged-out landing page)
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
	.sfx-site-home-intro,
	.sfx-principal-card {
		flex-direction: column;
	}

	/* Quote/message first, then photo */
	.sfx-site-home-intro .sfx-pull-quote,
	.sfx-principal-card .sfx-pull-quote {
		order: 1;
		padding-inline-start: 0;
		border-left: none;
		border-top: 4px solid var(--wp--preset--color--sfx-maroon);
		padding-top: 16px;
	}

	.sfx-site-home-intro__card,
	.sfx-principal-card .sfx-teacher-card {
		order: 2;
		width: 100%;
	}
}

/* --------------------------------------------------------------------------
   Sidebar page navigation — suppress browser list bullets
   -------------------------------------------------------------------------- */

.sfx-page-nav .wp-block-page-list,
.sfx-page-nav .wp-block-page-list ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.sfx-page-nav .wp-block-page-list li {
	list-style: none;
}

/* --------------------------------------------------------------------------
   Table block
   -------------------------------------------------------------------------- */

.wp-block-table table {
	border: 1px solid var(--wp--custom--color--border);
	border-collapse: collapse; /* required when outer border is present */
	font-size: 0.875rem;
}

.wp-block-table td,
.wp-block-table th {
	border-bottom: 1px solid var(--wp--custom--color--border);
}

.wp-block-table th,
.wp-block-table thead tr {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
}

.wp-block-table tfoot td {
	border-bottom: none;
	border-top: 1px solid var(--wp--custom--color--border);
}

.wp-block-table.is-style-stripes tbody tr:nth-child(odd) {
	background-color: var(--wp--preset--color--sfx-maroon-tint);
}

/* --------------------------------------------------------------------------
   Login form card — maroon tint treatment

   The card used to be a solid maroon block with gold links. Reversed out like
   that, the two smallest pieces of text failed WCAG AA badly: GravityForms'
   red "(Required)" landed at 1.39:1 against the maroon, and gold links at
   3.33:1. On the maroon tint already used for the note and table stripes,
   everything clears AA — body text 15.19:1, maroon headings and links 7.10:1.
   -------------------------------------------------------------------------- */

.sfx-login-form-wrap {
	background: var(--wp--preset--color--sfx-maroon-tint);
	color: #1a1a1a;
	border: 1px solid rgba(132, 52, 77, 0.25);
	border-radius: var(--wp--custom--border-radius--card);
	padding: 28px 32px;
}

.sfx-login-form-wrap .sfx-login-card__heading,
.sfx-login-form-wrap h2 {
	color: var(--wp--preset--color--sfx-maroon);
	margin-top: 0;
}

.sfx-login-form-wrap p {
	color: #1a1a1a;
	margin-bottom: 20px;
}

/* GravityForms login form inside the card */
.sfx-login-form-wrap .gform_wrapper label,
.sfx-login-form-wrap .gform_wrapper .gfield_label {
	color: var(--wp--preset--color--sfx-maroon);
	font-weight: 600;
	font-size: 0.875rem;
}

/* GravityForms marks required fields in its own red, which carries no meaning
   here — both fields are required. Inheriting the label color keeps it as a
   quiet qualifier; 85% opacity holds it at 5.07:1, still above AA. The colour
   is set from a plugin rule this cannot outrank on specificity alone. */
.sfx-login-form-wrap .gform_wrapper .gfield_required {
	color: inherit !important;
	opacity: 0.85;
	font-weight: 400;
}

/* #6f6f6f rather than the palette gray: a field border is a UI component and
   needs 3:1, and #939393 sits at 3.07:1, too close to the line to rely on.

   The vertical metrics are set here rather than left to the browser, because
   engines disagree about where an input's text goes when the box is taller
   than the line. Chromium and WebKit centre the text in the content box;
   Firefox lays it out as an ordinary line box anchored to the top, so anything
   relying on that centring reads high there.

   22px line-height + 7px padding + 1px borders is exactly the 38px control
   size, so the content box is precisely one line tall. There is no leftover
   space for an engine to distribute, and the text lands in the same place in
   all of them. Adjust the three numbers together or not at all. */
.sfx-login-form-wrap .gform_wrapper input[type="text"],
.sfx-login-form-wrap .gform_wrapper input[type="email"],
.sfx-login-form-wrap .gform_wrapper input[type="password"] {
	background: var(--wp--preset--color--sfx-white);
	border: 1px solid #6f6f6f;
	border-radius: var(--wp--custom--border-radius--card);
	color: #1a1a1a;
	height: auto;
	min-height: 38px;
	line-height: 22px;
	padding: 7px 14px;
	width: 100%;
	font-size: 1rem;
}

.sfx-login-form-wrap .gform_wrapper input[type="text"]::placeholder,
.sfx-login-form-wrap .gform_wrapper input[type="email"]::placeholder,
.sfx-login-form-wrap .gform_wrapper input[type="password"]::placeholder {
	color: var(--wp--custom--color--text-muted);
}

.sfx-login-form-wrap .gform_wrapper input[type="text"]:focus,
.sfx-login-form-wrap .gform_wrapper input[type="email"]:focus,
.sfx-login-form-wrap .gform_wrapper input[type="password"]:focus {
	outline: 2px solid var(--wp--preset--color--sfx-maroon);
	outline-offset: 2px;
}

/* GravityForms' framework paints the button from selectors whose :not() chains
   outrank anything reasonable written here — a five class selector still loses,
   which is why the button rendered as the plugin's default blue at 70px wide.
   These four declarations are the ones it fights over, so they carry
   !important; the rest cascade normally. */
.sfx-login-form-wrap .gform_wrapper input[type="submit"],
.sfx-login-form-wrap .gform_wrapper .gform_button {
	background-color: var(--wp--preset--color--sfx-maroon) !important;
	color: var(--wp--preset--color--sfx-white) !important;
	border: none !important;
	width: 100% !important;
	border-radius: var(--wp--custom--border-radius--card);
	padding: 12px 24px;
	font-weight: 700;
	font-size: 1rem;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.sfx-login-form-wrap .gform_wrapper input[type="submit"]:hover,
.sfx-login-form-wrap .gform_wrapper .gform_button:hover {
	background-color: var(--wp--custom--color--footer-dark) !important;
}

/* Links inside the login card (forgot password, etc.) */
.sfx-login-form-wrap a,
.sfx-login-form-wrap .gform_wrapper a {
	color: var(--wp--preset--color--sfx-maroon);
}

/* GravityForms' own footer margin is unreliable here, and the button used to
   sit hard against the Remember Me row. */
.sfx-login-form-wrap .gform_wrapper .gform_footer {
	margin-top: 20px;
}

.sfx-login-form-wrap .gform_wrapper .gform_ajax_spinner {
	margin-top: 0;
}

/* The h2 above the form already says "Sign In"; GravityForms' own form title
   is a second heading for the same thing. */
.sfx-login-form-wrap .gform_heading {
	display: none;
}

/* The card reads as one unit, so it uses a tighter rhythm than the 36px core
   puts between every child of a flow layout. */
.sfx-login-form-wrap.is-layout-flow > * + * {
	margin-block-start: 16px;
}

.sfx-login-form-wrap .gform_fields {
	row-gap: 20px;
}

/* "Remember Me" is a checkbox and its label, which wpautop separated with a
   <br> (hidden above) and GravityForms styles with appearance: none but no
   border of its own — a white square that reads as neither checked nor
   checkable. Handing it back to the platform makes it unmistakably a checkbox,
   and accent-color keeps it on brand. */
.sfx-login-form-wrap .gchoice {
	display: flex;
	align-items: center;
	gap: 8px;
}

.sfx-login-form-wrap .gform_wrapper input[type="checkbox"] {
	appearance: auto;
	accent-color: var(--wp--preset--color--sfx-maroon);
	width: 16px;
	height: 16px;
	margin: 0;
	flex: none;
	cursor: pointer;
}

/* An option, not a field heading: body colour and weight rather than the
   maroon 600 the Email and Password labels use. */
.sfx-login-form-wrap .gchoice label {
	color: #1a1a1a;
	font-size: 0.875rem;
	font-weight: 400;
	margin: 0;
	cursor: pointer;
}

/* Validation messages ("This field is required.", "Unknown email address.")
   sit under the field they belong to; bold so they stand out from the labels
   and the checkbox text around them, which GravityForms sets at the same size.
   Core wraps "Error:" and the attempted username in <strong>, which the parent
   theme sets to semi-bold, so those would otherwise read lighter than the rest
   of the message. */
.sfx-login-form-wrap .gfield_validation_message {
	font-weight: 700;
}

.sfx-login-form-wrap .gfield_validation_message strong {
	font-weight: inherit;
}

/* Secondary to the Login button, and matched to the note below it. */
.sfx-login-form-wrap .gf_login_links {
	font-size: 0.8rem;
	text-align: right;
}

/* --------------------------------------------------------------------------
   Photo gallery page template
   -------------------------------------------------------------------------- */

.sfx-gallery-main {
	padding-block: var(--wp--preset--spacing--medium);
}

.sfx-gallery-main .wp-block-gallery {
	margin-bottom: var(--wp--preset--spacing--large);
}

.sfx-gallery-main .wp-block-gallery .wp-block-image img {
	border-radius: var(--wp--custom--border-radius--card);
	object-fit: cover;
}

