/**
 * Front-end styles for the document template block's collection wrapper.
 *
 * These rules apply the "list" layout's marker options deterministically,
 * replacing the previous reliance on core's Query Loop stylesheet (whose
 * selectors never matched this block's classnames).
 *
 * Two rules govern everything below.
 *
 * 1. **Every selector sits inside `:where()`, so the whole stylesheet has
 *    zero specificity.** These are defaults, not decisions. Anything the
 *    author sets in the editor -- a border color, padding, a font size --
 *    arrives as a core block-support class at specificity (0,1,0), which
 *    beats (0,0,0) without needing `!important` or a longer selector. The
 *    same goes for a theme wanting a different look. Raising the specificity
 *    of any rule here would take that override away, so don't.
 *
 *    The cost is that source order, not specificity, now decides which of
 *    *our own* rules wins when two match the same element. That is
 *    deliberate but load-bearing: the narrower rule has to come later in the
 *    file. Each place that depends on it says so.
 *
 * 2. **Every color is mixed out of `currentColor`** rather than written as a
 *    literal, so these blocks take on whatever text color the theme sets and
 *    stay legible on a dark background without a `prefers-color-scheme`
 *    branch or an `.is-dark-theme` special case.
 *
 * Generic classnames (`is-document-layout-*`, `is-child-*`,
 * `is-collapsible-list`) are additionally scoped to this block's own class.
 *
 * Those layout classes were once named `is-layout-grid`/`-table`/`-list`,
 * and `is-layout-grid` is a *core* layout classname -- core emits it for any
 * block with `layout: { type: "grid" }`. Sharing that namespace leaked in
 * both directions. Outward: an unscoped rule here restyled unrelated core
 * blocks on any page that also held a collection. Inward, and far quieter:
 * core's own `:root :where(.is-layout-grid) { gap: ... }` sits at (0,1,0),
 * so once these rules dropped to zero specificity it silently won the grid's
 * gap -- the block's own Block spacing setting could never take effect, and
 * the hardcoded 16px default it appeared to honor was really the theme's
 * 1rem coming through core's rule. The classes carry their own name now.
 *
 * Class names already carrying the `document-blocks` prefix are unique on
 * their own and are left unscoped.
 *
 * The plugin ships a `theme.json` into the blocks layer of global styles
 * (src/ThemeJson.php). None of the declarations below can move there:
 *
 * - Structured properties (`spacing`, `typography`) land on the block's
 *   *root* at `:root :where(...)` -- (0,1,0). The root reset below must
 *   stay at (0,0,0) beneath the marker and layout paddings that narrow it
 *   by source order, and `spacing.blockGap` emits nothing at all for a
 *   block without core layout support -- the gap here is custom plumbing
 *   through `--document-blocks-block-gap`.
 * - Everything else is keyed to a layout, marker, state or style-variation
 *   class, which only theme.json's `css` property could express -- and a
 *   theme setting its own `css` string for this block replaces the
 *   plugin's wholesale. Table chrome, markers, the collapse toggle and the
 *   palette custom properties are load-bearing; none may vanish that way.
 *
 * The custom-property layer below therefore remains how a theme gets a say
 * without touching a single selector.
 */

/*
 * There is deliberately no accent color here. The only things that used one
 * were a border on the grid's child cards and one on the table's spanning
 * detail row -- decoration drawn on generated wrappers, now removed in favor
 * of the author's own blocks. What remains is the small amount of chrome
 * that has nowhere else to live: the muted text of a table header, a rule
 * between table cells, the striped rows of a table style.
 */
:where(.wp-block-document-blocks-template) {
	--document-blocks-border: color-mix(in srgb, currentColor 18%, transparent);
	--document-blocks-faint: color-mix(in srgb, currentColor 45%, transparent);
	--document-blocks-muted: color-mix(in srgb, currentColor 65%, transparent);
	--document-blocks-surface: color-mix(in srgb, currentColor 5%, transparent);

	margin: 0;
	padding: 0;
}

:where(.wp-block-document-blocks-template.has-markers-none) {
	list-style: none;
}

