/*
Theme Name: Ollie TS
Template: ollie
Description: Ollie child theme with a Tailscale-style look for Orchestra Solutions.
Version: 0.1.0
Requires at least: 6.6
Text Domain: ollie-ts
License: GNU General Public License v2 or later
*/

/*
 * Design tokens, element and block styles live in theme.json and styles/.
 * This file only holds what theme.json cannot express: pseudo elements,
 * child selectors, transitions and plugin (Menu Designer) markup.
 */

/* Base
---------------------------------------------------------------------------- */

/* Anchor links land below the sticky header, and scroll smoothly */
html {
	scroll-padding-top: calc(var(--ts-header-h, 81px) + 1.5rem);
}

@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

:where(h1, h2, h3, h4, h5, h6) {
	text-wrap: balance;
}

a {
	text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}

a:where(:not(.wp-element-button)):hover {
	opacity: 0.8;
}

.wp-element-button,
.wp-block-button__link {
	transition: color .2s cubic-bezier(.4, 0, .2, 1), background-color .2s cubic-bezier(.4, 0, .2, 1), border-color .2s cubic-bezier(.4, 0, .2, 1), opacity .2s;
}

:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary-alt);
	outline-offset: 2px;
}

::selection {
	background: var(--wp--preset--color--blue-pale);
}

/* Block styles (see styles/blocks/*.json for the token part)
---------------------------------------------------------------------------- */

/* Button: Text Link */
.is-style-ts-button-text .wp-block-button__link {
	text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}

.is-style-ts-button-text .wp-block-button__link:hover {
	opacity: 0.8;
}

/* Paragraph/Heading: Eyebrow With Rule - a hairline fills the rest of the row */
.is-style-ts-eyebrow-rule {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.is-style-ts-eyebrow-rule::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--wp--preset--color--border-light);
}

/* List: Menu Links - full-width link rows with a grey hover fill */
.wp-block-list.is-style-ts-menu-list {
	list-style: none;
	margin-left: -0.75rem;
	margin-right: -0.75rem;
}

.is-style-ts-menu-list li {
	margin: 0;
}

/* Dropdown panels sit inside the Navigation block, where core resets every
   list's margins (.wp-block-navigation ul). Restore the gap between a column
   label and its links; it matches the columns' 1.25rem block spacing. */
.wp-block-ollie-mega-menu__menu-container .wp-block-column > .is-style-ts-menu-list:not(:first-child) {
	margin-top: 1.25rem;
}

/* Wide dropdowns span the content width, but the visible panel is narrower
   (patterns/menu-*.php center it). Only the panel takes the mouse, so moving
   off it to the side counts as leaving the menu. */
.wp-block-ollie-mega-menu__menu-container.menu-width-wide {
	pointer-events: none;
}

.wp-block-ollie-mega-menu__menu-container.menu-width-wide .is-style-ts-menu-panel {
	pointer-events: auto;
}

.is-style-ts-menu-list a {
	display: block;
	padding: 0.75rem;
	border-radius: var(--wp--preset--border-radius--sm);
	color: inherit;
	text-decoration: none;
	transition: background-color .2s;
}

.is-style-ts-menu-list a:hover {
	opacity: 1;
	background: var(--wp--preset--color--primary-accent);
}

/* Group: Menu Panel - clip the footer strip to the rounded corners */
.is-style-ts-menu-panel {
	overflow: hidden;
}

/* Post Terms: Tag - pastel pills */
.wp-block-post-terms.is-style-ts-tag {
	display: flex;
	flex-wrap: wrap;
	gap: 0.375rem;
}

.is-style-ts-tag .wp-block-post-terms__separator {
	display: none;
}

.is-style-ts-tag a {
	display: inline-block;
	padding: 0.375rem 0.5rem;
	line-height: 1;
	border-radius: var(--wp--preset--border-radius--xs);
	background: var(--wp--preset--color--green-pale);
	color: var(--wp--preset--color--forest);
	text-decoration: none;
}

.is-style-ts-tag a:hover {
	opacity: 1;
	background: var(--wp--preset--color--green-pale);
	filter: brightness(0.96);
}

/* Core blocks
---------------------------------------------------------------------------- */

/* Details: FAQ row with a round dark chevron */
.wp-block-details summary {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 1rem;
	font-weight: 500;
	cursor: pointer;
	list-style: none;
}

.wp-block-details summary::-webkit-details-marker {
	display: none;
}

