/*
 * The app shell and the sidebar's CONTENT pieces.
 *
 * The sidebar itself — panel, header, collapse, resize, drawer, rail, rows,
 * sections, regions — is the wpds/app-sidebar block family in the WPDS Blocks
 * plugin, which ships its own CSS and behaviour so the sidebar survives a
 * theme switch. What remains here is what a THEME legitimately owns:
 *
 *  1. The shell row the sidebar sits in, and how it meets the admin bar.
 *  2. The mockup content this theme puts INSIDE the sidebar (workspace
 *     switcher, tip card, disclosures, action stack, profile footer), which
 *     is authored content, not component.
 *  3. That content's collapsed-rail treatment. The blocks broadcast the
 *     .wpds-sidebar-collapsed state; content decides what it means for
 *     itself.
 */

/*
 * The block's one geometry knob: how much of the viewport something else
 * already owns. The theme maps its shell offset onto it, so the drawer starts
 * below the admin bar exactly as the shell does.
 */
.wpds-app-sidebar {
	--wpds-app-sidebar-offset: var( --canvas-shell-offset, 0px );
}

/* ------------------------------------------------------ workspace switcher */

/*
 * The switcher is a wpds/button carrying this class; the button brings the
 * control, the theme adds the width and the down-chevron that mark it as a
 * chooser rather than an action.
 */
.wpds-app-sidebar__switcher.wp-block-wpds-button {
	inline-size: 100%;
	justify-content: space-between;
	margin-inline: var( --wpds-dimension-padding-sm, 8px );
	max-inline-size: calc( 100% - 2 * var( --wpds-dimension-padding-sm, 8px ) );
}

.wpds-app-sidebar__switcher.wp-block-wpds-button::after {
	block-size: 7px;
	border-block-start: 1.5px solid currentColor;
	border-inline-end: 1.5px solid currentColor;
	content: '';
	flex: 0 0 auto;
	inline-size: 7px;
	rotate: 135deg;
	translate: 0 -2px;
}

/*
 * The workspace switcher is wpds/dropdown-menu now (Daniel, 2026-08-28:
 * "Replace this with our dropdown block"), not a wpds/button wearing a caret
 * this file drew for it. The button rules above are left in place for any
 * shell still authoring one, but the real control is below.
 *
 * NO ::after HERE. The block draws its own chevron
 * (.wpds-dropdown-menu__chevron), so the theme adding a second one is how a
 * switcher ends up with two arrows. The theme supplies only what a SHELL
 * decides: that this control spans the rail and pushes its chevron to the
 * far edge.
 */
.wpds-app-sidebar__switcher.wp-block-wpds-dropdown-menu {
	inline-size: 100%;
	margin-inline: var( --wpds-dimension-padding-sm, 8px );
	max-inline-size: calc( 100% - 2 * var( --wpds-dimension-padding-sm, 8px ) );
}

.wpds-app-sidebar__switcher.wp-block-wpds-dropdown-menu .wpds-dropdown-menu__trigger {
	inline-size: 100%;
	justify-content: space-between;
}

/* --------------------------------------------------------- action stack */

