/* =============================================================================
   Accordion (acf/accordion) — DY-to-Dev Figma node 2003:376
   Full-bleed section, no inner box: the section itself carries the background.
   with-image  → 50/50 grid; `grid-template-rows: 1fr auto` drops the list to
                 the bottom of the copy column so it stays flush with the photo,
                 and the media stretches past its ratio when the copy is taller.
   no-image    → single column, list capped at 75%, media hidden (dimmed in the
                 editor canvas so it doesn't look deleted).
   Divider + the +/- glyph are currentColor (50% for the rule); the ring is lime
   on every background — designer to confirm on light backgrounds.
   ============================================================================= */

.accordion--block {
	/* Default gutter — the theme's blockGap, same as every other grid/flex
	   container. With the list capped at 600px the leftover slack in the copy
	   column adds to this, landing close to the comp's ~96px visual gap. */
	--accordion-gutter: var(--wp--style--block-gap, 24px);
	--accordion-list-gap: 60px;   /* copy → list; desktop overrides to 120px */
	--accordion-list-max: 600px;  /* with-image only */
	--accordion-icon-size: 31px;
	--accordion-icon-gap: 24px;
	--accordion-ring: var(--wp--preset--color--lime, #c3d941);
	--accordion-rule: color-mix(in srgb, currentColor 50%, transparent);
	--accordion-item-pad: 26px;
	--accordion-panel-max: 950px;
	--accordion-speed: 300ms;

	padding-top: 60px;
	padding-bottom: 60px;
}

@media (min-width: 756px) {
	.accordion--block {
		padding-top: 90px;
		padding-bottom: 90px;
	}
}

/* --- grid ------------------------------------------------------------------
   Mobile order is copy → list → image (client request). NOTE: the DOM order is
   copy → image → list, because ACF allows exactly one <InnerBlocks> insertion
   point and the media group has to sit next to the copy group inside it. The
   divergence is a knowing tradeoff — see CLAUDE.md. It only becomes a focus
   order issue when the media tile is focusable, which acf/media only is when a
   caption is set (it is otherwise a plain <div>), so leave accordion captions
   empty unless you accept that. */
.accordion--grid {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-areas:
		"copy"
		"list"
		"media";
	row-gap: 0; /* copy → list spacing is an explicit margin, see below */
}

/* ACF wraps InnerBlocks in an .acf-innerblocks-container div on the FRONT END
   as well as in the canvas (verified) — without display:contents the copy and
   media groups are not grid items and every grid-area placement is ignored. */
.accordion--grid > .acf-innerblocks-container {
	display: contents;
}

.accordion--grid .accordion--copy  { grid-area: copy;  min-width: 0; }
.accordion--grid .accordion--media { grid-area: media; min-width: 0; }
.accordion--grid .accordion--list  { grid-area: list;  min-width: 0; }

/* Copy → list separation is an explicit margin (not space-between): the copy
   column sizes the block, the list just sits a fixed distance below it. */
.accordion--list {
	margin-top: var(--accordion-list-gap);
}

.accordion--media {
	margin-top: 40px; /* mobile only — the image is last in the stack */
}

@media (min-width: 756px) {
	.accordion--block {
		--accordion-list-gap: 120px;
	}

	.accordion--layout-with-image .accordion--grid {
		grid-template-columns: 1fr 1fr;
		grid-template-areas:
			"copy media"
			"list media";
		column-gap: var(--accordion-gutter);
	}

	/* The copy column drives the block height; the photo keeps its own aspect
	   ratio and simply sits on the bottom edge of the column. */
	.accordion--layout-with-image .accordion--media {
		align-self: end;
		margin-top: 0;
	}

	.accordion--layout-with-image .accordion--list {
		max-width: var(--accordion-list-max);
	}
}

/* --- no-image --------------------------------------------------------------
   The media group stays in the block (the scaffold is locked), it just isn't
   output. In the canvas it stays visible but dimmed so an editor can see their
   image is still there rather than assuming it was deleted. */
.accordion--layout-no-image .accordion--media {
	display: none;
}

/* Capped: with no image the grid is a single full-width column, so an
   unconstrained portrait tile renders ~1250x1700 in the canvas and buries the
   rest of the block. This is a disabled preview, not content — keep it small. */
.editor-styles-wrapper .accordion--layout-no-image .accordion--media {
	display: block;
	opacity: 0.35;
	position: relative;
	max-width: 240px;
}
.editor-styles-wrapper .accordion--layout-no-image .accordion--media::before {
	content: "Not shown — layout is set to “Without Image”";
	display: block;
	margin-bottom: 8px;
	font-size: 13px;
	font-style: italic;
	letter-spacing: 0.02em;
}

@media (min-width: 756px) {
	.accordion--layout-no-image .accordion--list {
		max-width: 75%;
	}
}

/* --- media -----------------------------------------------------------------
   The tile keeps its own aspect ratio — it is NOT stretched to the copy column.
   min-width:0 is load-bearing: `aspect-ratio` resolves in both directions, so
   any rule that gives the tile a definite height (a previous `min-height:100%`
   stretch did) makes aspect-ratio compute a min-content WIDTH from it, which a
   grid track cannot shrink below — that was a 266px horizontal scrollbar just
   above 756px. Keep height off this element. */
.accordion--media,
.accordion--media .media--figure,
.accordion--media .media--media {
	min-width: 0;
}

/* --- list ------------------------------------------------------------------
   Rule between items only: none above the first, none below the last. */
.accordion--item + .accordion--item {
	border-top: 1px solid var(--accordion-rule);
}

/* Type comes from theme.json's styles.elements.h3 on the native <h3> — do not
   restate the scale here. The button below inherits it via `font: inherit`. */
.accordion--item-title {
	margin: 0;
}

.accordion--trigger {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--accordion-icon-gap);
	width: 100%;
	margin: 0;
	padding: var(--accordion-item-pad) 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	letter-spacing: inherit;
	text-align: left;
	cursor: pointer;
}