.wp-block-details summary::after {
	content: "";
	flex: none;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: var(--wp--preset--color--primary) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M6 8.5l4 4 4-4' fill='none' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat;
	transition: transform .2s;
}

.wp-block-details[open] summary::after {
	transform: rotate(180deg);
}

.wp-block-details[open] summary {
	margin-bottom: 0.5rem;
}

.wp-block-details > :not(summary) {
	color: var(--wp--preset--color--secondary);
}

/* Search input */
.wp-block-search .wp-block-search__input {
	border: 1px solid var(--wp--preset--color--border-medium);
	border-radius: var(--wp--preset--border-radius--sm);
	padding: 0.625rem 1rem;
	background: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--base);
}

.wp-block-search .wp-block-search__input:focus {
	border-color: var(--wp--preset--color--secondary);
	outline: none;
}

/* Table: hairline rows, tinted header */
.wp-block-table table {
	border-collapse: collapse;
}

/* Table text one step under body text. Ollie's core-table.css sets x-small on
   the table, which beats the "small" size in theme.json. */
.wp-block-table > table {
	font-size: var(--wp--preset--font-size--small);
}

.wp-block-table thead {
	border-bottom: 0;
}

.wp-block-table th,
.wp-block-table td {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--border-light);
	padding: 0.75rem;
}

.wp-block-table th {
	text-align: left;
	font-weight: 500;
	background: var(--wp--preset--color--tertiary);
}

/* Header navigation (Menu Designer)
---------------------------------------------------------------------------- */

/* Nav items: 14px/500, 10px 12px padding, radius 8, grey fill on hover and when open */
.wp-block-navigation .wp-block-navigation-item .wp-block-navigation-item__content {
	padding: 0.625rem 0.75rem;
	border-radius: var(--wp--preset--border-radius--sm);
	transition: background-color .2s;
}

.wp-block-navigation .wp-block-navigation-item .wp-block-navigation-item__content:hover,
.wp-block-navigation .wp-block-ollie-mega-menu .wp-block-ollie-mega-menu__toggle[aria-expanded="true"] {
	background: var(--wp--preset--color--primary-accent);
	opacity: 1;
}

/* Dropdown toggle icon. theme.json settings.custom.menuToggle picks it per style
   variation: plus/minus glyph (default look) or the plugin's chevron (Orchestra),
   which turns 180 degrees when the menu opens. */
.wp-block-navigation .wp-block-ollie-mega-menu .wp-block-ollie-mega-menu__toggle .wp-block-ollie-mega-menu__toggle-icon {
	width: auto;
	height: auto;
	margin-left: 0.25rem;
	line-height: 1;
	font-weight: 400;
	font-size: 1.1em;
}

.wp-block-navigation .wp-block-ollie-mega-menu .wp-block-ollie-mega-menu__toggle .wp-block-ollie-mega-menu__toggle-icon svg {
	display: var(--wp--custom--menu-toggle--chevron, none);
	width: 10px;
	height: 10px;
	margin-top: 0;
	vertical-align: middle;
}

.wp-block-ollie-mega-menu__toggle-icon::before {
	content: "+";
	display: var(--wp--custom--menu-toggle--plus, inline);
}

.wp-block-ollie-mega-menu__toggle[aria-expanded="true"] .wp-block-ollie-mega-menu__toggle-icon::before {
	content: "\2212";
}

/* Announcement bar text. Size comes from settings.custom.announcement.fontSize:
   12px mono in the default look, the Small size in the Orchestra variation. */
.ts-announcement {
	font-size: var(--wp--custom--announcement--font-size, var(--wp--preset--font-size--x-small));
}

/* Header items that only show when the full nav shows. 1100px matches the
   navigation's mobileMenuBreakpoint in patterns/header.php. */
@media (max-width: 1099px) {
	.ts-desktop-only {
		display: none !important;
	}
}

/* Mobile menu: accordion links keep the normal text color */
.wp-block-details .is-style-ts-menu-list {
	color: var(--wp--preset--color--main);
}

/* Prose (blog posts, text pages): add class "ts-prose" to a Post Content block
---------------------------------------------------------------------------- */

.ts-prose {
	line-height: 1.7;
}

.ts-prose > * + * {
	margin-block-start: 1.25em;
}

.ts-prose :where(h2) {
	font-size: var(--wp--preset--font-size--section);
	margin-block-start: 1.75em;
}

.ts-prose :where(h3) {
	font-size: var(--wp--preset--font-size--title);
	margin-block-start: 1.5em;
}

.ts-prose :where(h4) {
	font-size: var(--wp--preset--font-size--medium);
}