.wpds-app-sidebar__section--ruled {
	border-block-start: var( --wpds-border-width-xs, 1px ) solid var( --wpds-color-stroke-surface-neutral-weak, #f0f0f0 );
	margin-block-start: var( --wpds-dimension-gap-sm, 8px );
	padding-block-start: var( --wpds-dimension-gap-lg, 16px );
}

.wpds-app-sidebar__stack {
	display: flex;
	flex-direction: column;
	gap: var( --wpds-dimension-gap-sm, 8px );
	padding-inline: var( --wpds-dimension-padding-sm, 8px );
}

/* The actions are wpds/button; only their width is the sidebar's business. */
.wpds-app-sidebar__stack .wp-block-wpds-button {
	inline-size: 100%;
	justify-content: flex-start;
}

/* ------------------------------------------------------- tip + disclosures */

/* The cards take the inset the rows deliberately do not. */
.wpds-app-sidebar__tip,
.wpds-app-sidebar__disclosure {
	margin-inline: var( --wpds-dimension-padding-sm, 8px );
}

.wpds-app-sidebar__tip {
	background-color: var( --wpds-color-background-surface-info-weak, #f3f9ff );
	border: var( --wpds-border-width-xs, 1px ) solid var( --wpds-color-stroke-surface-info, #a9c6e7 );
	border-radius: var( --wpds-border-radius-lg, 8px );
	color: var( --wpds-color-foreground-content-info, #001b4f );
	font-size: var( --wpds-typography-font-size-sm, 12px );
	line-height: var( --wpds-typography-line-height-xs, 16px );
	padding: var( --wpds-dimension-padding-md, 12px );
}

.wpds-app-sidebar__tip p {
	font-size: inherit;
	line-height: inherit;
	margin: 0;
}

.wpds-app-sidebar__tip-kind {
	color: var( --wpds-color-foreground-interactive-brand, #3858e9 );
	display: block;
	font-size: var( --wpds-typography-font-size-xs, 11px );
	font-weight: var( --wpds-typography-font-weight-emphasis, 600 );
	letter-spacing: 0.04em;
	margin-block-end: var( --wpds-dimension-gap-sm, 8px );
	text-transform: uppercase;
}

.wpds-app-sidebar__tip-foot {
	align-items: center;
	display: flex;
	gap: var( --wpds-dimension-gap-sm, 8px );
	justify-content: space-between;
	margin-block-start: var( --wpds-dimension-gap-sm, 8px );
}

.wpds-app-sidebar__tip-foot a {
	font-weight: var( --wpds-typography-font-weight-emphasis, 600 );
}

.wpds-app-sidebar__disclosure {
	border: var( --wpds-border-width-xs, 1px ) solid var( --wpds-color-stroke-surface-neutral-weak, #f0f0f0 );
	border-radius: var( --wpds-border-radius-md, 4px );
	font-size: var( --wpds-typography-font-size-sm, 12px );
	line-height: var( --wpds-typography-line-height-xs, 16px );
	padding: var( --wpds-dimension-padding-sm, 8px ) var( --wpds-dimension-padding-md, 12px );
}

.wpds-app-sidebar__disclosure summary {
	cursor: var( --wpds-cursor-control, pointer );
	font-weight: var( --wpds-typography-font-weight-emphasis, 600 );
}

.wpds-app-sidebar__disclosure p {
	font-size: inherit;
	line-height: inherit;
	margin: var( --wpds-dimension-gap-sm, 8px ) 0 0;
}

/* ----------------------------------------------------------------- footer */

/*
 * The identity row fills the sidebar width: a clickable area's background is
 * the whole row, per the house rule.
 */
.wpds-app-sidebar__profile {
	align-items: center;
	background: none;
	border: var( --wpds-border-width-xs, 1px ) solid transparent;
	border-radius: var( --wpds-border-radius-sm, 2px );
	color: var( --wpds-color-foreground-content-neutral, #1e1e1e );
	cursor: var( --wpds-cursor-control, pointer );
	display: flex;
	font: inherit;
	gap: var( --wpds-dimension-gap-sm, 8px );
	inline-size: 100%;
	padding: var( --wpds-dimension-padding-sm, 8px );
	text-align: start;
}

.wpds-app-sidebar__profile:hover {
	background-color: var( --wpds-color-background-interactive-neutral-weak-active, #ededed );
}

.wpds-app-sidebar__profile p {
	margin: 0;
}

.wpds-app-sidebar__avatar {
	align-items: center;
	background-color: var( --wpds-color-background-surface-brand, #ecf0fa );
	block-size: 28px;
	border-radius: 50%;
	color: var( --wpds-color-foreground-interactive-brand, #3858e9 );
	display: flex;
	flex: 0 0 auto;
	font-size: var( --wpds-typography-font-size-sm, 12px );
	font-weight: var( --wpds-typography-font-weight-emphasis, 600 );
	inline-size: 28px;
	justify-content: center;
	margin: 0;
}

.wpds-app-sidebar__signed-in {
	color: var( --wpds-color-foreground-content-neutral-weak, #707070 );
	display: block;
	font-size: var( --wpds-typography-font-size-xs, 11px );
	line-height: var( --wpds-typography-line-height-xs, 16px );
}

.wpds-app-sidebar__display-name {
	display: block;
	font-size: var( --wpds-typography-font-size-md, 13px );
	font-weight: var( --wpds-typography-font-weight-emphasis, 600 );
	line-height: var( --wpds-typography-line-height-sm, 20px );
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Changelog, README and API Reference travel together, per the reference. */
.wpds-app-sidebar__docs {
	display: flex;
	flex-wrap: wrap;
	font-size: var( --wpds-typography-font-size-sm, 12px );
	gap: var( --wpds-dimension-gap-sm, 8px );
	line-height: var( --wpds-typography-line-height-xs, 16px );
	margin: 0;
	padding-inline: var( --wpds-dimension-padding-sm, 8px );
}

.wpds-app-sidebar__version {
	color: var( --wpds-color-foreground-content-neutral-weak, #707070 );
	font-size: var( --wpds-typography-font-size-xs, 11px );
	line-height: var( --wpds-typography-line-height-xs, 16px );
	margin: 0;
	padding-inline: var( --wpds-dimension-padding-sm, 8px );
}

/* ------------------------------------- this content in the collapsed rail */

@media ( min-width: 783px ) {
	/* Chrome that carries no meaning at 72px goes entirely. */
	.wpds-sidebar-collapsed .wpds-app-sidebar__switcher,
	.wpds-sidebar-collapsed .wpds-app-sidebar__tip,
	.wpds-sidebar-collapsed .wpds-app-sidebar__disclosure,
	.wpds-sidebar-collapsed .wpds-app-sidebar__docs,
	.wpds-sidebar-collapsed .wpds-app-sidebar__version {
		display: none;
	}

	/*
	 * Labels are CLIPPED, never display:none: the rail keeps an accessible
	 * name on every control, and display:none would take the name out of the
	 * accessibility tree along with the pixels.
	 */
	.wpds-sidebar-collapsed .wpds-app-sidebar__signed-in,
	.wpds-sidebar-collapsed .wpds-app-sidebar__display-name {
		block-size: 1px;
		clip-path: inset( 50% );
		inline-size: 1px;
		overflow: hidden;
		position: absolute;
		white-space: nowrap;
	}

	.wpds-sidebar-collapsed .wpds-app-sidebar__profile {
		justify-content: center;
		/*
		 * Zero, not a small inset: the avatar is the widest thing in the rail
		 * and its host's padding pushes it off the rail's centre line.
		 */
		padding-inline: 0;
	}

	.wpds-sidebar-collapsed .wpds-app-sidebar__section--ruled {
		padding-block-start: var( --wpds-dimension-gap-sm, 8px );
	}

	.wpds-sidebar-collapsed .wpds-app-sidebar__stack {
		padding-inline: 0;
	}

	/*
	 * The three actions become their icons, drawn with the Dashicons font
	 * through a pseudo element rather than markup, so the rail needs no second
	 * copy of the buttons and nothing here can be stripped by kses. The
	 * reference asks for icons on exactly these three and forbids them on the
	 * numbered journeys, which keep their ordinals as the identifier.
	 *
	 * font-size: 0 rather than a clip, because the label is the button's own
	 * text node and there is no element to clip. The text stays in the
	 * accessibility tree, and the pseudo element sets its own size so the
	 * glyph survives the zero. It also collapses the component's min-width to
	 * nothing, which is what lets a 40px control fit a 72px rail.
	 */
	.wpds-sidebar-collapsed .wpds-app-sidebar__action {
		font-size: 0;
		gap: 0;
		justify-content: center;
		min-inline-size: 0;
		padding-inline: 0;
	}

	.wpds-sidebar-collapsed .wpds-app-sidebar__action::before {
		content: "\f125";
		font-family: dashicons;
		font-size: var( --wpds-dimension-size-xs, 20px );
		line-height: 1;
	}

	.wpds-sidebar-collapsed .wpds-app-sidebar__action--help::before {
		content: "\f223";
	}

	.wpds-sidebar-collapsed .wpds-app-sidebar__action--settings::before {
		content: "\f111";
	}
}

/* ------------------------------------------------------------- the shell */

/*
 * The scroll contract changed 2026-08-27: page scroll owns the shell.
 * The earlier viewport-pinned version (height + overflow hidden, main
 * as its own scroller) put THREE scrollbars on screen; now the columns
 * are sticky and the browser's bar is the only visible one.
 */
.wpds-app-shell {
	/*
	 * How much of the viewport something else already owns. Zero for a
	 * visitor; the admin bar's height for a logged-in editor, who is most of
	 * the people looking at a mockup.
	 *
	 * Deliberately NOT in the --wpds- namespace. That prefix means "a WPDS
	 * design token" everywhere in this theme, and tools/check-tokens.mjs
	 * enforces it. A theme-local variable gets a theme-local name; the
	 * sidebar block's own --wpds-app-sidebar-offset knob is fed FROM this at
	 * the top of this file.
	 */
	--canvas-shell-offset: 0px;

	align-items: stretch;
	/*
	 * ONE visible scrollbar, the browser's (Daniel, 2026-08-27): the shell
	 * no longer pins to the viewport - the page scrolls natively, the
	 * sidebar and assistant stick, and their internal scrollers hide
	 * their bars. min keeps short pages filling the viewport.
	 */
	min-block-size: calc( 100vh - var( --canvas-shell-offset ) );

	/*
	 * One expression for both header bars, so the sidebar's and the page's
	 * line up as a single rule across the shell: a 40px control between two
	 * 16px paddings and NOTHING else. The hairline term is gone (the W1
	 * immunity diagnosis, changed together with the wpds/app-sidebar block):
	 * both bars now draw their divider as an inset box-shadow that takes no
	 * layout, so the height is EVEN (72, not 73) and centred children stop
	 * landing on half pixels. The sidebar block computes the same expression
	 * for its own header, so the two bars agree without either measuring the
	 * other.
	 */
	--canvas-header-height: calc(
		var( --wpds-dimension-size-lg, 40px ) + 2 * var( --wpds-dimension-padding-lg, 16px )
	);
}

/*
 * Lean header on small screens (Daniel's standing rule): same 40px control,
 * the block padding drops from lg to sm, so both bars go 73 -> 57 together
 * through the one shared expression instead of two hand-kept numbers.
 */
@media ( max-width: 782px ) {
	.wpds-app-shell {
		--canvas-header-height: calc(
			var( --wpds-dimension-size-lg, 40px ) + 2 * var( --wpds-dimension-padding-sm, 8px )
		);
	}
}

/*
 * WordPress pushes the document down with html { margin-top: 32px !important }
 * when the admin bar is present, so a shell of exactly 100vh makes the page
 * 100vh + 32px and it scrolls by precisely the bar's height. The height comes
 * from CORE's variable: admin-bar.css sets --wp-admin--admin-bar--height to
 * 32px and 46px at its own breakpoint, and a theme restating those numbers
 * would drift the day core changes them.
 */
.admin-bar .wpds-app-shell {
	--canvas-shell-offset: var( --wp-admin--admin-bar--height, 0px );
}

/*
 * A DESCENDANT selector, not a child one. The sidebar lives inside a template
 * part wrapper, and display: contents on that wrapper changes how it LAYS
 * OUT, not who its parent is in the DOM: > still walks the real tree and
 * would miss it.
 */
.wpds-app-shell .wpds-app-sidebar {
	flex: 0 0 auto;
}

/* Sticky columns: they hold the viewport while the page scrolls. */
@media ( min-width: 783px ) {
	.wpds-app-shell .wpds-app-sidebar {
		align-self: flex-start;
		block-size: calc( 100vh - var( --canvas-shell-offset, 0px ) );
		inset-block-start: var( --canvas-shell-offset, 0px );
		position: sticky;
	}
}

/* Internal scrollers keep scrolling, without a second visible bar. */
.wpds-app-shell .wpds-sidebar-body,
.wpds-app-shell .wpds-custom-ai-chat__transcript,
.wpds-app-shell .wpds-custom-ai-conversations__list {
	scrollbar-width: none;
}

.wpds-app-shell .wpds-sidebar-body::-webkit-scrollbar,
.wpds-app-shell .wpds-custom-ai-chat__transcript::-webkit-scrollbar,
.wpds-app-shell .wpds-custom-ai-conversations__list::-webkit-scrollbar {
	display: none;
}

/*
 * The wrapper is not a box. The part carries its own aside so it styles
 * itself when someone edits the part on its own, where there is no shell.
 */
.wpds-app-shell > .wp-block-template-part {
	display: contents;
}

.wpds-app-shell > .wpds-app-shell__main {
	flex: 1 1 auto;
	min-inline-size: 0;
}

/*
 * Below the breakpoint the sidebar becomes the block's fixed drawer, so the
 * shell stops pinning itself to the viewport and hands scrolling back to the
 * page.
 */
@media ( max-width: 782px ) {
	.wpds-app-shell {
		block-size: auto;
		flex-wrap: wrap;
		overflow: visible;
	}

	.wpds-app-shell > .wpds-app-shell__main {
		inline-size: 100%;
		overflow-y: visible;
	}

	/* Room for the drawer's fixed opener, so it does not sit on the title. */
	.wpds-sidebar-collapsed .wpds-admin-page__header-lead {
		padding-inline-start: var( --wpds-dimension-size-md, 32px );
	}
}

/*
 * The blank canvas template drops the shell entirely, so it drops its gutter
 * too. The root itself has no padding any more (an app-shell theme keeps its
 * root at zero and document templates carry their own), so this only zeroes
 * the template's own group.
 */
.wpds-canvas-blank {
	padding: 0;
}
/* ---------------------------------------------------------- framed layout */

/*
 * The shell's second mode, ported from UI Playground's .wpc-app-frame
 * .is-framed: the surround shows through (white, per the house style: the
 * frame reads via its border, not via a tinted field), the sidebar blends
 * into the surround, and the work column floats as a rounded, bordered
 * panel. Flush stays the default; the toggle below is the only way in.
 * Desktop-only: below the breakpoint the sidebar is a drawer and the frame
 * has nothing to float against.
 */
@media ( min-width: 783px ) {
	.wpds-shell-framed .wpds-app-shell {
		gap: var( --wpds-dimension-gap-lg, 16px );
		padding: var( --wpds-dimension-padding-lg, 16px );
	}

	/*
	 * The sidebar escapes the frame's padding on its three outer sides, the
	 * donor's negative-margin move: full-bleed against the viewport while the
	 * main panel floats beside it. Its divider goes; the gap is the divider.
	 */
	.wpds-shell-framed .wpds-app-shell .wpds-app-sidebar {
		/* 100% is the shell CONTENT box; the escaped padding is given back, or
		 * the panel stops 2 x 16px short of the viewport bottom. */
		block-size: calc( 100% + 2 * var( --wpds-dimension-padding-lg, 16px ) );
		border-inline-end: 0;
		margin-block: calc( -1 * var( --wpds-dimension-padding-lg, 16px ) );
		margin-inline-start: calc( -1 * var( --wpds-dimension-padding-lg, 16px ) );
	}

	.wpds-shell-framed .wpds-app-shell > .wpds-app-shell__main {
		background-color: var( --wpds-color-background-surface-neutral-strong, #fff );
		border: var( --wpds-border-width-xs, 1px ) solid var( --wpds-color-stroke-surface-neutral, #dbdbdb );
		border-radius: var( --wpds-border-radius-lg, 8px );
	}
}

/* ------------------------------------------------------- assistant column */

/*
 * The assistant rail (Daniel, 2026-08-27): the ai-chat panel as a fixed
 * right column of the shell, beside the main panel on every shell
 * template. The block brings its own chrome; the shell only gives it a
 * lane. Below the drawer breakpoint there is no room for a third column.
 */
.wpds-app-shell .wpds-app-shell__assistant {
	align-self: flex-start;
	block-size: calc( 100vh - var( --canvas-shell-offset, 0px ) );
	/* The ONE line between the main panel and the assistant, the shell's own
	 * hairline in the sidebar's gray (Daniel, 2026-09-02: the panel no longer
	 * draws a box border of its own; dk1-ai-assistant's host zeroes it). */
	border-inline-start: var( --wpds-border-width-xs, 1px ) solid var( --wpds-color-stroke-surface-neutral-weak, #f0f0f0 );
	display: flex;
	/* The chat's resize handle writes the size (ai-agent-block view.js). */
	flex: 0 0 var( --wpds-app-shell-assistant-size, 320px );
	flex-direction: column;
	inset-block-start: var( --canvas-shell-offset, 0px );
	min-inline-size: 0;
	position: sticky;
}

/* The panel is now a group of two surfaces (chat + conversations); the
   visible one fills the column. */
.wpds-app-shell__assistant > .wpds-custom-ai-chat,
.wpds-app-shell__assistant > .wpds-custom-ai-conversations {
	flex: 1 1 auto;
	min-block-size: 0;
}

@media ( max-width: 899px ) {
	.wpds-app-shell .wpds-app-shell__assistant {
		display: none;
	}
}

/*
 * The assistant as a summoned panel: wide screens show the shell column
 * always; below the breakpoint the column is gone, and the
 * wpds-assistant-open class (toggled by the chat's view.js from any
 * .wpds-open-assistant trigger, the Ask button first) floats it over
 * the content as a fixed right panel, the Lingo shape.
 */
@media ( max-width: 899px ) {
	.wpds-assistant-open .wpds-app-shell .wpds-app-shell__assistant {
		display: flex;
		inline-size: var( --wpds-app-shell-assistant-size, 320px );
		inset-block: var( --wpds-app-sidebar-offset, 0px ) 0;
		inset-inline-end: 0;
		max-inline-size: 92vw;
		position: fixed;
		z-index: 30;
	}
}

/* Wide screens: the column stands by default; the closed class (set by
   the chat's close action) collapses it, and Ask brings it back. */
@media ( min-width: 900px ) {
	.wpds-assistant-closed .wpds-app-shell .wpds-app-shell__assistant {
		display: none;
	}
}

/*
 * The panel's two surfaces (Daniel, 2026-08-27: "The header's history
 * action should swap the panel to the conversations screen"): the chat
 * stands by default, the conversations screen waits; the view script's
 * wpds-assistant-history class swaps them. Scoped to the panel wrapper,
 * so a conversations screen placed anywhere else never hides.
 */
.wpds-app-shell__assistant > .wpds-custom-ai-conversations {
	display: none;
}

.wpds-assistant-history .wpds-app-shell__assistant > .wpds-custom-ai-conversations {
	display: flex;
}

.wpds-assistant-history .wpds-app-shell__assistant > .wpds-custom-ai-chat {
	display: none;
}