/*
 * A marker-less nested list with no child template would otherwise render
 * flush against its parent -- no indent conveying depth, no gap above --
 * since the bulleted/numbered indents live on the marker rules and the
 * generated wrapper carries no styling of its own. These are fallback
 * defaults for exactly that case: the same block-gap chain every item
 * already uses for the gap above, and a 1em depth indent (em, so the
 * indent follows the nested list's own type size).
 *
 * `has-child-template` (set by DocumentTemplate::render_documents() and
 * mirrored by the editor canvas) opts the wrapper out: once a child
 * template governs nested documents, its own spacing and padding settings
 * are the whole story, and defaults underneath them would stack. Zero
 * specificity throughout -- `:where()` stays (0,0,0) no matter what it
 * contains -- so a theme overrides this with any ordinary rule.
 */
:where(.wp-block-document-blocks-template.has-markers-none .wp-block-document-blocks-template.has-markers-none:not(.has-child-template)) {
	margin-block-start: var(
		--document-blocks-block-gap,
		var(--wp--style--block-gap, 0.75em)
	);
	padding-inline-start: 1em;
}

:where(.wp-block-document-blocks-template.has-markers-bulleted) {
	list-style: disc;
	padding-inline-start: 1.5em;
}

:where(.wp-block-document-blocks-template.has-markers-bulleted .wp-block-document-blocks-template.has-markers-bulleted) {
	list-style: circle;
	padding-inline-start: 1.5em;
	margin-block-start: 0.5em;
}

/*
 * Numbered markers step through the conventional outline sequence --
 * decimal, then lower-alpha, then lower-roman (1. > a. > i.), the same
 * scheme word processors default nested ordered lists to -- because CSS
 * itself does not: every <ol> level renders decimal, and "1." nested under
 * "1." reads as a numbering mistake rather than a deeper level. All at zero
 * specificity, so a theme preferring a different scheme overrides each
 * level with any ordinary rule.
 *
 * Order-dependent: each deeper level narrows the one before it.
 */
:where(.wp-block-document-blocks-template.has-markers-numbered) {
	list-style: decimal;
	padding-inline-start: 1.75em;
}

:where(.wp-block-document-blocks-template.has-markers-numbered .wp-block-document-blocks-template.has-markers-numbered) {
	list-style: lower-alpha;
	padding-inline-start: 1.75em;
	margin-block-start: 0.5em;
}

:where(.wp-block-document-blocks-template.has-markers-numbered .wp-block-document-blocks-template.has-markers-numbered .wp-block-document-blocks-template.has-markers-numbered) {
	list-style: lower-roman;
}

/*
 * Block spacing between consecutive documents. This mirrors core's
 * default-layout block gap -- a margin between adjacent siblings, so the
 * first and last document need no reset -- and reads
 * --document-blocks-block-gap, which each wrapper sets from its own Block
 * spacing control: the collection root for the default template, and the
 * __children wrapper for a child template (see
 * DocumentTemplate::get_block_gap_style(), now emitted onto both). A child
 * template's spacing therefore governs the documents nested beneath a
 * parent, independently of the spacing between the top-level ones.
 *
 * Unset, it falls through to the theme's theme.json block gap, and only
 * then to a default of ours.
 */
:where(.wp-block-document-blocks-template__item + .wp-block-document-blocks-template__item) {
	margin-block-start: var(
		--document-blocks-block-gap,
		var(--wp--style--block-gap, 0.75em)
	);
}

:where(.wp-block-document-blocks-template.is-document-layout-grid) {
	display: grid;
	gap: var(--document-blocks-block-gap, var(--wp--style--block-gap, 16px));
	/*
	 * The full value is computed in one place -- see
	 * DocumentTemplate::grid_template_columns() and its JS mirror -- and
	 * handed in through this property, so the three grid modes (a max, a min
	 * width, or both) stay identical across CSS, the editor and the front
	 * end. The fallback matches a fresh collection: fit columns at least
	 * 12rem wide.
	 */
	grid-template-columns: var(
		--document-blocks-grid-template-columns,
		repeat(auto-fill, minmax(min(12rem, 100%), 1fr))
	);
}

@media (max-width: 600px) {
	:where(.wp-block-document-blocks-template.is-document-layout-grid) {
		grid-template-columns: 1fr;
	}
}