/* CTA cards ([cta slug="…"]) inside prose keep their own spacing and type,
   and get room around them. */
.ts-prose > .ts-cta-card {
	margin-block: 2.5rem;
	line-height: var(--wp--custom--line-height--body, 1.6);
}

.ts-prose .ts-cta-card :where(h2, h3, h4) {
	margin-block-start: var(--wp--preset--spacing--small);
}

.ts-prose a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--primary-alt);
	font-weight: 600;
	text-underline-offset: 2px;
}

.ts-prose :where(ul, ol) {
	padding-left: 1.25em;
}

.ts-prose :where(li) {
	margin-block: 0.4em;
}

.ts-prose :where(ul) li::marker {
	color: rgba(24, 23, 23, 0.4);
}

.ts-prose :where(img) {
	border-radius: var(--wp--preset--border-radius--sm);
}

.ts-prose :where(code):not(pre code) {
	font-family: var(--wp--preset--font-family--monospace);
	font-size: 0.85em;
	background: var(--wp--preset--color--tertiary);
	border: 1px solid var(--wp--preset--color--border-medium);
	border-radius: var(--wp--preset--border-radius--sm);
	padding: 0 4px;
}

/* Tabs: Product Cards (Tailscale home product switcher)
   Tab labels use <strong>Title</strong><em>Description</em>.
---------------------------------------------------------------------------- */

.is-style-ts-product-tabs .wp-block-tab-list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
	gap: 0.75rem;
	margin-bottom: 0.75rem;
}

.is-style-ts-product-tabs .wp-block-tab-list button {
	width: auto;
	padding: 1.5rem;
	border-radius: var(--wp--preset--border-radius--lg);
	text-align: left;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	color: var(--wp--preset--color--secondary);
	transition: background-color .2s, color .2s;
}

.is-style-ts-product-tabs .wp-block-tab-list button strong {
	display: block;
	margin-bottom: 0.25rem;
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--main);
}

.is-style-ts-product-tabs .wp-block-tab-list button em {
	display: block;
	font-style: normal;
}

.is-style-ts-product-tabs .wp-block-tab-list button:hover {
	background: var(--wp--preset--color--primary-accent);
}

.is-style-ts-product-tabs .wp-block-tab-list button[aria-selected="true"] {
	background: var(--wp--preset--color--red);
	color: rgba(255, 255, 255, 0.85);
}

.is-style-ts-product-tabs .wp-block-tab-list button[aria-selected="true"] strong {
	color: #fff;
}

.is-style-ts-product-tabs .wp-block-tab-list button::before {
	display: none;
}

@media (max-width: 781px) {
	.is-style-ts-product-tabs .wp-block-tab-list {
		display: flex;
		flex-wrap: wrap;
		gap: 0.375rem;
	}

	.is-style-ts-product-tabs .wp-block-tab-list button {
		padding: 0.5rem 0.75rem;
		border-radius: var(--wp--preset--border-radius--md);
		background: var(--wp--preset--color--base);
	}

	.is-style-ts-product-tabs .wp-block-tab-list button strong {
		margin: 0;
		font-size: var(--wp--preset--font-size--small);
	}

	.is-style-ts-product-tabs .wp-block-tab-list button em {
		display: none;
	}
}

/* Tabs: Pills (centered rounded pills, active = dark) */
.is-style-ts-pill-tabs .wp-block-tab-list {
	justify-content: center;
	gap: 0.375rem;
}

.is-style-ts-pill-tabs .wp-block-tab-list button {
	padding: 0.5rem 0.75rem;
	border: 1px solid rgba(31, 30, 30, 0.1);
	border-radius: var(--wp--preset--border-radius--full);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--main);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1;
}

.is-style-ts-pill-tabs .wp-block-tab-list button[aria-selected="true"] {
	background: var(--wp--preset--color--primary);
	border-color: var(--wp--preset--color--primary);
	color: #fff;
}

.is-style-ts-pill-tabs .wp-block-tab-list button::before {
	display: none;
}

/* List: Accent Squares - small squares in the current accent color */
.wp-block-list.is-style-ts-list-shapes {
	list-style: none;
}

.is-style-ts-list-shapes li {
	position: relative;
	padding-left: 1.25rem;
	margin-block: 0.6rem;
}

.is-style-ts-list-shapes li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.45em;
	width: 0.55rem;
	height: 0.55rem;
	background: var(--ts-accent, var(--wp--preset--color--red));
}

