/*
 * core/tabs -- the three things the block family has no attribute for.
 *
 * Enqueued against core/tabs by xperience_starter_enqueue_core_block_styles(), so it loads
 * only on a page that actually renders one. Every value below was measured on the source's
 * own tabs widget (#tabs1) with tooling/extract/probe.js on 2026-09-09; nothing here is a
 * guess and nothing here duplicates something a block attribute could carry.
 *
 * WHY THESE CANNOT BE BLOCK ATTRIBUTES:
 *
 * 1. THE STRIP'S OWN BACKGROUND. core/tab-list's colour support carries
 *    __experimentalSkipSerialization, and its `selectors.color.background` points at
 *    `.wp-block-tab-list button` -- so a backgroundColor attribute on that block paints the
 *    BUTTONS, never the container. The source's ul.nav measures rgb(255, 255, 255).
 *
 * 2. THE ACTIVE TAB'S APPEARANCE. Core ships exactly one active-state rule --
 *    :where(.wp-block-tab-list button)[aria-selected=true]::before with a 2px currentColor
 *    underline -- and no attribute anywhere expresses a per-state fill. The source's active
 *    button measures rgb(13, 110, 253) on white at 700; its inactive sibling measures
 *    transparent on rgb(0, 0, 0) at 400. Core's ::before is switched off rather than
 *    restyled: with a white active label, currentColor would draw a white line inside a blue
 *    button, which is not a treatment the source has anywhere.
 *
 * 3. THE MOBILE SKIN, AND IT IS AN APPROXIMATION RATHER THAN A REPRODUCTION. Below
 *    Bootstrap's md breakpoint the source interleaves a full-width trigger bar BEFORE EACH
 *    PANEL. core/tabs emits every button inside core/tab-list and every panel inside a
 *    sibling core/tab-panels, so no stylesheet can interleave them -- the rules below stack
 *    the strip into a column of bars ABOVE the panels, which is as close as the mapping
 *    reaches. This is a knowing deviation for the operator to record at the verdict.
 */

/* --- The strip ------------------------------------------------------------------------ */

.wp-block-tab-list {
	background-color: var(--wp--preset--color--white);
}

/*
 * Core's own button rule is written with :where(), so it has zero specificity and a single
 * class beats it. Its padding resolves to the theme's spacing 20/30 presets (4px 8px)
 * because this theme defines both -- the `0.5em 1em` fallbacks in core's shorthand never
 * fire on a themed site, which is why the source's 20px 40px has to be stated here.
 */
.wp-block-tab-list button {
	padding: 20px 40px;
	background-color: transparent;
	color: var(--wp--preset--color--black);
	font-weight: 400;

	/*
	 * THE TITLE'S SIZE IS RESPONSIVE ON THE SOURCE AND THE CONTRACT DOES NOT MODEL IT. The
	 * contract's `fontSize: large` is the measurement at the captured viewport and is
	 * correct there; below Bootstrap's xxl the source steps the same element down to 1rem.
	 * Read from the source's own stylesheet (CSS/JS channel,
	 * Website/wwwroot/frontend/src/styles/components/_tabs.scss:45-54): `.nav-link` sets
	 * `font-size: 1rem` and raises it to `1.125rem` only inside
	 * `@include media-breakpoint-up(xxl)`, whose Bootstrap 5 value is 1400px. Confirmed by
	 * measurement the same way: probe.js --props reports 18px/27px line-height at 1440x900
	 * and 16px/24px at both 1024x768 and 768x1024, taking the strip from 68px to 65px.
	 * The block attribute is left exactly as the contract records it and this overrides it
	 * below 1400px only.
	 */
	font-size: var(--wp--preset--font-size--medium);
}

@media (min-width: 1400px) {

	.wp-block-tab-list button {
		font-size: var(--wp--preset--font-size--large);
	}
}

/*
 * THE STRIP IS ONE PIXEL SHORTER THAN ITS TALLEST BUTTON ON THE SOURCE, and this is the rule
 * that does it. Measured 2026-09-09 with probe.js --props on #tabs1 button.nav-link:
 * margin-bottom -1px on both buttons, against ul.nav.nav-tabs measuring 1296x68 while its
 * active child measures 165x69. It is Bootstrap's own .nav-tabs .nav-link rule pulling the
 * strip up over the panel area, so the active tab's 2px underline overlaps the panels' top
 * edge instead of sitting above it -- which is why the source's ul ends at y=754 and its
 * accordion begins at y=754. Without it the built unit measured 1296x299 against the
 * source's 1296x298 and 936x296 against 936x295.
 *
 * THE SELECTOR IS QUALIFIED BY role BECAUSE A PLAIN `.wp-block-tab-list button` LOSES THE
 * TIE, and the rule it loses to is invisible from this file. WordPress's layout stylesheet
 * emits `.is-layout-flex > :is(*, div) { margin: 0 }`, whose specificity is (0,1,1) -- the
 * same as `.wp-block-tab-list button` -- and global-styles-inline-css is printed AFTER a
 * theme block stylesheet, so the later rule wins and the declaration is dropped with no
 * error. Measured 2026-09-10 with CDP CSS.getMatchedStylesForNode against
 * http://127.0.0.1:8080/?page_id=227: with the plain selector the button's matched rules
 * include both and getComputedStyle reports margin-bottom 0px. core/tab-list's own save()
 * writes role="tablist" on the container, so this hook is core's markup rather than an
 * invented class, and it takes the selector to (0,2,1).
 */