.accordion--trigger-text {
	min-width: 0;
}

/* Focus indication: the ⊕ disc fills solid lime, the glyph flips to green.
   No outline anywhere.

   BOTH pseudo-classes are needed. `reset.min.css` carries normalize's
   `button:focus{outline:-webkit-focus-ring-color auto 5px}` (0,1,1) — on a
   MOUSE click `:focus-visible` never matches, so a `:focus-visible`-only reset
   leaves that ring as the last rule standing and the row gets a browser
   outline. `.accordion--trigger:focus` (0,2,0) outranks it in both cases.
   The lime fill stays on :focus-visible so mouse users don't get a stuck
   highlight, while keyboard users keep a clear indicator (lime on green ~8:1,
   well past the 3:1 WCAG 2.4.11 non-text minimum). */
.accordion--trigger:focus,
.accordion--trigger:focus-visible {
	outline: none;
}
.accordion--trigger:focus-visible .accordion--icon-ring {
	fill: var(--accordion-ring);
}
.accordion--trigger:focus-visible .accordion--icon-bar {
	fill: var(--wp--preset--color--green, #1a3d39);
}

.accordion--icon-ring,
.accordion--icon-bar {
	transition: fill 150ms ease;
}

@media (prefers-reduced-motion: reduce) {
	.accordion--icon-ring,
	.accordion--icon-bar {
		transition: none;
	}
}

/* --- icon ------------------------------------------------------------------
   Ring is lime; the +/- strokes take currentColor so they follow the copy. */
.accordion--icon {
	flex: none;
	display: block;
	width: var(--accordion-icon-size);
	height: var(--accordion-icon-size);
}
.accordion--icon svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}
.accordion--icon-ring {
	fill: none;
	stroke: var(--accordion-ring);
	stroke-width: 1;
}
.accordion--icon-bar {
	fill: currentColor;
}
/* The vertical bar rotates onto the horizontal one, so + morphs into −.
   Rects rather than lines: a <line> has a zero-width fill box, which makes
   transform-box: fill-box degenerate (and unreliable in Safari). */