.is-style-ts-list-shapes li:nth-child(3n+2)::before {
	border-radius: 50%;
}

.is-style-ts-list-shapes li:nth-child(3n)::before {
	border-radius: 0 0.55rem 0 0;
}

/* Group: Logo Tile - small bordered chip (icon + name), centered */
.is-style-ts-logo-tile {
	justify-content: center;
	min-height: 4rem;
	padding: 0.75rem 1rem;
}

.is-style-ts-logo-tile .wp-block-image {
	margin: 0;
	flex: none;
}

/* Group: Icon Tile - square tile holding one logo that fills it */
.is-style-ts-icon-tile {
	aspect-ratio: 1;
	padding: 0.375rem;
}

.is-style-ts-icon-tile .wp-block-image,
.is-style-ts-icon-tile img {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: contain;
	border-radius: var(--wp--preset--border-radius--sm);
}

/* Integrations wall (patterns/integrations-wall.php): on phones the text card
   takes a full row. Spanning 4 of 5 narrow columns, it was wider than the screen. */
@media (max-width: 480px) {
	.wp-block-group.ts-wall-card {
		grid-column: 1 / -1;
		grid-row: auto;
	}

	/* Later logos fill the gap left in the row above the card. */
	.wp-block-group:has(> .ts-wall-card) {
		grid-auto-flow: dense;
	}
}

/* Code: Ollie's "Dark" style as a terminal window */
.wp-block-code.is-style-dark-code {
	background: var(--wp--preset--color--charcoal);
	border-color: var(--wp--preset--color--charcoal);
	color: var(--wp--preset--color--border-light);
	text-align: left;
}

/* Product Cards: one accent per tab (Tailscale uses red, purple, blue, green) */
.is-style-ts-product-tabs .wp-block-tab-list button:nth-child(2)[aria-selected="true"] { background: var(--wp--preset--color--purple); }
.is-style-ts-product-tabs .wp-block-tab-list button:nth-child(3)[aria-selected="true"] { background: var(--wp--preset--color--blue); }
.is-style-ts-product-tabs .wp-block-tab-list button:nth-child(4)[aria-selected="true"] { background: var(--wp--preset--color--forest); }
.is-style-ts-product-tabs .wp-block-tab-list button:nth-child(5)[aria-selected="true"] { background: var(--wp--preset--color--amber); }
.is-style-ts-product-tabs .wp-block-tab-panel:nth-child(2) { --ts-accent: var(--wp--preset--color--purple); }
.is-style-ts-product-tabs .wp-block-tab-panel:nth-child(3) { --ts-accent: var(--wp--preset--color--blue); }
.is-style-ts-product-tabs .wp-block-tab-panel:nth-child(4) { --ts-accent: var(--wp--preset--color--forest); }
.is-style-ts-product-tabs .wp-block-tab-panel:nth-child(5) { --ts-accent: var(--wp--preset--color--amber); }

/* Motion (research/tailscale-motion.md): Tailscale uses very little.
---------------------------------------------------------------------------- */

/* Dim the page behind an open mega menu (fades in over 300ms). Drawn by the
   sticky main bar: Ollie dissolves the header wrapper for a partial sticky header. */
.site-header .is-position-sticky::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -1;
	background: rgba(24, 23, 23, 0.25);
	opacity: 0;
	pointer-events: none;
	transition: opacity .3s;
}

.site-header .is-position-sticky:has(.wp-block-ollie-mega-menu__toggle[aria-expanded="true"])::after {
	opacity: 1;
}

/* Blog cards: darker border and a shadow on hover */
.wp-block-post .is-style-ts-card {
	transition: border-color .3s, box-shadow .3s;
}

.wp-block-post .is-style-ts-card:hover {
	box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
}

/* FAQ rows open with a short height and fade animation */
.wp-block-details {
	interpolate-size: allow-keywords;
}

.wp-block-details::details-content {
	height: 0;
	opacity: 0;
	overflow: hidden;
	transition: height .2s, opacity .2s, content-visibility .2s allow-discrete;
}

.wp-block-details[open]::details-content {
	height: auto;
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-details::details-content,
	.site-header .is-position-sticky::after {
		transition: none;
	}
}

/* Table: Compare - plan comparison rows (first column left, values centered) */
.wp-block-table.is-style-ts-compare {
	margin-block: 0;
}

/* In page and post text (compare pages, blog), keep space around the table. */
.ts-prose > .wp-block-table.is-style-ts-compare {
	margin-block: 1.5em;
}