.wp-block-tab-list[role="tablist"] button {
	margin-bottom: -1px;
}

.wp-block-tab-list button[aria-selected="true"] {
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--white);
	font-weight: 700;
	/*
	 * The source's inactive button carries NO bottom border and measures 2px shorter than
	 * its active sibling (67px against 69px), so the border is added on the active state
	 * rather than held transparent on the base -- the strip's jagged bottom edge on switch
	 * is the source's own behaviour, not an artefact of reproducing it.
	 */
	border-bottom: 2px solid var(--wp--preset--color--primary);
}

/* Core's underline, suppressed -- see note 2 in the header. */
.wp-block-tab-list button[aria-selected="true"]::before {
	content: none;
}

/* --- The mobile skin ------------------------------------------------------------------ */

/*
 * Bootstrap's md breakpoint. The source swaps skins at exactly this width, and core ships no
 * media query of its own for the tabs family, so this is the whole of the responsive
 * behaviour.
 */
@media (max-width: 767.98px) {

	/*
	 * THE BOX AROUND THE STACKED BARS. On the source the mobile skin's edge is carried by
	 * each div.accordion-item -- measured 2026-09-09 at 390x844 with probe.js --props:
	 * 1px solid rgb(222, 226, 230) on all four sides of the first item and on every side but
	 * the top of the second, which composes to one 1px box around the whole widget and makes
	 * every bar 364px wide inside a 366px column. The bars live in core/tab-list and the
	 * panels in a sibling core/tab-panels, so the box has to be drawn on both halves: the
	 * strip carries the top and sides, core/tab-panels' own `style.border` attribute carries
	 * the bottom and sides. Together they measure 113 + 74 = 187px against the source
	 * accordion's 366x187, and the unit root 366x275 against the source's 366x275; without
	 * the strip's border the bars were 366px wide and the root measured 366x274.
	 */
	.wp-block-tab-list {
		box-sizing: border-box;
		flex-direction: column;
		flex-wrap: nowrap;
		background-color: transparent;
		border: 1px solid var(--wp--preset--color--light-gray);
		border-bottom: 0;
	}

	/*
	 * Core sets `width: max-content` on every tab button; the source's bars are full-bleed,
	 * so it is overridden rather than added to.
	 */
	.wp-block-tab-list button {
		width: 100%;
		padding: 16px 20px;
		background-color: var(--wp--preset--color--bright-blue);
		color: var(--wp--preset--color--white);
		font-weight: 400;
		font-size: var(--wp--preset--font-size--medium);
		text-align: left;
		border-bottom: 0;
		box-shadow: inset 0 -1px 0 0 var(--wp--preset--color--light-gray);

		/*
		 * `display: flex` IS HERE ONLY SO THE CHEVRON BELOW CAN BE PUSHED TO THE TRAILING EDGE.
		 * The glyph's `margin-left: auto` and `flex-shrink: 0` are meaningless in the block
		 * formatting context core's button otherwise establishes -- measured before this
		 * change, `display: block`. It moves the build TOWARD the source rather than away from
		 * it: the source's own `button.accordion-button` is Bootstrap's `display: flex;
		 * align-items: center`. IT IS SCOPED TO THIS MEDIA QUERY DELIBERATELY. Above 767.98px
		 * the element this button pairs with is the source's `button.nav-link`, which is
		 * `display: block`, so carrying flex up there would introduce a difference where none
		 * exists.
		 *
		 * THE BOX DOES NOT MOVE, and that was measured rather than argued: the label's line box
		 * is 24px and the glyph is 20px, so the taller of the two still sets the content height
		 * and the bar stays 364x56.
		 */
		display: flex;
		align-items: center;
	}

	/*
	 * THE 20x20 WHITE CHEVRON THE SOURCE DRAWS ON EVERY COLLAPSE BAR AND THIS BUILD DREW ON
	 * NONE. It is the unit contract's `chrome[0]`, `collapse-bar-chevron`, recorded there by
	 * wp-spec with its whole computed set and never accepted into the build until now.
	 * Measured on the built side before this rule with getComputedStyle(el, '::after') through
	 * tooling/node_modules/playwright -- tooling/extract/probe.js has NO pseudo-element
	 * support at all, which is the standing toolkit defect that entry already names: both
	 * buttons reported `content: none` and `backgroundImage: none` on BOTH pseudo-elements.
	 *
	 * EVERY DECLARATION BELOW REPRODUCES A MEASURED COMPUTED VALUE, in the contract's own
	 * order: content '""', display block, 20x20, that backgroundImage, backgroundSize 20px,
	 * no-repeat, position 0% 0%, transform matrix(-1, 0, 0, -1, 0, 0), transition
	 * `transform 0.2s ease-in-out`, flex-shrink 0, margin-left auto, opacity 1. Three of those
	 * are core's own defaults and are NOT restated: background-position 0% 0% and opacity 1
	 * are initial values, and the rotation is written as `rotate(-180deg)` because that is what
	 * computes to the measured matrix.
	 *
	 * `margin-left: auto` IS THE RULE AND `229px` IS NOT. The contract records
	 * `marginLeft: 229px` as the measurement and says in the same breath that it is a resolved
	 * `auto` on a 364px-wide bar -- the sample, not the rule. Written as `auto` here.
	 *
	 * THE DATA URI IS LITERAL, WITH `fill='%23fff'` HARDCODED, and that is a deliberate break
	 * from the mask+currentColor technique the accordion's glyphs use next door
	 * (assets/css/blocks/core-accordion.css). The measured value that has to be reproduced IS
	 * `backgroundImage`; a mask would compute `backgroundImage: none` and put the glyph in
	 * `mask-image` instead, which reproduces the picture and not the measurement. The theme
	 * has no preset that can appear inside a data URI in any case.
	 *
	 * IT IS THE SAME GLYPH ON THE OPEN BAR AND THE CLOSED ONE, with no state selector, and
	 * that is the contract's explicit warning rather than an oversight: neither of the
	 * source's bars carries Bootstrap's `collapsed` class, so its `:not(.collapsed)` rule
	 * matches both and both take the active, rotated icon. "Rotate the chevron when open"
	 * would be reproducing Bootstrap's intent and not this source.
	 *
	 * 390x844 IS THE ONLY VIEWPORT IT PAINTS AT, which is why it lives inside this media query
	 * and nowhere else. The contract's readings at the other three viewports are off a
	 * `display: none` subtree and are facts about nothing painted.
	 */
	.wp-block-tab-list button::after {
		content: "";
		display: block;
		flex-shrink: 0;
		width: 20px;
		height: 20px;
		margin-left: auto;
		background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
		background-repeat: no-repeat;
		background-size: 20px;
		transform: rotate(-180deg);
		transition: transform 0.2s ease-in-out;
	}

	/*
	 * The open bar and the closed bars look identical on the source -- both measured
	 * rgb(28, 58, 169) at weight 400 -- so the desktop active treatment is undone here
	 * rather than carried down.
	 */
	.wp-block-tab-list button[aria-selected="true"] {
		background-color: var(--wp--preset--color--bright-blue);
		color: var(--wp--preset--color--white);
		font-weight: 400;
		/* The desktop rule's 2px underline would make the open bar 58px against its 56px
		   siblings; the source's bars are all 56px and identical. */
		border-bottom: 0;
	}

	/*
	 * THE PANEL'S PADDING IS RESPONSIVE ON THE SOURCE and this is the one rule here that has
	 * to fight an inline style. Measured on div.accordion-body: 50px at 1440x900, 16px 20px
	 * at 390x844 -- same element, same class, a media query in the source's own stylesheet.
	 * On the WordPress side the 50px is a core/tab-panel `style.spacing.padding` attribute,
	 * which serialises as an inline style and therefore outranks any selector here.
	 *
	 * WP 7.1 DOES have viewport-scoped block styles (`style.@mobile`, `style.@tablet`) and
	 * they would be the conventional answer -- but this theme.json declares `mobile` at
	 * 575.98px and `tablet` at 991.98px, and the source swaps skins at Bootstrap's md,
	 * 767.98px. Neither declared viewport is that breakpoint, and theme.json is
	 * wp-theme-scaffold's file rather than this unit's. So the escape hatch is used
	 * deliberately and is scoped to the two properties that actually change.
	 *
	 * If a `md` viewport is ever added to theme.json, replace this with a `style.@md` on the
	 * core/tab-panel blocks in patterns/tabs.php and delete the !important.
	 */
	/*
	 * The desktop overhang is undone here, and at the same specificity as the rule that sets
	 * it -- a media query adds none of its own. Above, a -1px bottom margin pulls the strip
	 * up over the panels; in this column flex container it would pull every bar up over the
	 * one below it instead, taking the strip from 113px to 111px and eating the bars' own
	 * divider.
	 */
	.wp-block-tab-list[role="tablist"] button {
		margin-bottom: 0;
	}

	.wp-block-tab-panel {
		padding: 16px 20px !important;
	}
}