.accordion--icon-bar-v {
	transform-box: fill-box;
	transform-origin: center;
	transition: transform 200ms ease;
}
.accordion--item.is-open .accordion--icon-bar-v {
	transform: rotate(90deg);
}

/* --- panel -----------------------------------------------------------------
   0fr → 1fr animates to auto height with no JS measurement. The collapsed state
   is carried by `hidden="until-found"` (set in PHP, toggled by accordion.js),
   which is what keeps closed content out of the tab order and the a11y tree
   while still being reachable by browser find-in-page. */
.accordion--panel {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows var(--accordion-speed) ease;
}
.accordion--panel > .accordion--panel-inner {
	overflow: hidden;
	min-height: 0;
}
.accordion--item.is-open .accordion--panel {
	grid-template-rows: 1fr;
}

/* `hidden` is what keeps a closed panel out of the tab order and the a11y tree.
   Do NOT blanket-override it — that would leave links in closed panels tabbable
   while invisible. accordion.js removes the attribute a frame before opening.

   BUT: reset.min.css ships normalize's `[hidden]{display:none!important}`, which
   outranks the UA rule that gives `hidden="until-found"` its whole point
   (content-visibility:hidden instead of display:none). Left alone, find-in-page
   can never reveal a closed panel and `beforematch` never fires. Restoring it
   needs !important to beat the reset — sanctioned here, it IS a vendor override.

   Scoped to @supports so browsers without content-visibility keep the reset's
   display:none and stay safely hidden rather than collapsed-but-focusable. */
@supports (content-visibility: hidden) {
	.accordion--panel[hidden="until-found"] {
		display: grid !important;
		content-visibility: hidden;
	}
}

/* Keep body copy clear of the icon lane; the panel is the full row width, so
   without this the text runs under the ⊕ on narrow screens. */
.accordion--panel-inner {
	padding-right: calc(var(--accordion-icon-size) + var(--accordion-icon-gap));
}
.accordion--panel-inner > * {
	max-width: var(--accordion-panel-max);
}
.accordion--panel-inner > *:first-child {
	margin-top: 0;
}
.accordion--panel-inner > *:last-child {
	margin-bottom: 0;
	padding-bottom: var(--accordion-item-pad);
}

.accordion--empty {
	margin: 0;
	opacity: 0.7;
	font-style: italic;
}

/* --- derived color scheme --------------------------------------------------
   Cream copy on the dark backgrounds unless the editor picked a text color.
   The :not() guard is what lets the native text control win when it is used. */
.accordion--block.has-green-background-color:not(.has-text-color),
.accordion--block.has-black-background-color:not(.has-text-color) {
	color: var(--wp--preset--color--cream, #efede6);
}

/* Editor canvas bridge: ACF renders the block's own markup INSIDE the editor's
   wrapper div, so get_block_wrapper_attributes()' has-*-background-color lands
   on that parent instead of on .accordion--block. Without this the canvas shows
   near-black copy on the green band while the front end is correctly cream.
   Scoped to .acf-block-preview (canvas-only) so it can't leak to the front end
   or misfire on an accordion nested inside some other coloured group. */
.acf-block-preview.has-green-background-color:not(.has-text-color) .accordion--block,
.acf-block-preview.has-black-background-color:not(.has-text-color) .accordion--block {
	color: var(--wp--preset--color--cream, #efede6);
}

/* --- motion ---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.accordion--panel,
	.accordion--icon-bar-v {
		transition: none;
	}
}

/* --- editor canvas ---------------------------------------------------------
   accordion.js bails inside .editor-styles-wrapper, so panels render expanded
   (PHP omits `hidden` in preview) and the triggers are inert. */
.editor-styles-wrapper .accordion--trigger {
	pointer-events: none;
}