.is-style-ts-compare th,
.is-style-ts-compare td {
	text-align: center;
	padding: 0.875rem 0.75rem;
	background: none;
}

.is-style-ts-compare th:first-child,
.is-style-ts-compare td:first-child {
	text-align: left;
	width: 32%;
}

.is-style-ts-compare thead th {
	border-top: 0;
	font-weight: 500;
	font-size: var(--wp--preset--font-size--base);
}

.is-style-ts-compare thead th:first-child {
	font-size: var(--wp--preset--font-size--medium);
	padding-top: var(--wp--preset--spacing--large);
}

.is-style-ts-compare td:not(:first-child) {
	color: var(--wp--preset--color--secondary);
}

.wp-block-table.is-style-ts-compare,
.is-style-ts-compare table {
	background: transparent;
	border: 0;
}

/* Forms: Tailscale-style fields. Used by the contact pattern's HTML form; the
   same look applies to embedded forms that use plain inputs.
---------------------------------------------------------------------------- */

.ts-form {
	display: grid;
	gap: 1.25rem;
}

.ts-form label {
	display: grid;
	gap: 0.25rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.2;
}

/* .ts-form is doubled to outrank Ollie's input:not(...):not(...) rule */
.ts-form.ts-form label :is(input, select, textarea) {
	width: 100%;
	box-sizing: border-box;
	padding: 0.7rem 1rem;
	border: 1px solid var(--wp--preset--color--border-light);
	border-radius: var(--wp--preset--border-radius--sm);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--charcoal);
	font: inherit;
	font-size: var(--wp--preset--font-size--base);
	font-weight: 400;
	line-height: 1.5;
}

.ts-form.ts-form label :is(input, select, textarea):focus {
	border-color: var(--wp--preset--color--secondary);
	outline: none;
}

.ts-form.ts-form label select {
	appearance: none;
	height: auto;
	padding-right: 2.5rem;
	background: var(--wp--preset--color--base) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%23706e6d' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right 1rem center / 16px no-repeat;
}

.ts-form ::placeholder {
	color: var(--wp--preset--color--main-accent);
}

.ts-form button {
	justify-self: start;
	border: 0;
	cursor: pointer;
}

/* Long code lines scroll sideways instead of being cut off */
.wp-block-code {
	overflow-x: auto;
}

.wp-block-code code {
	white-space: pre;
}

/* Group: Mosaic Tile - square colored tile with a centered logo (navy heroes) */
.is-style-ts-mosaic-tile {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1;
}

.is-style-ts-mosaic-tile .wp-block-image {
	width: 42%;
	margin: 0;
}

.is-style-ts-mosaic-tile img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--wp--preset--border-radius--md);
}

/* Blog posts: text is inset 32px inside the article column, media stays full width */
@media (min-width: 782px) {
	.single-post .ts-prose > :where(p, h2, h3, h4, h5, h6, ul, ol, blockquote, .wp-block-quote, .wp-block-details) {
		margin-inline: 2rem;
	}
}


/* ==========================================================================
   Content type templates (integrations, use cases, events, FAQ, glossary)
   ========================================================================== */

/* ==========================================================================
   CPT templates (integration, use-case, event, faq, glossary-item)
   Staging file: merge into style.css later.
   ========================================================================== */

/* Card term label: grey text, not a link look (integration + use-case cards) */
.ts-cpt-card-terms a {
	color: inherit;
	text-decoration: none;
}

/* "Find out more ->" label inside a linked card (the whole card is the link) */
.ts-cpt-more {
	text-decoration: underline;
	text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}

/* Event status tag: "Ended" events get a grey pill instead of the green one */
.is-style-ts-tag.taxonomy-event-status a[href*="/event-status/past/"] {
	background: var(--wp--preset--color--primary-accent);
	color: var(--wp--preset--color--secondary);
}


/* ==========================================================================
   Product landers and the Sticky Section Nav
   ========================================================================== */

/*
 * Lander patterns (patterns/lander-*.php) - rules theme.json cannot express.
 * Staging file: merge into style.css later.
 */

/* Height of the sticky main bar (the announcement bar scrolls away). Sticky
   elements below the header (section nav, sidebars) and anchor jumps use it.
   Measured 2026-09-25: at 1100px and wider it is settings.custom.header.height
   (81px default, 84px Orchestra, whose buttons are larger); 72px below (mobile
   menu). If the header changes, update these numbers. */
:root {
	--ts-header-h: var(--wp--custom--header--height, 81px);
}

@media (max-width: 1099px) {
	:root { --ts-header-h: 72px; }
}