/*
 * A grid item carries no card chrome of its own -- no border, no radius, no
 * padding. The wrapper it draws is generated markup the author cannot select,
 * so any look imposed here is a look they cannot change; and it fights what
 * they *can* reach, since our padding would sit outside the padding of
 * whatever block they put inside it. The card is theirs to build: wrap the
 * template's blocks in a Group and style that, exactly as core's Query Loop
 * expects. All that remains here is the spacing the grid itself requires --
 * `gap` owns the space between the grid's own direct items, so the sibling
 * margin-block-start those items would otherwise pick up has to go. Nested
 * lists inside a card are not direct grid children and keep that spacing.
 */
:where(.wp-block-document-blocks-template.is-document-layout-grid > .wp-block-document-blocks-template__item) {
	margin-block-start: 0;
}

/*
 * A grid card holding nested documents becomes a grid of its own: one 1fr
 * row for the parent document's own blocks, and the nested list dropping
 * into the implicit row beneath it.
 *
 * The card already stretches to its row's height, so without this the
 * nested list sits immediately under however tall the parent's content
 * happens to be, and lands at a different height in every card. Giving the
 * first row 1fr makes the parent's content take up the slack instead, so
 * the nested lists line up along the bottom of the row.
 *
 * `:has(>)` rather than a descendant match: only a card that directly holds
 * a nested list should become a grid. Deeper levels nest inside that list,
 * and the sequential children mode has no `__children` wrapper at all, so
 * this correctly never matches there.
 *
 * Order-dependent: narrows the rule above.
 */
:where(
	.wp-block-document-blocks-template.is-document-layout-grid
		> .wp-block-document-blocks-template__item:has(
			> .wp-block-document-blocks-template__children
		)
) {
	display: grid;
	grid-template-rows: 1fr;
}

:where(.wp-block-document-blocks-template.is-document-layout-table) {
	border-collapse: collapse;
	width: 100%;
}

:where(.wp-block-document-blocks-template.is-document-layout-table th[scope="col"]) {
	border-bottom: 2px solid currentColor;
	color: var(--document-blocks-muted);
	font-size: 0.75em;
	letter-spacing: 0.02em;
	padding: 8px 10px;
	text-align: start;
	text-transform: uppercase;
}

:where(.wp-block-document-blocks-template.is-document-layout-table td),
:where(.wp-block-document-blocks-template.is-document-layout-table th[scope="row"]) {
	border-bottom: 1px solid var(--document-blocks-border);
	font-weight: normal;
	padding: 10px;
	text-align: start;
}

/* Order-dependent: narrows the cell padding set immediately above. */
:where(.wp-block-document-blocks-template .is-child-row th[scope="row"]) {
	padding-inline-start: calc(10px + (var(--document-blocks-row-depth, 1) * 24px));
}

/*
 * The table layout's spanning detail row: when
 * the collection has a children-role template, a nested document renders as
 * a single, full-width cell holding that template's own blocks instead of
 * column-aligned cells. There is no first-cell <th> here to carry the depth
 * indent the column-aligned fallback row uses, so the cell itself picks up
 * the same --document-blocks-row-depth custom property instead.
 *
 * Only that indent remains -- the tint and accent border this once drew are
 * the children-role template's business, and it has full color and border
 * supports to draw them with.
 *
 * Order-dependent: narrows the generic cell rule above.
 */
:where(.wp-block-document-blocks-template .is-child-detail-row td) {
	padding-inline-start: calc(10px + (var(--document-blocks-row-depth, 1) * 24px));
}

/*
 * Table layout's disclosure column: a narrow leading column holding only the
 * chevron toggle, so the title cell stays free for the title link and its
 * child count.
 */
:where(.document-blocks-disclosure-col) {
	padding-inline-end: 0;
	width: 28px;
}

/*
 * The table itself scrolls horizontally rather than the page, so a wide
 * table (many columns on a narrow viewport) never causes horizontal page
 * scroll.
 */
@media (max-width: 600px) {
	:where(.wp-block-document-blocks-template.is-document-layout-table) {
		display: block;
		overflow-x: auto;
	}
}