/* Sticky Section Nav (patterns/lander-section-nav.php)
   ---------------------------------------------------------------------------
   Markup: group.ts-section-series > [ group.ts-section-nav (Position: Sticky),
   section#routing, section#failover, ... ]. A sticky element only sticks
   inside its parent, so the bar releases when the series group ends, that is
   after the last section has scrolled past. Core writes "top: 0" for sticky
   groups; this moves the bar under the sticky header. Keep the z-index below
   the header's (its mega menus must open over the bar). */
.ts-section-nav.is-position-sticky {
	top: calc(var(--ts-header-h) + var(--wp-admin--admin-bar--position-offset, 0px));
	z-index: 9;
}

/* Anchor jumps land below the header and the bar. (scroll-padding on the
   page, not scroll-margin on the sections: the scroll spy below then marks a
   section active when it reaches the upper half of the screen.) This beats
   the site-wide 150px in style.css, because the bar adds 3.5rem. */
html:has(.ts-section-series) {
	scroll-padding-top: calc(var(--ts-header-h) + 3.5rem);
}

/* Links: one row that scrolls sideways on small screens. */
.ts-section-nav .ts-section-nav__links {
	min-width: 0;
	overflow-x: auto;
	scrollbar-width: none;
	/* CSS-only scroll spy (Chrome 140+): the link whose section is in view
	   matches :target-current. Other browsers show no active state. */
	scroll-target-group: auto;
}

.ts-section-nav .ts-section-nav__links::-webkit-scrollbar {
	display: none;
}

.ts-section-nav .ts-section-nav__links .wp-block-button {
	flex: none;
}

.ts-section-nav .ts-section-nav__links .wp-block-button__link:target-current {
	background: var(--wp--preset--color--primary-accent);
}

/* Lander details
   --------------------------------------------------------------------------- */

/* Accent for the bullet shapes (is-style-ts-list-shapes) per section */
.ts-accent-red { --ts-accent: var(--wp--preset--color--red); }
.ts-accent-purple { --ts-accent: var(--wp--preset--color--purple); }
.ts-accent-blue { --ts-accent: var(--wp--preset--color--blue); }
.ts-accent-green { --ts-accent: var(--wp--preset--color--emerald); }
.ts-accent-amber { --ts-accent: var(--wp--preset--color--amber); }

/* "Before" list: grey shapes */
.is-style-ts-list-shapes.ts-list-muted {
	--ts-accent: var(--wp--preset--color--main-accent);
}

/* Quote with a hanging opening mark */
.ts-hanging-quote {
	text-indent: -0.4em;
}

/* FAQ: close the last row with a hairline, like Tailscale */
.ts-faq .wp-block-details:last-child {
	border-bottom: 1px solid var(--wp--preset--color--border-light);
}

/* FAQ sections embed [faq tags="…"] (FAQ content type): two columns from 782px,
   filled row by row. The last row gets the closing hairline in both columns. */
@media (min-width: 782px) {
	.ts-faq .faq-shortcode {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: var(--wp--preset--spacing--x-large);
		align-items: start;
	}

	.ts-faq .faq-shortcode > .wp-block-details:nth-last-child(2):nth-child(odd) {
		border-bottom: 1px solid var(--wp--preset--color--border-light);
	}
}

/* Image panel with no padding: the photo fills the rounded panel */
.ts-panel-fill {
	position: relative;
	overflow: hidden;
}

.ts-panel-fill > .wp-block-image {
	position: absolute;
	inset: 0;
	margin: 0;
}

.ts-panel-fill > .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Stacked columns: shorter image panels (overrides the inline min-height).
   .ts-panel = image on a padded color panel, .ts-panel-fill = full-bleed photo. */
@media (max-width: 781px) {
	.ts-panel {
		min-height: 0 !important;
	}

	.ts-panel-fill {
		min-height: 260px !important;
	}
}


/* ==========================================================================
   Extra page types (changelog, careers, press, SDKs, legal, resources)
   ========================================================================== */

/*
 * Extras (extra-* patterns: changelog, careers, press, SDKs, legal, resources).
 * Only rules that theme.json and block attributes cannot express.
 * TEMPORARY staging file: merge into style.css later.
 */

/* Changelog entry: the New / Fixed label hangs in the gutter to the left of
   the content column, so titles, sub-heads and text all share one left edge. */
@media (min-width: 782px) {
	.ts-changelog-item > .ts-changelog-label {
		margin-left: -5.125rem; /* label width 64px + 18px gap */
	}
}

.ts-changelog-item > .ts-changelog-label {
	flex-shrink: 0; /* keep the 64px gutter when the text is long */
}

/* Careers hero photo strip: on phones, crop the wide strip instead of
   shrinking it to a thin band. */
@media (max-width: 781px) {
	.wp-block-image.alignfull.ts-careers-strip img {
		height: 260px;
		object-fit: cover;
		object-position: 35% 50%;
	}
}

/* Split CTA "Try ... for free" panel: on desktop the shapes sit to the right
   of the text (45% right padding). On phones, move the shapes below the text. */
@media (max-width: 781px) {
	.ts-split-cta-try {
		padding-right: var(--wp--preset--spacing--large) !important;
		padding-bottom: 15rem !important;
		background-position: 100% 100% !important;
		background-size: auto 13rem !important;
	}
}

/* Illustrations (Custom HTML blocks with inline SVG, see tools/inline_art.py)
   Colors are CSS variables. theme.json settings.custom.art.tailscale / .orchestra
   (inline | none) choose which shape set shows, so a style variation can swap them.
---------------------------------------------------------------------------- */

.ts-art {
	margin: 0;
}

.ts-art .ts-art-tailscale {
	display: var(--wp--custom--art--tailscale, inline);
}

.ts-art .ts-art-orchestra {
	display: var(--wp--custom--art--orchestra, none);
}

.ts-art.alignright svg {
	margin-left: auto;
}

/* Heading/Paragraph: Highlight - text marked with the Highlight format becomes a
   chip. Its color, padding and tilt come from settings.custom.highlight, so each
   style variation can change them (Orchestra: blue chip tilted -2deg, text straight).
   Keep it to one or two words; the chip does not wrap across lines. It stays
   inline (not inline-block), so punctuation right after it stays on its line. */
.is-style-ts-highlight mark {
	position: relative;
	z-index: 0;
	display: inline;
	white-space: nowrap;
	padding: var(--wp--custom--highlight--padding, 0 0.15em);
	background: transparent !important;
	color: var(--wp--custom--highlight--text);
	line-height: 1.05;
}

/* The chip is drawn behind the text, so only the chip tilts. */
.is-style-ts-highlight mark::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: var(--wp--preset--border-radius--sm);
	background: var(--wp--custom--highlight--background);
	transform: rotate(var(--wp--custom--highlight--tilt, 0deg));
}

/* On a blue band the chip turns white, with the band's blue as the text. */
.has-band-blue-gradient-background .is-style-ts-highlight mark,
.has-primary-background-color .is-style-ts-highlight mark {
	--wp--custom--highlight--background: var(--wp--preset--color--base);
	--wp--custom--highlight--text: var(--wp--preset--color--primary);
}

/* Outline buttons: Ollie draws the ring with a CSS outline (no border), set 3.5px
   inside the edge. Put a 1.5px ring right at the edge instead, so an outline button
   looks exactly as big as a filled one (both use the same padding). */
.wp-block-button.is-style-outline .wp-block-button__link {
	outline-width: 1.5px;
	outline-offset: -1.5px;
}

/* ==========================================================================
   Plugin output: Snippet Aggregator and Edible Live Search
   ========================================================================== */

/*
 * These plugins print their own HTML from shortcodes. The rules below dress it
 * in the theme's tokens, so it follows the style variations too.
 */

/* Integration filter pills ([integration_filter_buttons]): the plugin prints core
   Buttons with the "Pill" block style; mark the current filter. */
.integration-filter .wp-block-button.is-active .wp-block-button__link {
	background: var(--wp--preset--color--main);
	border-color: var(--wp--preset--color--main);
	color: var(--wp--preset--color--base);
}

/* Live search ([edible_live_search]): match the core Search input; left-aligned. */
.edible-search-form.edible-search-form {
	max-width: 30rem;
	width: 100%;
	margin: 0;
}

.edible-search-form .edible-search-input {
	border: 1px solid var(--wp--preset--color--border-medium);
	border-radius: var(--wp--preset--border-radius--sm);
	padding: 0.625rem 2.5rem 0.625rem 1rem;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--main);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--base);
}

.edible-search-form .edible-search-input:focus {
	border-color: var(--wp--preset--color--secondary);
}

.edible-search-form .edible-search-input::placeholder {
	color: var(--wp--preset--color--secondary);
}

/* Loupe: a drawn icon instead of the plugin's emoji. */
.edible-search-form::after {
	content: "";
	right: 1rem;
	width: 1rem;
	height: 1rem;
	background: var(--wp--preset--color--secondary);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
}