/*
 * Collapsible children toggle: a leading chevron in the list layout, and a
 * dedicated disclosure column in the table layout. The grid layout never
 * renders this button. Borderless by design: no chip, no background, just a
 * muted chevron.
 */
:where(.document-blocks-collapse-toggle) {
	align-items: center;
	background: none;
	border: none;
	color: var(--document-blocks-muted);
	cursor: pointer;
	display: inline-flex;
	gap: 4px;
	padding: 2px;
}

/*
 * The chevron is a CSS triangle (the classic zero-size, transparent-borders
 * trick) rather than a glyph, drawn in currentColor so it always matches the
 * toggle's muted text color. Logical properties mean it points toward the
 * inline-end edge (right in LTR, left in RTL) at rest, matching the
 * disclosure-arrow convention in both directions.
 */
:where(.document-blocks-collapse-icon) {
	border-block-end: 4px solid transparent;
	border-block-start: 4px solid transparent;
	border-inline-start: 5px solid currentColor;
	display: inline-block;
	height: 0;
	transform: rotate(90deg);
	transition: transform 0.15s ease;
	width: 0;
}

/*
 * The toggle renders collapsed (aria-expanded="false") on the server, so the
 * chevron starts in its unrotated orientation, pointing toward the
 * inline-end edge. Expanding (aria-expanded="true", set by view.js on click)
 * rotates it down.
 *
 * Order-dependent: overrides the resting rotation set above.
 */
:where(.document-blocks-collapse-toggle[aria-expanded="false"] .document-blocks-collapse-icon) {
	transform: rotate(0deg);
}

@media (prefers-reduced-motion: reduce) {
	:where(.document-blocks-collapse-icon) {
		transition: none;
	}
}

/*
 * List layout leading chevron (Option A): every item under a collapsible
 * list wrapper (`is-collapsible-list`, added to the `<ul>`/`<ol>` whenever
 * collapsibleChildren is active) reserves the same padding-inline-start
 * gutter on the `<li>` itself, whether or not that particular item has
 * children, so titles stay aligned. The toggle is then positioned inside
 * that gutter, absolute within its `<li>` (which is why the item needs
 * `position: relative`).
 */
:where(.wp-block-document-blocks-template.is-collapsible-list > .wp-block-document-blocks-template__item) {
	padding-inline-start: 2.2em;
	position: relative;
}

:where(.wp-block-document-blocks-template.is-collapsible-list > .wp-block-document-blocks-template__item > .document-blocks-collapse-toggle) {
	inset-inline-start: 0;
	position: absolute;
	top: 0.15em;
}

/*
 * Bulleted/numbered markers render outside the `<li>`, in the *wrapper's*
 * own padding-inline-start gutter -- a separate box from the per-item
 * gutter above, so the marker and the chevron don't occupy the same space.
 * Widen the wrapper's gutter a little for collapsible lists anyway so the
 * marker has breathing room instead of sitting flush against the item edge
 * where the chevron begins.
 *
 * Order-dependent: these narrow the plain `.has-markers-*` rules at the top
 * of the file (and their nested variants), so they must stay below them.
 */
:where(.wp-block-document-blocks-template.has-markers-bulleted.is-collapsible-list),
:where(.wp-block-document-blocks-template.has-markers-numbered.is-collapsible-list) {
	padding-inline-start: 2em;
}

:where(.wp-block-document-blocks-template.has-markers-bulleted.is-collapsible-list .wp-block-document-blocks-template.has-markers-bulleted.is-collapsible-list),
:where(.wp-block-document-blocks-template.has-markers-numbered.is-collapsible-list .wp-block-document-blocks-template.has-markers-numbered.is-collapsible-list) {
	padding-inline-start: 2em;
}

:where(.document-blocks-collapse-count) {
	color: var(--document-blocks-faint);
	font-size: 0.75em;
}

/*
 * Collapsed state: rendered on the server so nested documents start
 * collapsed, and toggled by JS thereafter on the element the toggle's
 * `aria-controls` points at (a nested list wrapper, or a table's `<tbody>`).
 *
 * Without scripting the toggle cannot do anything, so a `<noscript>` style
 * emitted alongside the collection reverts both of these rules -- see
 * `DocumentTemplate::render_noscript_expand_style()`. Those visitors get the
 * expanded tree rather than content they could never reach.
 */