.edible-search-form .edible-loading {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--x-small);
}

/* Results dropdown: a card under the input. */
.edible-search-form .edible-search-results-container {
	top: calc(100% + 0.25rem);
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border-light);
	border-radius: var(--wp--preset--border-radius--md);
	box-shadow: var(--wp--preset--shadow--small-dark);
}

.edible-search-form .edible-search-results-container:empty {
	border: 0;
	visibility: hidden;
}

.edible-search-form .edible-search-result-item {
	border-bottom-color: var(--wp--preset--color--border-light);
}

.edible-search-form .edible-search-result-item:hover {
	background: var(--wp--preset--color--tertiary);
}

.edible-search-form .edible-search-result-thumbnail {
	width: 2.5rem;
	height: 2.5rem;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border-light);
	border-radius: var(--wp--preset--border-radius--sm);
}

.edible-search-form .edible-search-result-thumbnail img {
	object-fit: contain;
	padding: 0.25rem;
}

.edible-search-form .edible-search-result-title {
	color: var(--wp--preset--color--main);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
}

.edible-search-form .edible-search-result-excerpt,
.edible-search-form .edible-search-no-results {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--x-small);
}

/* Pipedrive scheduler on single events: the "Book a meeting" group shows only
   when [pipedrive_scheduler] printed its iframe. */
.ts-pipedrive:not(:has(iframe)) {
	display: none;
}

.ts-pipedrive iframe {
	display: block;
	border: 1px solid var(--wp--preset--color--border-light);
	border-radius: var(--wp--preset--border-radius--md);
}

/* Plain eyebrow labels inside mega menu panels (card and strip labels) match
   the column labels ("Eyebrow with rule"). Values per look: settings.custom.menuLabel. */
.is-style-ts-menu-panel .is-style-ts-eyebrow {
	font-family: var(--wp--custom--menu-label--font-family);
	font-weight: var(--wp--custom--menu-label--font-weight);
	letter-spacing: var(--wp--custom--menu-label--letter-spacing);
	text-transform: var(--wp--custom--menu-label--text-transform);
	color: var(--wp--custom--menu-label--color);
}

/* Compare skeleton (pattern ollie-ts/compare-skeleton): in page prose, compare
   table cells keep words whole on phones (break with a hyphen, not mid-word).
---------------------------------------------------------------------------- */

.ts-prose .is-style-ts-compare :is(th, td) {
	word-break: normal;
	overflow-wrap: normal;
	hyphens: auto;
}

/* Phones: compare tables in page text keep readable columns and scroll sideways
   inside their own box (the page itself never scrolls sideways). */
@media (max-width: 781px) {
	.ts-prose > .wp-block-table.is-style-ts-compare {
		overflow-x: auto;
		overscroll-behavior-x: contain;
	}

	.ts-prose > .wp-block-table.is-style-ts-compare > table {
		min-width: 40rem;
	}
}

/* Pattern guide (/pattern-guide/, [ts_pattern_guide] in inc/pattern-guide.php)
   ---------------------------------------------------------------------------
   The shortcode prints a jump bar, one H2 per category (.ts-pg-cat) and one
   section per pattern (.ts-pg-item: a meta header, then the rendered pattern).
   Each item is a full-width constrained box, like the page content, so the
   pattern's own full-width and wide blocks keep their size. */
.wp-block-post-content > .ts-pg-cat {
	margin-block-start: var(--wp--preset--spacing--xx-large);
	padding-block-start: var(--wp--preset--spacing--large);
	border-top: 2px solid var(--wp--preset--color--main);
}

.wp-block-post-content > .ts-pg-item {
	/* Each item is a frame: a pattern that sticks out sideways (the press hero
	   and careers locations art do on phones) must not scroll the guide.
	   "clip", not "hidden", so the sticky section nav still sticks. */
	overflow-x: clip;
	margin-block-start: var(--wp--preset--spacing--x-large);
	padding-block-start: var(--wp--preset--spacing--large);
	border-top: 1px solid var(--wp--preset--color--border-light);
}

.wp-block-post-content > .ts-pg-cat + .ts-pg-item {
	border-top: 0;
	padding-block-start: 0;
}

.ts-pg-meta {
	margin-block-end: var(--wp--preset--spacing--large);
}

.ts-pg-meta > * {
	max-width: 48rem;
	margin-block: 0;
}

.ts-pg-meta > * + * {
	margin-block-start: 0.5rem;
}