:where(.document-blocks-collapsible.is-collapsed) {
	display: none;
}

:where(tbody.is-collapsed .document-blocks-collapsible-row) {
	display: none;
}

/*
 * Print always renders expanded, regardless of the on-screen toggle state.
 * Order-dependent: reverts the two rules directly above.
 */
@media print {
	:where(.document-blocks-collapsible.is-collapsed) {
		display: revert;
	}

	:where(tbody.is-collapsed .document-blocks-collapsible-row) {
		display: revert;
	}
}

/*
 * Busy while the router fetches a filtered or paged set of results.
 *
 * The fade waits 0.4s, the same pause core's router takes before showing its
 * loading bar, so a fast response never flashes the list. The class leaves
 * with no transition, so new results appear at full opacity.
 */
:where(.wp-block-document-blocks-template.is-loading) {
	cursor: progress;
}

@media (prefers-reduced-motion: no-preference) {
	:where(.wp-block-document-blocks-template.is-loading) {
		opacity: 0.6;
		transition: opacity 0.2s ease 0.4s;
	}
}

/*
 * Block styles -- table treatments only.
 *
 * A block style is one class on the wrapper: it can decorate what a layout
 * already renders, but it cannot add a block. That makes it the right and
 * only tool for the table, where there is no per-row block for an author to
 * style and the treatment has to come from somewhere -- and the wrong tool
 * for a card, whose whole point is *which* document fields it shows. Cards
 * are inserted as blocks by the template's starting-content chooser instead.
 *
 * So the Styles tab offers Default, Ruled and Striped, and all three are
 * about tables. They are inert in the list and grid layouts by design;
 * core's block styles are registered per block type and cannot be shown
 * conditionally, so the names say plainly what they affect.
 *
 * These sit inside `:where()` like everything else here, so choosing a style
 * still leaves the author's own border and color settings winning over it.
 * They come last in the file because zero specificity means source order
 * decides, and a style has to be able to override the base rules it builds
 * on.
 */

/* Ruled -- vertical separators as well as the horizontal ones every row has. */
:where(.wp-block-document-blocks-template.is-style-ruled.is-document-layout-table td),
:where(.wp-block-document-blocks-template.is-style-ruled.is-document-layout-table th) {
	border-inline-end: 1px solid var(--document-blocks-border);
}

:where(.wp-block-document-blocks-template.is-style-ruled.is-document-layout-table td:last-child),
:where(.wp-block-document-blocks-template.is-style-ruled.is-document-layout-table th:last-child) {
	border-inline-end: none;
}

/* Striped -- alternating row tint, for tables wide enough to lose the row. */
:where(.wp-block-document-blocks-template.is-style-striped.is-document-layout-table tbody tr:nth-child(even) td),
:where(.wp-block-document-blocks-template.is-style-striped.is-document-layout-table tbody tr:nth-child(even) th[scope="row"]) {
	background-color: var(--document-blocks-surface);
}

/*
 * Divided -- hairline rules between list items, and only between.
 *
 * The premium list patterns want separators that start at the second row --
 * a border on a per-row group cannot say "not the first", so the rule lives
 * here as a sibling selector, which is exactly what a block style is for.
 * List-oriented where Ruled and Striped are table-oriented; like them it is
 * inert in the layouts it does not address.
 *
 * In this style the template's own border *is* the divider. The render
 * callback hands the border's colour, width and style over as the custom
 * properties read here and keeps them off the wrapper itself, so the one
 * Border control an author already has sets the rules between rows rather
 * than drawing a box around the list. Unset, each falls through to what the
 * style always drew (see `DocumentTemplate::get_divider_style()` and
 * `getDividedWrapperProps()` in blocks/src/collection/utils/divider-style.js).
 *
 * Direct children only, so a nested list's items never inherit the parent
 * list's dividers.
 */
:where(.wp-block-document-blocks-template.is-style-divided > .wp-block-document-blocks-template__item + .wp-block-document-blocks-template__item) {
	border-block-start: var(--document-blocks-divider-width, 1px) var(--document-blocks-divider-style, solid) var(--document-blocks-divider-color, var(--document-blocks-border));
}

