/*
Theme Name:   Astra for Iptanus
Theme URI:    https://www.iptanus.com
Description:  Astra child theme for Iptanus. Exists mainly to carry the two cloud-authorization
              page templates inherited from the old Esteem child theme — without them the
              OneDrive and Facebook connection flows silently stop working — plus the site's
              own styles.
Author:       Iptanus
Author URI:   https://www.iptanus.com
Template:     astra
Version:      1.0.0
License:      GNU General Public License v2 or later
License URI:  http://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  astra-iptanus
*/

/* ---------------------------------------------------------------------------
   Brand tokens, sampled from the real assets rather than guessed:
     --ipt-blue-dark   logo blue      structure: header, footer, headings
     --ipt-blue        bright blue    energy: hero, accents, icons, hover
     --ipt-red         logo red       ACTION ONLY — Go Pro and nothing else
   White on --ipt-red is 3.2:1, so it needs 18px+ semibold. --ipt-red-deep is
   the 5.1:1 fallback if red is ever needed at a smaller size.
   --------------------------------------------------------------------------- */
:root {
	--ipt-blue-dark: #0c5490;
	--ipt-blue-deep: #093f6d;   /* hover state for the wordmark — 10.4:1 on white */
	--ipt-blue-link: #1a63d8;   /* accessible sibling of --ipt-blue: 5.5:1 on white.
	                               --ipt-blue itself is only 4.02:1, under the 4.5:1
	                               minimum for normal-size text, so it is reserved for
	                               large type and filled areas, never link text.
	                               "Filled areas" means the fill ONLY, and only where no
	                               small text sits on top of it: white on #2878ff is
	                               4.02:1, so NOTHING under 24px (or 18.66px bold) is
	                               legible on it at any opacity. That is why the banners
	                               use --ipt-blue-dark, where white reaches 7.82:1. */
	--ipt-blue:      #2878ff;
	--ipt-red:       #f06060;
	--ipt-red-deep:  #c93a3a;
	--ipt-ink:       #16324f;
	--ipt-muted:     #56718c;
	--ipt-line:      #e4edf6;
	--ipt-field:     #f0f5fa;   /* THE PAGE. One field sitewide, on <body>, replacing the two
	                              page-specific rules that used to paint only Docs and Services.
	                              The grey is not decoration: it is what makes a white card BE a
	                              card. Docs articles and news posts already sit on white
	                              <article> cards, so on a white page that card was invisible and
	                              the same component read as a raised surface on one page and as
	                              nothing at all on another.
	                              The surface ladder is exactly three steps, and there is no
	                              fourth: field #f0f5fa -> card #fff -> inset --ipt-surface, where
	                              the inset may only ever appear INSIDE a card. #f2f7fc against
	                              this field is a two-point difference AND lighter than the thing
	                              it sits in, so on the field it is both invisible and inverted.
	                              This exact value is load-bearing, not a preference:
	                              --ipt-muted-light was resolved against it as the worst of its
	                              three backgrounds (4.63:1). A different grey re-opens that. */
	--ipt-red-fill:       #c93a3a; /* red BEHIND WHITE TEXT. --ipt-red is only 3.21:1 with
	                                  white, so it fails the 4.5 minimum on every button
	                                  under 18.66px bold — which was all of them except the
	                                  homepage hero. This is 5.06:1. --ipt-red stays as the
	                                  accent colour for fills that carry no text. */
	--ipt-red-fill-hover: #ad2f2f; /* 6.51:1 — deepens, matching the hover rule. Replaces
	                                  --ipt-red-hover #e04f4f, which was LIGHTER than the
	                                  new fill and would have inverted the hover. */
	--ipt-red-ink:        #b52d2d; /* red AS TEXT, on a pale ground. --ipt-red-fill is a FILL —
	                                  the comment above says so — and it was being used as an ink
	                                  in six places, where it measures 4.49:1 on the red badge's
	                                  own #fdeeee and clears 4.5 only just on the others. A fill
	                                  and an ink are different jobs and now have different tokens.
	                                  5.52 on #fdeeee, 5.59 on the notice #fdf0f0, 5.67 on the
	                                  page field, 6.22 on white — which also puts the red state
	                                  in line with its siblings rather than below them:
	                                  --good 4.58, --wait 5.53. */
	--ipt-muted-light:  #56718c;   /* tertiary text: file hints, dates, counts, percentages.
	                                  Now IDENTICAL to --ipt-muted, and that is the finding,
	                                  not an oversight. It was #7d94ab (3.14:1 on white).
	                                  #5b748d fixed white and --ipt-surface but still missed
	                                  on the page background #f0f5fa (4.42). The lightest
	                                  value clearing 4.5 on all three is #5a738c, which clears
	                                  the worst case by 0.01 — no margin at all.
	                                  So there is no room for a third grey: the accessible
	                                  range between --ipt-muted and unreadable is narrower
	                                  than one perceptible step. Tertiary rank comes from size
	                                  and weight (11-14px against 15-16px), which the CSS
	                                  already does. The token is kept so its ~35 declarations
	                                  keep their intent; a later pass could fold them into
	                                  --ipt-muted. Backgrounds checked: #fff 5.08,
	                                  --ipt-surface 4.71, page bg #f0f5fa 4.63. */
	--ipt-line-strong:  #b9d2ea;   /* dashed dropzone border */
	--ipt-surface:      #f2f7fc;   /* inset panel fill */
}

/* Astra title-cases button labels; respect what was actually written. */
.wp-block-button__link,
.ast-custom-button {
	text-transform: none;
	letter-spacing: 0;
}

/* ---------------------------------------------------------------------------
   Header branding — treat logo + wordmark as ONE target.
   Astra renders them as two separate <a> elements (a.custom-logo-link and an
   anchor inside span.site-title), both pointing home, so hovering either one
   left the other looking inert. Hang the hover state on the shared parent so
   the pair lights up together. :focus-within does the same for keyboard users.

   Hover direction is DEEPEN, never dim — matching the buttons, which darken.
   Fading an element on hover is the visual language of "disabled", and brightening
   the wordmark to --ipt-blue dropped its contrast on white from 7.8:1 to 4.0:1,
   i.e. hovering made it harder to read. Deepening raises contrast instead.
   The logo gets a slight scale rather than an opacity change: movement reads as
   responsive without dimming anything.
   --------------------------------------------------------------------------- */
.site-branding .custom-logo-link img,
.site-branding .site-title a {
	transition: color 0.18s ease, transform 0.18s ease;
}

.site-branding:hover .site-title a,
.site-branding:focus-within .site-title a {
	color: var(--ipt-blue-deep);
}

.site-branding:hover .custom-logo-link img,
.site-branding:focus-within .custom-logo-link img {
	transform: scale(1.04);
}

/* Respect users who have asked for less motion. */
@media (prefers-reduced-motion: reduce) {
	.site-branding .custom-logo-link img,
	.site-branding .site-title a {
		transition: none;
	}
	.site-branding:hover .custom-logo-link img,
	.site-branding:focus-within .custom-logo-link img {
		transform: none;
	}
}

/* ---------------------------------------------------------------------------
   Primary navigation.
   Was inheriting Astra's stock slate (#334155) at body weight in the BODY font,
   so it read as page text rather than site chrome. Montserrat 600 matches the
   headings and gives it presence without enlarging the header, which would
   crowd the Go Pro button.
   --------------------------------------------------------------------------- */
.main-header-menu > .menu-item > .menu-link,
.ast-nav-menu > .menu-item > .menu-link,
.main-header-menu .menu-link {
	font-family: 'Montserrat', sans-serif;
	font-weight: 600;
	font-size: 16px;
	color: var(--ipt-ink);
	transition: color 0.18s ease;
}

/* ---------------------------------------------------------------------------
   The narrowest desktop width.
   Astra's mobile header takes over at 921px, so 1024 is the tightest the full
   row ever gets — and there it squeezed the Go Pro button from 118px to 88px,
   breaking "Go Pro" onto two lines and pushing the header to 161px tall. With
   a cart in the header the chip dropped to a second row instead. Neither
   element should be the one that gives: the menu hands back the space.
   --------------------------------------------------------------------------- */
.ast-custom-button,
.ipt-cart-chip { white-space: nowrap; flex-shrink: 0; }

/* The row needs 845px for eight items at the default 16px of link padding, and stops having it
   just under 1280 — worst case being a signed-in visitor with something in the cart, where
   "My Account" and the cart chip are both present. Two tiers so the type only drops a point at
   the very bottom of the desktop range. */
@media (min-width: 1121px) and (max-width: 1280px) {
	body .main-header-menu > .menu-item > .menu-link { padding-left: 10px; padding-right: 10px; }
}

@media (min-width: 922px) and (max-width: 1120px) {
	body .main-header-menu > .menu-item > .menu-link {
		padding-left: 7px;
		padding-right: 7px;
		font-size: 15px;
	}
	body .ast-header-button-1 .ast-custom-button { padding-left: 20px; padding-right: 20px; font-size: 15px; }
	.ipt-cart-chip { padding-left: 14px; padding-right: 14px; }
}

/* Below 1024 the row runs out of space in one state only: signed in AND holding something, where
   "My Account" and the cart chip are both in the menu. The word "Cart" goes rather than the type
   size — a trolley with a count on it is not ambiguous, and the link keeps its accessible name. */
@media (min-width: 922px) and (max-width: 1023px) {
	body .main-header-menu > .menu-item > .menu-link { padding-left: 5px; padding-right: 5px; }
	.ipt-cart-chip .ipt-cart-chip__t { display: none; }
	.ipt-cart-chip { padding-left: 12px; padding-right: 12px; gap: 6px; }
	.main-header-menu > .ipt-nav-account::before,
	.main-header-menu > .ipt-nav-utility::before { margin-left: 4px; margin-right: 4px; }
	.main-header-menu .ipt-nav-account__my { display: none; }
}

.main-header-menu > .menu-item > .menu-link:hover,
.main-header-menu > .menu-item > .menu-link:focus-visible,
.main-header-menu .menu-item.current-menu-item > .menu-link,
.ast-nav-menu .menu-item.current-menu-item > .menu-link {
	color: var(--ipt-blue-link);
}

/* ---------------------------------------------------------------------------
   Footer.
   Headings were Astra's stock #1e293b; links were the one element already using
   a brand colour. Unified: headings in logo blue, links in ink, both hovering to
   the same accessible blue as the nav so there is ONE interaction language.
   --------------------------------------------------------------------------- */
.ast-builder-footer-grid .widget-title,
.site-footer .widget-title,
.site-footer h2 {
	color: var(--ipt-blue-dark);
	font-family: 'Montserrat', sans-serif;
	font-weight: 600;
}

.site-footer .menu-link,
.site-footer .widget a,
.ast-builder-footer-grid a {
	color: var(--ipt-ink);
	transition: color 0.18s ease;
}

.site-footer .menu-link:hover,
.site-footer .widget a:hover,
.ast-builder-footer-grid a:hover,
.site-footer .menu-link:focus-visible,
.site-footer .widget a:focus-visible {
	color: var(--ipt-blue-link);
}

/* ===========================================================================
   HOME / LANDING SECTIONS
   Moved here from an inline <style> inside the homepage's own content. Living
   in the theme means these sections can be reused on any page, survive the
   homepage being rebuilt, and stay editable in one place.

   Class prefix `ipt-` is applied per block in the editor, so nothing here
   affects a page that does not opt in.
   =========================================================================== */

/* Astra's page-builder template strips width constraints from full-width blocks:
     .ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull > *
     { max-width: none }
   That is specificity 0,4,0 and beats both a plain class and core's own
   constrained-layout rule, so a block's contentSize is silently ignored.
   These selectors sit one class higher (0,5,0) to win. */
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-hero > *,
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-proof > *,
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-features > *,
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-services > * {
	max-width: 1140px;
	margin-left: auto;
	margin-right: auto;
}

/* The docs hub sits on the wider documentation measure: the design is 1440 with
   100px of padding each side, the same 1240 the article page's three columns add up to. */
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-kb-hero > *,
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-kb-body > * {
	max-width: 1240px;
	margin-left: auto;
	margin-right: auto;
}

/* ---- hero ---------------------------------------------------------------- */
.ipt-hero { color: #fff; }

.ipt-eyebrow {
	display: inline-block;
	background: rgba(255, 255, 255, 0.16);
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	padding: 7px 13px;
	border-radius: 4px;
	margin: 0 0 22px;
}

.ipt-hero .ipt-h1 {
	color: #fff;
	font-size: 50px;
	line-height: 1.1;
	font-weight: 800;
	margin: 0;
	text-wrap: pretty;
}

.ipt-hero .ipt-sub {
	color: rgba(255, 255, 255, 0.92);
	font-size: 19px;
	line-height: 1.55;
	margin: 20px 0 0;
	max-width: 540px;
}

/* ---- calls to action ----------------------------------------------------- */
.ipt-cta { margin-top: 32px; gap: 14px; }

.ipt-cta .wp-block-button__link {
	font-size: 19px;      /* >=18px semibold, which is what keeps white-on-red legible */
	font-weight: 700;
	padding: 15px 30px;
	border-radius: 7px;
}

.ipt-btn-primary .wp-block-button__link {
	background: var(--ipt-red-fill);
	color: #fff;
	border: 0;
}
.ipt-btn-primary .wp-block-button__link:hover,
.ipt-btn-primary .wp-block-button__link:focus {
	background: var(--ipt-red-fill-hover);
	color: #fff;
}

.ipt-btn-ghost .wp-block-button__link {
	background: transparent;
	color: #fff;
	border: 2px solid rgba(255, 255, 255, 0.55);
	font-weight: 600;
}
.ipt-btn-ghost .wp-block-button__link:hover,
.ipt-btn-ghost .wp-block-button__link:focus {
	background: rgba(255, 255, 255, 0.12);
	color: #fff;
	border-color: #fff;
}

/* ---- upload mockup ------------------------------------------------------- */
.ipt-mock {
	background: #fff;
	border-radius: 12px;
	box-shadow: 0 18px 44px rgba(4, 32, 64, 0.24);
	overflow: hidden;
	color: var(--ipt-ink);
}
.ipt-mock__bar {
	background: var(--ipt-surface);
	padding: 13px 18px;
	border-bottom: 1px solid var(--ipt-line);
	font-size: 13px;
	font-weight: 600;
	color: var(--ipt-muted);
}
.ipt-mock__body  { padding: 22px 18px 24px; }
.ipt-mock__drop  { border: 2px dashed var(--ipt-line-strong); border-radius: 9px; padding: 30px 16px; text-align: center; }
.ipt-mock__drop strong { display: block; font-size: 15px; color: var(--ipt-ink); font-weight: 600; }
.ipt-mock__drop span   { display: block; font-size: 13px; color: var(--ipt-muted-light); margin-top: 4px; }
.ipt-mock__row   { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.ipt-mock__track { flex-grow: 1; height: 7px; background: var(--ipt-line); border-radius: 4px; overflow: hidden; }
.ipt-mock__fill  { width: 72%; height: 100%; background: var(--ipt-blue); }
.ipt-mock__pct   { font-size: 12px; color: var(--ipt-muted-light); font-weight: 600; }
.ipt-mock__file  { font-size: 13px; color: var(--ipt-muted); margin-top: 9px; }

/* ---- proof strip --------------------------------------------------------- */
.ipt-proof { border-bottom: 1px solid var(--ipt-line); }
.ipt-proof p { margin: 0; font-size: 15px; color: var(--ipt-ink); text-align: center; }
.ipt-proof strong { font-weight: 700; }

/* ---- feature cards ------------------------------------------------------- */
.ipt-features h2 {
	font-size: 32px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	text-align: center;
	margin: 0;
}
.ipt-card {
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 26px 24px 28px;
	height: 100%;
}
.ipt-card h3 { font-size: 20px; font-weight: 700; color: var(--ipt-ink); margin: 14px 0 0; }
.ipt-card p  { font-size: 16px; line-height: 1.6; color: var(--ipt-muted); margin: 9px 0 0; }

/* ---- services band ------------------------------------------------------- */
.ipt-services { color: #fff; }
.ipt-services h2 { font-size: 28px; font-weight: 700; color: #fff; margin: 0; }
.ipt-services p  { font-size: 17px; line-height: 1.6; color: rgba(255, 255, 255, 0.86); margin: 12px 0 0; }
.ipt-services .wp-block-button__link {
	background: #fff;
	color: var(--ipt-blue-dark);
	font-size: 17px;
	font-weight: 700;
	padding: 14px 26px;
	border-radius: 7px;
	border: 0;
}
.ipt-services .wp-block-button__link:hover,
.ipt-services .wp-block-button__link:focus {
	background: #eaf2fb;
	color: var(--ipt-blue-dark);
}

/* ---- narrow screens ------------------------------------------------------ */
@media (max-width: 921px) {
	.ipt-hero .ipt-h1  { font-size: 36px; }
	.ipt-hero .ipt-sub { font-size: 17px; }
	.ipt-features h2   { font-size: 26px; }
	.ipt-proof p       { text-align: left; }
}

/* ---------------------------------------------------------------------------
   "Login" is an account utility, not a destination like Docs or Services.
   Demote it so the six real nav items read as one group and it sits apart.
   --------------------------------------------------------------------------- */
.main-header-menu > .ipt-nav-utility > .menu-link {
	font-size: 14px;
	font-weight: 500;
	color: var(--ipt-muted);
}
.main-header-menu > .ipt-nav-utility > .menu-link:hover,
.main-header-menu > .ipt-nav-utility > .menu-link:focus-visible {
	color: var(--ipt-blue-link);
}
/* hairline separating the utility link from the navigation proper */
.main-header-menu > .ipt-nav-utility {
	position: relative;
	margin-left: 6px;
	padding-left: 16px;
}
.main-header-menu > .ipt-nav-utility::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 1px;
	height: 18px;
	background: var(--ipt-line);
}
/* the separator is desktop chrome; the off-canvas menu is a plain stack */
#ast-mobile-site-navigation .ipt-nav-utility { margin-left: 0; padding-left: 0; }
#ast-mobile-site-navigation .ipt-nav-utility::before { display: none; }

/* ---------------------------------------------------------------------------
   Feature cards.
   They were white cards, on a white page, behind a 1px near-white border —
   the flattest thing on the page, so this section carried its own tint to
   separate them. The page field now does that job for every card on the site,
   which is the whole point of it, so the section fills with NOTHING and lets
   the field through. Re-tinting here would put a lighter band on the field and
   flatten the cards a second time — the exact bug the tint was added to fix.
   The hover that lifts (deepen, never dim) stays.
   --------------------------------------------------------------------------- */

.ipt-card {
	background: #fff;
	transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.ipt-card:hover {
	border-color: #c9dcf0;
	box-shadow: 0 10px 28px rgba(12, 84, 144, 0.10);
	transform: translateY(-2px);
}

/* Give the icon a tinted tile so it carries weight against the card. */
.ipt-card > svg {
	display: block;
	box-sizing: content-box;
	padding: 9px;
	background: var(--ipt-surface);
	border-radius: 9px;
	transition: background 0.18s ease;
}
.ipt-card:hover > svg { background: #e3edf9; }

@media (prefers-reduced-motion: reduce) {
	.ipt-card, .ipt-card > svg { transition: none; }
	.ipt-card:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   Buttons sitting ON a coloured background.
   "Deepen" has no meaning against blue or navy, so these invert instead:
   the outline fills solid and the label flips to the background colour.
   Same intent — the control becomes MORE definite on hover, never dimmer.
   --------------------------------------------------------------------------- */
.ipt-btn-ghost .wp-block-button__link:hover,
.ipt-btn-ghost .wp-block-button__link:focus {
	background: #fff;
	color: var(--ipt-blue-link);
	border-color: #fff;
}

/* Logged-in account entry: same demoted treatment as the logged-out Login link,
   so the header reads identically in both states. Which of the two appears is
   decided in PHP (see functions.php), not by hiding one with CSS. */
.main-header-menu > .ipt-nav-account > .menu-link {
	font-size: 14px;
	font-weight: 500;
	color: var(--ipt-muted);
}
.main-header-menu > .ipt-nav-account > .menu-link:hover,
.main-header-menu > .ipt-nav-account > .menu-link:focus-visible,
.main-header-menu > .ipt-nav-account:hover > .menu-link {
	color: var(--ipt-blue-link);
}
.main-header-menu > .ipt-nav-account {
	position: relative;
	margin-left: 6px;
	padding-left: 16px;
}
.main-header-menu > .ipt-nav-account::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 1px;
	height: 18px;
	background: var(--ipt-line);
}
#ast-mobile-site-navigation .ipt-nav-account { margin-left: 0; padding-left: 0; }
#ast-mobile-site-navigation .ipt-nav-account::before { display: none; }

/* Log out is a destructive-ish action — give it the deep red, not the link blue. */
.ipt-nav-logout > .menu-link:hover,
.ipt-nav-logout > .menu-link:focus-visible {
	color: var(--ipt-red-deep);
}

/* ===========================================================================
   ARTICLE / DOCUMENTATION PAGES
   Applies to posts and ordinary pages — everything EXCEPT page-builder
   templates, so the homepage and other built landing pages are untouched.

   These pages carry 61% of the site's organic clicks, so readability here
   matters more than anywhere else on the site.
   =========================================================================== */

/* ---- title and byline ---------------------------------------------------- */
body:not(.ast-page-builder-template) .entry-title {
	font-family: 'Montserrat', sans-serif;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	line-height: 1.2;
	text-wrap: pretty;
}

body:not(.ast-page-builder-template) .entry-meta,
body:not(.ast-page-builder-template) .entry-meta a {
	font-size: 14px;
	color: var(--ipt-muted-light);
}
body:not(.ast-page-builder-template) .entry-meta a:hover {
	color: var(--ipt-blue-link);
}

/* ---- body copy -----------------------------------------------------------
   `:not(.woocommerce-page)` is not decoration. These selectors sit at (0,2,2),
   which outranks any single-class page rule, and every WooCommerce screen —
   cart, checkout, order-pay, order-received, the product page — renders inside
   .entry-content. That collision cost eight separate defects: a breadcrumb at
   1.42:1, a download button at 1.09:1, 49px of stray margin above a card
   heading, and 42px of list indent inside a summary column, among others. A
   shop screen is not an article; it opts out here once instead of every
   component in it fighting the same rule.
   -------------------------------------------------------------------------- */
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content {
	font-size: 17px;      /* 16px sat at ~85 characters per line, above the
	                         comfortable 65-75; 17px brings the measure down
	                         and lifts legibility on long technical pages */
	line-height: 1.75;
	color: var(--ipt-ink);
}

body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content p { margin: 0 0 1.15em; }

body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h2,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h3,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h4 {
	font-family: 'Montserrat', sans-serif;
	color: var(--ipt-blue-dark);
	line-height: 1.25;
	text-wrap: pretty;
}
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h2 { font-size: 26px; font-weight: 700; margin: 1.9em 0 0.6em; }
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h3 { font-size: 21px; font-weight: 600; margin: 1.6em 0 0.5em; }
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h4 { font-size: 18px; font-weight: 600; margin: 1.4em 0 0.4em; }

/* Links in prose need to be unmistakable without shouting. */
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content a {
	color: var(--ipt-blue-link);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 2px;
	transition: color 0.15s ease;
}
/* ...which is what the rule above intends, but Astra also sets font-weight 700 on them, so a
   prose link arrived with THREE signals — colour, underline and bold — where two say it
   unmistakably. The third is not free: these articles use <strong> for the terms that carry
   the meaning ("Content Management Systems", "Personal Data"), and a 700 link outshouts real
   emphasis. The GDPR article has nineteen links in its opening screens and reads as a page of
   bold text.

   Scoped by :not([class]) rather than by element. Across all 51 technical articles there are
   384 bare prose links and exactly one carrying a class — a call-to-action — so the test
   separates prose from designed components precisely, and every button, chip and card link
   keeps whatever weight its own rule gives it. */
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content p > a:not([class]),
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content li > a:not([class]) {
	font-weight: 400;
}
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content a:hover {
	color: var(--ipt-blue-deep);
	text-decoration-thickness: 2px;
}

body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content ul,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content ol { margin: 0 0 1.15em 1.3em; }
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content li { margin-bottom: 0.5em; }

/* ---- the gap between paragraphs -------------------------------------------
   Astra's 1.15em came to 19.55px against a 29.75px line — 0.66 of a line. With
   no indents, that break is the ONLY thing separating one idea from the next,
   and at 0.66 it is narrower than the space inside the paragraph on a wrapped
   line, so on a screen of solid prose the boundaries stop registering. That
   matters most on the twelve articles that also have no headings.

   1.53em = 26px = 0.875 of a line: a clear break without opening a hole. Kept
   in em so it holds if the body size ever moves.

   Direct children only. A <p> nested inside a component — the option
   reference, a card, a blockquote — carries its own spacing.
   -------------------------------------------------------------------------- */
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content > p { margin-bottom: 1.53em; }

/* Screenshots are the main illustration on these pages — give them an edge so
   they read as artefacts rather than floating on the page. */
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content img {
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	max-width: 100%;
	height: auto;
}
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content img.aligncenter { display: block; margin: 1.6em auto; }

body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content blockquote {
	margin: 1.6em 0;
	padding: 2px 0 2px 20px;
	border-left: 3px solid var(--ipt-blue);
	color: var(--ipt-muted);
}

body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content pre,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content code {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 6px;
	font-size: 0.92em;
}
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content code { padding: 1px 5px; }
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content pre  { padding: 14px 16px; overflow-x: auto; }
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content pre code { background: none; border: 0; padding: 0; }

/* ---- justification -------------------------------------------------------
   The content was set to text-align: justify with hyphens off. At a ~630px
   measure that forces large word gaps ("rivers") and is measurably harder to
   read. Ragged-right is the correct default for body text on the web.
   -------------------------------------------------------------------------- */
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content p,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content li,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h1,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h2,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h3,
body:not(.ast-page-builder-template):not(.woocommerce-page) .entry-content h4 {
	text-align: left;
}

/* ---------------------------------------------------------------------------
   Inline text-align: justify baked into the content.
   1,368 occurrences across 105 posts and 13 pages. Inline styles beat any
   stylesheet rule, so this needs !important — but it is targeted by attribute
   so it ONLY neutralises justify. Elements deliberately centred (captions,
   CTAs) keep their alignment.

   This is a patch over content pollution, not a fix. The proper repair is to
   strip the inline styles from the database — see PLAN.md.
   --------------------------------------------------------------------------- */
body:not(.ast-page-builder-template) .entry-content [style*="justify"],
body:not(.ast-page-builder-template) .entry-content[style*="justify"] {
	text-align: left !important;
}

/* ---------------------------------------------------------------------------
   Short answer.
   Sits above the article for someone who arrived from a search and wants the
   fix before the explanation. Blue rule rather than a coloured fill, so it
   reads as part of the document rather than an advert.
   --------------------------------------------------------------------------- */
.ipt-short-answer {
	/* an inset: it sits inside the article card, which is the only place the inset fill is
	   allowed to appear */
	background: var(--ipt-surface);
	border: 1px solid #d3e3f5;
	border-left: 4px solid var(--ipt-blue);
	border-radius: 8px;
	padding: 18px 22px 20px;
	margin: 0 0 28px;
}
.ipt-short-answer__label {
	font-family: 'Montserrat', sans-serif;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ipt-blue-link);
}
.ipt-short-answer__text {
	font-size: 17px;
	line-height: 1.6;
	color: var(--ipt-ink);
	margin: 8px 0 0 !important;
}
.ipt-short-answer__text a { color: var(--ipt-blue-link); }
.ipt-short-answer__text code {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 5px;
	padding: 1px 5px;
	font-size: 0.92em;
}

/* Headings wrap more evenly instead of leaving a single orphaned word on the
   last line. Cheap, and it makes long-but-legitimate headings behave. */
body:not(.ast-page-builder-template) .entry-content h2,
body:not(.ast-page-builder-template) .entry-content h3,
body:not(.ast-page-builder-template) .entry-title {
	text-wrap: balance;
}

/* ===========================================================================
   DOCUMENTATION LAYOUT — three columns, per the published design
     240px navigation | 660px article | 260px contents rail, 40px gaps
   Astra's "narrow container" caps the shell at 750px, which squeezed the
   article to 417px of text. Scoped to .ipt-doc so nothing else is affected.
   =========================================================================== */
.ipt-doc .site-content > .ast-container {
	max-width: 1240px;
	display: grid;
	grid-template-columns: 240px minmax(0, 660px) 260px;
	gap: 40px;
	align-items: start;
}
.ipt-doc #secondary,
.ipt-doc #primary,
.ipt-doc .ipt-rail { width: auto; max-width: none; margin: 0; padding: 0; float: none; }

/* Astra's sidebar divider, which this layout has no use for.
   The `ast-left-sidebar` template draws a 1px #d1d5db rule on the right of #secondary and the
   left of #primary, to separate two columns that used to sit flush against each other. This
   layout is a grid with a 40px gutter and a bordered article card, so the columns are already
   separated — and because #primary is as tall as the article while the sidebar ends with its
   last menu item, the line ran 1,128px past anything it could be dividing: a rule down an
   empty gutter, ending nowhere.

   #d1d5db is also a neutral grey with no blue in it, the same foreign value already corrected
   on the header and the footer. Removed rather than recoloured: the gap is the separator. */
.ipt-doc #secondary,
.ipt-doc #primary,
.ipt-doc #secondary .sidebar-main { border: 0; }
.ipt-doc #secondary { order: 1; }
.ipt-doc #primary   { order: 2; }
.ipt-doc .ipt-rail  { order: 3; }

.ipt-doc .ast-separate-container .ast-article-single,
.ipt-doc .ast-article-single {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 40px 44px 44px;
	margin: 0;
}

/* ---- left: documentation navigation -------------------------------------- */
.ipt-doc #secondary .widget { margin-bottom: 22px; }
.ipt-doc #secondary .widget-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted-light);
	margin: 0 0 12px;
}
.ipt-doc #secondary .widget_nav_menu ul { list-style: none; margin: 0; padding: 0; }
.ipt-doc #secondary .widget_nav_menu li { margin: 0; border: 0; }

/* a top-level item with children is a GROUP LABEL, not a link */
.ipt-doc #secondary .menu-item-has-children > a {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted-light);
	padding: 0;
	margin: 22px 0 8px;
	pointer-events: none;
}
.ipt-doc #secondary .menu-item-has-children:first-child > a { margin-top: 0; }

.ipt-doc #secondary .sub-menu { display: block !important; position: static !important;
	opacity: 1 !important; visibility: visible !important; box-shadow: none; background: none;
	width: auto; border: 0; transform: none !important; }
.ipt-doc #secondary .sub-menu a {
	display: block;
	font-size: 15px;
	line-height: 1.35;
	color: var(--ipt-ink);
	padding: 5px 0;
	border: 0;
	transition: color 0.15s ease;
}
.ipt-doc #secondary .sub-menu a:hover,
.ipt-doc #secondary .sub-menu a:focus-visible { color: var(--ipt-blue-link); }

.ipt-doc #secondary .sub-menu .current-menu-item > a {
	font-weight: 700;
	color: var(--ipt-blue-link);
	border-left: 3px solid var(--ipt-blue-link);
	padding-left: 11px;
	margin-left: -14px;
}
/* Astra draws submenu arrows and hover panels; neither belongs in a docs index. */
.ipt-doc #secondary .ast-menu-toggle,
.ipt-doc #secondary .sub-arrow { display: none !important; }

/* ---- right: contents rail ------------------------------------------------ */
.ipt-rail { display: flex; flex-direction: column; gap: 18px; }
.ipt-rail__card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 18px 20px;
}
.ipt-rail__label {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted-light);
}
.ipt-toc__list { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.ipt-toc__item a {
	display: block;
	font-size: 14px;
	line-height: 1.4;
	color: var(--ipt-muted);
	border-left: 2px solid var(--ipt-line);
	padding-left: 10px;
	text-decoration: none;
	transition: color 0.15s ease, border-color 0.15s ease;
}
.ipt-toc__item a:hover,
.ipt-toc__item.is-current a {
	color: var(--ipt-blue-link);
	border-left-color: var(--ipt-blue-link);
	font-weight: 600;
}
.ipt-toc__item--h3 a { padding-left: 20px; }

/* The comment thread is a different kind of destination from the article's
   sections, so it sits below the list rather than in it: hairline above, no left
   rule, quieter colour. Hover deepens to link blue and the icon follows the text
   via currentColor. */
.ipt-toc__thread {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 14px;
	padding-top: 13px;
	border-top: 1px solid var(--ipt-line);
	font-size: 14px;
	line-height: 1.4;
	color: var(--ipt-muted-light);
	text-decoration: none;
	transition: color 0.15s ease;
}
.ipt-toc__thread svg { flex-shrink: 0; }
.ipt-toc__thread:hover,
.ipt-toc__thread:focus-visible { color: var(--ipt-blue-link); }

/* Stays a white card like its siblings. It used to be tinted to stand apart from them; on the
   field that tint would sink INTO the page instead, so the stronger border does the separating. */
.ipt-rail__help { border-color: #d3e3f5; }
.ipt-rail__help-title { font-family: 'Montserrat', sans-serif; font-size: 16px; font-weight: 700; color: var(--ipt-blue-dark); }
.ipt-rail__help-text  { font-size: 14px; line-height: 1.55; color: var(--ipt-muted); margin: 6px 0 0; }
.ipt-rail__help-link {
	display: block;
	margin-top: 12px;
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 9px 14px;
	font-size: 14px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-align: center;
	text-decoration: none;
}
.ipt-rail__help-link:hover { background: #eef4fb; }

/* ---- article typography at the designed sizes ---------------------------- */
.ipt-doc .entry-title { font-size: 38px; font-weight: 700; line-height: 1.15; }
.ipt-doc .entry-content { font-size: 17px; line-height: 1.75; }
.ipt-doc .entry-content h2 { font-size: 26px; margin-top: 34px; }

@media (max-width: 1199px) {
	.ipt-doc .site-content > .ast-container { grid-template-columns: 220px minmax(0, 1fr); }
	.ipt-doc .ipt-rail { display: none; }
}
@media (max-width: 921px) {
	.ipt-doc .site-content > .ast-container { grid-template-columns: minmax(0, 1fr); }
	.ipt-doc #secondary { order: 3; }
}

/* The grid must measure 1240px INSIDE its padding, otherwise Astra's container
   padding steals 40px and the article column lands at 620 instead of 660. */
.ipt-doc .site-content > .ast-container {
	padding-left: 0;
	padding-right: 0;
	box-sizing: content-box;
}
/* Astra gives the widget area its own width; let the grid track decide. */
.ipt-doc #secondary,
.ipt-doc #secondary .sidebar-main { width: 100%; }

/* Breadcrumb above the article, as in the design. */
.ipt-crumbs {
	grid-column: 1 / -1;
	order: 0;
	font-size: 14px;
	color: var(--ipt-muted);
	margin: 0 0 4px;
}
.ipt-crumbs a { color: var(--ipt-muted); text-decoration: none; }
.ipt-crumbs a:hover { color: var(--ipt-blue-link); }
/* Presentational punctuation, and marked aria-hidden in the markup to say so — the trail is
   carried by the links, not by the slashes. It was --ipt-line-strong, which is a BORDER colour:
   1.42:1 against the field, i.e. very nearly not drawn at all. A separator still has to be seen
   to do its job, so this is deepened to 3.16:1 on the field and 3.47:1 on a card — visible, and
   still clearly subordinate to the links either side of it. */
.ipt-crumbs__sep { color: #6a8db0; margin: 0 6px; }
.ipt-crumbs__here { color: var(--ipt-ink); }

/* ---- blocks below a documentation article -------------------------------- */
.ipt-convert, .ipt-helpful, .ipt-updown { margin-top: 22px; }

.ipt-convert {
	background: var(--ipt-blue-dark);
	border-radius: 12px;
	padding: 30px 36px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 30px;
}
.ipt-convert__title { font-family: 'Montserrat', sans-serif; font-size: 21px; font-weight: 700; color: #fff; margin: 0; }
.ipt-convert__text  { font-size: 16px; line-height: 1.6; color: rgba(255,255,255,.86); margin: 8px 0 0; max-width: 400px; }
.ipt-convert__act   { display: flex; flex-direction: column; gap: 9px; flex-shrink: 0; align-items: center; }
.ipt-convert__btn {
	background: var(--ipt-red-fill); color: #fff; font-size: 18px; font-weight: 700;
	padding: 14px 26px; border-radius: 7px; text-decoration: none; white-space: nowrap;
}
.ipt-convert__btn:hover, .ipt-convert__btn:focus { background: var(--ipt-red-fill-hover); color: #fff; }
.ipt-convert__note { font-size: 14px; color: rgba(255,255,255,.7); }

.ipt-helpful {
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 12px;
	padding: 20px 28px; display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.ipt-helpful__q { font-size: 16px; color: var(--ipt-ink); }
.ipt-helpful__buttons { display: flex; gap: 10px; }
.ipt-helpful__btn {
	background: #fff; border: 1px solid #d3e3f5; border-radius: 6px; padding: 8px 18px;
	font-family: inherit; font-size: 15px; font-weight: 600; color: var(--ipt-ink); cursor: pointer;
}
.ipt-helpful__btn:hover, .ipt-helpful__btn:focus {
	/* the background is stated even though it does not change much: Astra's global
	   `button:hover,button:focus{color:#fff;background:#2878ff}` fills in whichever of the
	   two a component rule omits, and omitting it here gave blue text on a blue fill. */
	background: #eef4fb;
	border-color: var(--ipt-blue-link);
	color: var(--ipt-blue-link);
}

.ipt-updown { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.ipt-updown__card {
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px;
	padding: 16px 20px; text-decoration: none; display: block;
}
.ipt-updown__card:hover { border-color: #c9dcf0; }
.ipt-updown__card--next { text-align: right; }
.ipt-updown__label { display: block; font-size: 13px; color: var(--ipt-muted-light); }
.ipt-updown__title { display: block; font-size: 16px; font-weight: 600; color: var(--ipt-blue-link); margin-top: 3px; }

/* ---- comment thread ------------------------------------------------------
   Astra gives each comment body the class `entry-content`, so the article
   typography set earlier (17px / 1.75) was being applied to every comment and
   inflating the thread. These rules target Astra's real comment classes and
   reset that inheritance.
   -------------------------------------------------------------------------- */
/* #comments is the wrapper for the whole discussion area, not a card: the design
   stacks a discussions card and an "Ask a question" card as siblings on the page
   background, each with its own border. */
.ipt-thread #comments {
	background: transparent;
	border: 0;
	padding: 0;
	margin-top: 22px;
}
.ipt-thread .ipt-comments-card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 26px 28px 22px;
}
.ipt-thread .comments-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; color: var(--ipt-ink); margin: 0 0 18px;
}
.ipt-thread .ast-comment-list { margin: 0; padding: 0; }
.ipt-thread .ast-comment-list li.comment { padding: 0; margin: 0; }
.ipt-thread .ast-comment-list .children { padding-left: 34px; margin: 0; }

.ipt-thread .ast-comment {
	padding: 0 0 16px;
	margin: 0;
	border-bottom: 0;
}

/* One rule per DISCUSSION, not per comment: replies inside a thread belong to
   the comment above them, so a line between them breaks the thread up visually. */
.ipt-thread .ast-comment-avatar-wrap img { width: 36px; height: 36px; border-radius: 50%; }
.ipt-thread .ast-comment-meta,
.ipt-thread .ast-comment-meta a { font-size: 13px; color: var(--ipt-muted-light); text-decoration: none; }

/* reset the article typography that leaks in through `entry-content` */
.ipt-thread .ast-comment-content.entry-content {
	font-size: 15px;
	line-height: 1.6;
	color: var(--ipt-muted);
	margin-top: 2px;
}
.ipt-thread .ast-comment-content.entry-content p { margin: 0 0 0.6em; font-size: 15px; line-height: 1.6; }
.ipt-thread .ast-comment-content.entry-content p:last-child { margin-bottom: 0; }
.ipt-thread .ast-comment-edit-reply-wrap a { font-size: 13px; font-weight: 600; color: var(--ipt-blue-link); }

/* an Iptanus answer should be findable without reading the whole thread */

.ipt-thread .comment-navigation,
.ipt-thread .navigation.comment-navigation {
	display: flex; align-items: center; justify-content: space-between;
	margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--ipt-line);
	font-size: 14px; color: var(--ipt-muted-light);
}
.ipt-thread .comment-navigation a {
	border: 1px solid #d3e3f5; border-radius: 6px; padding: 6px 13px;
	font-size: 15px; font-weight: 600; color: var(--ipt-blue-link); text-decoration: none;
}
.ipt-thread .comment-respond {
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 12px;
	padding: 24px 28px; margin-top: 22px;
}
.ipt-thread .comment-reply-title { font-family: 'Montserrat', sans-serif; font-size: 17px; font-weight: 700; color: var(--ipt-ink); }

/* Design values Astra was overriding. The theme sets the single-post title from
   its own typography options, which beat a plain class selector. */
.ipt-doc.single .ast-article-single .entry-title,
.ipt-doc.page .ast-article-single .entry-title,
.ipt-doc .ast-article-single > .entry-title,
.ipt-doc h1.entry-title {
	font-size: 38px;
	line-height: 1.15;
	font-weight: 700;
	color: var(--ipt-blue-dark);
}
.ipt-short-answer { padding: 18px 20px; }

/* byline: dot separators, as designed */
.ipt-doc .ipt-meta { display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--ipt-muted-light); margin-top: 14px; }
.ipt-doc .ipt-meta__dot { width: 3px; height: 3px; border-radius: 50%; background: #b9d2ea; display: inline-block; }

/* Astra applies a 64px top margin to #primary, which dropped the article column
   below both rails — the three grid tracks must start on the same line.
   Needs this specificity: the earlier `margin: 0` was overridden downstream. */
.ipt-doc .site-content > .ast-container > #primary,
.ipt-doc #primary.content-area {
	margin-top: 0;
}

/* Breadcrumb spacing, per the design: 18px below the header, 22px above the
   columns. The grid's 40px gap applies to ROWS too, so it was adding itself to
   the breadcrumb's margin (44px instead of 22). Row gap is zeroed and the
   spacing is carried by the breadcrumb's own margin. */
.ipt-doc .site-content > .ast-container {
	column-gap: 40px;
	row-gap: 0;
}
.ipt-crumbs { margin: 18px 0 22px; }

/* Docs search field, per the design: icon + field on one row inside a single
   bordered box — 8px gap, 9px/12px padding, 8px radius. */
.ipt-doc #secondary .widget_search { margin-bottom: 22px; }
.ipt-doc .ipt-search {
	display: flex;
	align-items: center;
	gap: 8px;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	padding: 9px 12px;
}
.ipt-doc .ipt-search:focus-within { border-color: var(--ipt-blue); }
.ipt-doc .ipt-search__icon { color: var(--ipt-muted-light); flex-shrink: 0; display: block; }
.ipt-doc .ipt-search__field {
	flex: 1 1 auto;
	min-width: 0;
	border: 0;
	background: transparent;
	padding: 0;
	font-family: inherit;
	font-size: 14px;
	line-height: 1.4;
	color: var(--ipt-ink);
	box-shadow: none;
}
.ipt-doc .ipt-search__field::placeholder { color: var(--ipt-muted-light); opacity: 1; }
.ipt-doc .ipt-search__field:focus { outline: none; box-shadow: none; background: transparent; }
.ipt-doc .ipt-search__field::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ---- comment pagination, per the design ---------------------------------- */
.ipt-thread #comment-nav-above { display: none; }   /* the design shows it once, below */

.ipt-thread .ipt-cpag {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	margin-top: 24px;
	padding-top: 18px;
	border-top: 1px solid var(--ipt-line);
}
.ipt-thread .ipt-cpag__count { font-size: 14px; color: var(--ipt-muted-light); }
.ipt-thread .ipt-cpag__links { display: flex; align-items: center; gap: 6px; }

.ipt-thread .ipt-cpag .page-numbers {
	min-width: 34px;
	text-align: center;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 6px 0;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
	display: inline-block;
	line-height: 1.4;
}
.ipt-thread .ipt-cpag a.page-numbers:hover { background: #eef4fb; }
.ipt-thread .ipt-cpag .page-numbers.current {
	background: var(--ipt-blue-link);
	border-color: var(--ipt-blue-link);
	color: #fff;
	font-weight: 700;
	padding: 7px 0;
}
.ipt-thread .ipt-cpag .prev.page-numbers,
.ipt-thread .ipt-cpag .next.page-numbers { padding: 6px 13px; min-width: 0; }
.ipt-thread .ipt-cpag .dots { border: 0; color: var(--ipt-muted-light); }

/* ---- comments: against Astra's REAL markup ------------------------------
   Astra renders the author inside .ast-comment-cite-wrap > cite; my earlier
   selectors (.ast-comment-author-name) matched nothing, so neither the name
   styling nor the badge ever applied.
   -------------------------------------------------------------------------- */
.ipt-thread .ast-comment-avatar-wrap img { width: 36px; height: 36px; border-radius: 50%; }
.ipt-thread .ast-comment-cite-wrap cite {
	font-style: normal;
	font-size: 15px;
	font-weight: 700;
	color: var(--ipt-ink);
}
.ipt-thread .ast-comment-time .timendate,
.ipt-thread .ast-comment-time a { font-size: 13px; color: var(--ipt-muted-light); text-decoration: none; }

/* an Iptanus answer, findable at a glance in a long thread */
.ipt-thread li.bypostauthor > .ast-comment .ast-comment-cite-wrap cite::after {
	content: "Iptanus";
	display: inline-block;
	margin-left: 8px;
	background: #eef4fb;
	color: var(--ipt-blue-link);
	font-family: 'Montserrat', sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	padding: 2px 7px;
	border-radius: 3px;
	vertical-align: middle;
}

/* ---- comment form, per the design --------------------------------------- */
.ipt-thread .comment-respond .ipt-form-note { font-size: 14px; color: var(--ipt-muted-light); margin: 3px 0 16px; }
.ipt-thread .comment-respond textarea,
.ipt-thread .comment-respond input[type="text"],
.ipt-thread .comment-respond input[type="email"],
.ipt-thread .comment-respond input[type="url"] {
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	font-size: 15px;
	color: var(--ipt-ink);
	background: #fff;
	box-shadow: none;
}
.ipt-thread .comment-respond textarea:focus,
.ipt-thread .comment-respond input:focus { border-color: var(--ipt-blue); outline: none; box-shadow: none; }

/* the design's action is an outlined button, not a filled blue slab */
.ipt-thread .comment-respond #submit,
.ipt-thread .comment-respond .submit {
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 9px 20px;
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-transform: none;
	letter-spacing: 0;
}
.ipt-thread .comment-respond #submit:hover,
.ipt-thread .comment-respond .submit:hover { background: #eef4fb; border-color: var(--ipt-blue-link); color: var(--ipt-blue-link); }

/* Astra caps comment avatars with max-width: 2.5em, which resolved to 32.875px
   and overrode the 36px the design specifies. */
.ipt-thread .ast-comment-avatar-wrap img { max-width: 36px; width: 36px; height: 36px; }

/* ---- "Ask a question" prompt --------------------------------------------
   Design: one row, heading + note left, outlined button right.
   padding 22px 28px, radius 12px, border #e4edf6 — the form stays hidden
   until the button is pressed.
   -------------------------------------------------------------------------- */
.ipt-askprompt {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 22px 28px;
	margin-top: 16px;
}
.ipt-askprompt__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 17px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin: 0;
}
.ipt-askprompt__note {
	font-size: 14px;
	color: var(--ipt-muted-light);
	margin: 3px 0 0;
}
.ipt-askprompt__btn {
	flex-shrink: 0;
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 9px 20px;
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease;
}
.ipt-askprompt__btn:hover,
.ipt-askprompt__btn:focus {
	background: #eef4fb;
	border-color: var(--ipt-blue-link);
	/* stated for the same reason as .ipt-helpful__btn above — without it Astra supplied
	   white, which put white text on a near-white fill. */
	color: var(--ipt-blue-dark);
}

/* once the form is open the prompt has done its job */
.ipt-askprompt--used { display: none; }

/* collapsed only when JavaScript confirms it can reopen it */
.ipt-respond--collapsed { display: none; }

/* Commenters who filled in the optional Website field get their name wrapped in
   an <a>, which then took its colour from the link rules — so those names read
   light grey while everyone else read dark ink. The name is a name either way;
   it inherits, and the link only announces itself on hover. */
.ipt-thread .ast-comment-cite-wrap cite a {
	color: inherit;
	text-decoration: none;
}
.ipt-thread .ast-comment-cite-wrap cite a:hover,
.ipt-thread .ast-comment-cite-wrap cite a:focus-visible {
	color: var(--ipt-blue-link);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Comments heading row: title left, most-recent date right, baseline aligned. */
.ipt-thread .ipt-comments-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
}
.ipt-thread .ipt-comments-head .comments-title { margin: 0; font-size: 18px; font-weight: 700; color: var(--ipt-ink); }
.ipt-thread .ipt-comments-head__recent { font-size: 14px; color: var(--ipt-muted-light); white-space: nowrap; }
.ipt-thread .ipt-comments-head__note { font-size: 14px; color: var(--ipt-muted-light); margin: 4px 0 18px; }

/* Astra ships .comments-title with padding: 27px 36px, which indented the
   heading 36px past the rest of the block and pushed the "most recent" line
   below the baseline it should sit on. The design has it flush, padding 0. */
.ipt-thread .ipt-comments-head .comments-title {
	padding: 0;
	margin: 0;
	font-family: 'Montserrat', sans-serif;
	line-height: 1.3;
}
.ipt-thread .ipt-comments-head__note { margin: 4px 0 20px; }

/* Comments heading sits flush with the block and "most recent" aligns on its
   baseline, matching the design. */
.ipt-thread .ipt-comments-head .comments-title {
	padding: 0;
	margin: 0;
	font-family: 'Montserrat', sans-serif;
	line-height: 1.3;
}
.ipt-thread .ipt-comments-head__note { margin: 4px 0 20px; }

/* An Iptanus reply carries the logo blue on the name as well as the badge. */
.ipt-thread li.bypostauthor > .ast-comment .ast-comment-cite-wrap cite,
.ipt-thread li.bypostauthor > .ast-comment .ast-comment-cite-wrap cite a {
	color: var(--ipt-blue-dark);
}

/* Reply and Edit sit on one line, vertically centred with each other. */
.ipt-thread .ast-comment-edit-reply-wrap {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-top: 6px;
}
.ipt-thread .ast-comment-edit-reply-wrap > * { margin: 0; }
.ipt-thread .ast-comment-edit-reply-wrap a,
.ipt-thread .ast-comment-edit-reply-wrap .comment-reply-link,
.ipt-thread .ast-comment-edit-reply-wrap .comment-edit-link {
	display: inline-flex;
	align-items: center;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.4;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-thread .ast-comment-edit-reply-wrap a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* No rules inside a thread: the separator belongs to the discussion, not to each
   comment within it. Zeroing all four sides, not just the bottom. */
.ipt-thread .ast-comment { border: 0; }
.ipt-thread .ast-comment-avatar-wrap img { border: 0; }

/* Rules go ABOVE each discussion, not below: the first comment gets a line
   separating it from the heading, and the list ends clean with no trailing rule. */

/* ---- discussion separators — single authoritative rule -------------------
   A line ABOVE each discussion, identical spacing on every one, and nothing
   after the last. Equal 18px above and below the rule for all of them.
   -------------------------------------------------------------------------- */
.ipt-thread .ast-comment-list > li.comment.comment,
.ipt-thread .ast-comment-list > li.comment.comment:first-child,
.ipt-thread .ast-comment-list > li.comment.comment:last-child {
	border-top: 1px solid var(--ipt-line);
	border-bottom: 0;
	margin: 18px 0 0;
	padding: 18px 0 0;
}
/* the first line separates the list from the heading, so it needs no extra space above */
.ipt-thread .ast-comment-list > li.comment.comment:first-child { margin-top: 0; }

/* pagination carried a top rule, which read as a line after the last comment */
.ipt-thread .ipt-cpag { border-top: 0; padding-top: 0; margin-top: 26px; }

/* ---- Akismet notice, relocated into the submit row -----------------------
   Foot of the comment card: submit button left, notice right, both on one line.
   -------------------------------------------------------------------------- */
.ipt-thread .comment-form .form-submit {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	flex-wrap: wrap;
}
.ipt-thread .comment-form .akismet_comment_form_privacy_notice {
	margin: 0;
	font-size: 12px;
	line-height: 1.5;
	color: var(--ipt-muted-light);
	text-align: right;
}
.ipt-thread .comment-form .akismet_comment_form_privacy_notice a { color: var(--ipt-muted); }
.ipt-thread .comment-form .akismet_comment_form_privacy_notice a:hover { color: var(--ipt-blue-link); }

/* The comment textarea is targeted elsewhere by id (.comments-area textarea#comment)
   with border-radius:0, which outranks the rule that rounds the rest of the fields.
   Matching on the id here brings it back in line with the inputs beside it. */
.ipt-thread .comment-respond textarea#comment { border-radius: 8px; }

/* ===========================================================================
   DOCS HUB  (/knowledge-base/)
   Built to design/docs/KnowledgeBase.dc.html. Search-led: people arrive here
   with an error message, not to browse, so the search box outranks the index.
   =========================================================================== */

/* ---- hero ---------------------------------------------------------------- */
.ipt-kb-hero { background: var(--ipt-blue); color: #fff; }
.ipt-kb-hero .ipt-kb-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 40px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	margin: 0;
	text-wrap: pretty;
}
.ipt-kb-hero .ipt-kb-sub {
	font-size: 18px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.92);
	margin: 10px 0 0;
	max-width: 620px;
}

/* The docs search, at hub scale. Same category-scoped form as the article
   sidebar; only the proportions differ. */
.ipt-kb-search {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 24px;
	max-width: 560px;
	background: #fff;
	border-radius: 8px;
	padding: 14px 18px;
}
.ipt-kb-search__icon { color: var(--ipt-muted-light); flex-shrink: 0; }
.ipt-kb-search__field {
	flex: 1;
	border: 0;
	padding: 0;
	background: transparent;
	font-size: 16px;
	line-height: 1.3;
	color: var(--ipt-ink);
	box-shadow: none;
}
.ipt-kb-search__field:focus { outline: none; box-shadow: none; }
.ipt-kb-search__field::placeholder { color: var(--ipt-muted-light); opacity: 1; }

/* ---- body ---------------------------------------------------------------- */
/* the fill moved to <body> — this section is now the field, not a band painted onto it */
.ipt-kb-body .ipt-kb-h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-kb-body .ipt-kb-h2--browse { margin-top: 42px; }

/* ---- most read ----------------------------------------------------------- */
.ipt-kb-read {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 18px;
	margin-top: 16px;
}
.ipt-kb-card {
	display: block;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 20px 22px;
	text-decoration: none;
	transition: border-color 0.15s ease;
}
.ipt-kb-card:hover,
.ipt-kb-card:focus-visible { border-color: var(--ipt-line-strong); }
.ipt-kb-card__eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ipt-blue-link);
}
.ipt-kb-card__eyebrow--alert { color: var(--ipt-red-deep); }
.ipt-kb-card__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--ipt-ink);
	margin: 8px 0 0;
}
.ipt-kb-card:hover .ipt-kb-card__title { color: var(--ipt-blue-dark); }
.ipt-kb-card__text {
	font-size: 15px;
	line-height: 1.55;
	color: var(--ipt-muted);
	margin: 6px 0 0;
}

/* ---- browse by topic ----------------------------------------------------- */
.ipt-kb-topics {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 18px;
	margin-top: 16px;
}
.ipt-kb-topic {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px 26px;
}
.ipt-kb-topic__head { display: flex; align-items: center; gap: 10px; }
.ipt-kb-topic__icon { display: inline-flex; color: var(--ipt-blue); }
.ipt-kb-topic__icon--alert { color: var(--ipt-red); }
.ipt-kb-topic__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 19px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-kb-topic__links {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-top: 14px;
}
.ipt-kb-topic__links a {
	font-size: 16px;
	line-height: 1.4;
	color: var(--ipt-blue-link);
	text-decoration: none;
	transition: color 0.15s ease;
}
.ipt-kb-topic__links a:hover,
.ipt-kb-topic__links a:focus-visible { color: var(--ipt-blue-dark); text-decoration: underline; }

/* ---- can't find it ------------------------------------------------------- */
.ipt-kb-more {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	margin-top: 34px;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 22px 28px;
}
.ipt-kb-more__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--ipt-ink);
	margin: 0;
}
.ipt-kb-more__text { font-size: 15px; line-height: 1.5; color: var(--ipt-muted); margin: 4px 0 0; }
.ipt-kb-more__btn {
	flex-shrink: 0;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 10px 20px;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ipt-blue-link);
	text-decoration: none;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ipt-kb-more__btn:hover,
.ipt-kb-more__btn:focus {
	background: #eef4fb;
	border-color: var(--ipt-blue-link);
	color: var(--ipt-blue-dark);
}

/* ---- docs hub: overrides that have to outrank the block editor and Astra ----
   Three separate rules elsewhere fight this page, so the selectors below are
   deliberately specific rather than tidy:

   1. Gutenberg's constrained layout centres EVERY child of a group, and that
      centring cannot be undone from CSS — an inline margin does not beat it. The
      sub-heading and search box therefore live in a nested FLOW group, which takes
      the column itself and lets its children stack from the left.
   2. Astra styles search inputs as bordered boxes; inside the hero the box IS
      the field's container, so the input itself carries no chrome.
   3. `.ast-single-post .entry-content a` underlines every link in page content,
      which put a rule under each card title, topic link and button.
   -------------------------------------------------------------------------- */
.ipt-kb-hero__copy > .ipt-kb-sub { max-width: 620px; }
.ipt-kb-hero__copy > .ipt-kb-search { max-width: 560px; }

.ipt-kb-search input.ipt-kb-search__field {
	border: 0;
	border-radius: 0;
	padding: 0;
	height: auto;
	background: transparent;
	box-shadow: none;
	font-size: 16px;
	line-height: 1.4;
	color: var(--ipt-ink);
}
.ipt-kb-search input.ipt-kb-search__field:focus {
	border: 0;
	outline: none;
	box-shadow: none;
	background: transparent;
}

.entry-content .ipt-kb-read .ipt-kb-card,
.entry-content .ipt-kb-topics .ipt-kb-topic__links a,
.entry-content .ipt-kb-more .ipt-kb-more__btn { text-decoration: none; }

.entry-content .ipt-kb-topics .ipt-kb-topic__links a:hover,
.entry-content .ipt-kb-topics .ipt-kb-topic__links a:focus-visible { text-decoration: underline; }

/* ---- docs hub: the four extra topics -------------------------------------
   Everything is in the markup; JS hides the extras. These rules only style
   the control, so a page without scripting shows all eight and no button.
   -------------------------------------------------------------------------- */
.ipt-kb-topic__all {
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-muted);
}
.entry-content .ipt-kb-topics .ipt-kb-topic__links .ipt-kb-topic__all:hover,
.entry-content .ipt-kb-topics .ipt-kb-topic__links .ipt-kb-topic__all:focus-visible {
	color: var(--ipt-blue-dark);
}

.ipt-kb-reveal { display: flex; align-items: center; gap: 14px; margin-top: 26px; }
.ipt-kb-reveal__rule { flex: 1; height: 1px; background: var(--ipt-line); }
.ipt-kb-reveal__btn {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 10px 22px;
	font-family: 'Source Sans Pro', sans-serif;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ipt-blue-link);
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ipt-kb-reveal__btn:hover,
.ipt-kb-reveal__btn:focus {
	background: #eef4fb;
	border-color: var(--ipt-blue-link);
	color: var(--ipt-blue-dark);
}
.ipt-kb-reveal svg { transition: transform 0.15s ease; }
.ipt-kb-reveal.is-open svg { transform: rotate(180deg); }
.ipt-kb-reveal__note { text-align: center; font-size: 14px; color: var(--ipt-muted-light); margin: 10px 0 0; }

/* ---- article sidebar: category accordion ---------------------------------
   <details>/<summary>, so the open/close behaviour, keyboard support and the
   state a screen reader announces all come from the browser.
   -------------------------------------------------------------------------- */
.ipt-docsnav__group { border-bottom: 1px solid var(--ipt-line); }
.ipt-docsnav__group:first-child { border-top: 1px solid var(--ipt-line); }

.ipt-docsnav__summary {
	display: flex;
	align-items: center;
	gap: 8px;
	list-style: none;
	cursor: pointer;
	padding: 10px 0;
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted-light);
	transition: color 0.15s ease;
}
.ipt-docsnav__summary::-webkit-details-marker { display: none; }
.ipt-docsnav__summary::marker { content: ''; }
.ipt-docsnav__summary:hover,
.ipt-docsnav__summary:focus-visible { color: var(--ipt-blue-dark); }
.ipt-docsnav__name { flex: 1; }
.ipt-docsnav__count { font-size: 11px; font-weight: 700; letter-spacing: 0; color: var(--ipt-muted-light); }
.ipt-docsnav__chev { flex-shrink: 0; transition: transform 0.15s ease; }
.ipt-docsnav__group[open] > .ipt-docsnav__summary { color: var(--ipt-blue-dark); }
.ipt-docsnav__group[open] > .ipt-docsnav__summary .ipt-docsnav__count { display: none; }
.ipt-docsnav__group[open] > .ipt-docsnav__summary .ipt-docsnav__chev { transform: rotate(180deg); }

.ipt-docsnav__list { list-style: none; margin: 0; padding: 0 0 9px; }
.ipt-docsnav__item { margin: 0; }
.ipt-docsnav__item a {
	display: block;
	font-size: 15px;
	line-height: 1.35;
	color: var(--ipt-ink);
	padding: 5px 0;
	text-decoration: none;
	transition: color 0.15s ease;
}
.ipt-docsnav__item a:hover,
.ipt-docsnav__item a:focus-visible { color: var(--ipt-blue-link); }
.ipt-docsnav__item.is-current a {
	font-weight: 700;
	color: var(--ipt-blue-link);
	border-left: 3px solid var(--ipt-blue-link);
	padding-left: 11px;
	margin-left: -14px;
}

/* ===========================================================================
   DOCS CATEGORY ARCHIVES  (/category/technical-articles/<topic>/)
   Built to design/docs/category-options/OptionB.dc.html. A documentation index,
   not a feed: no author, no publication date, no featured image.
   =========================================================================== */

/* Astra's header opens #content > .ast-container, which is width-capped and padded.
   The head is full-bleed, so the container is neutralised for this page only and each
   band sets its own inner measure — the same approach as the docs article grid above. */
.ipt-doccat .site-content > .ast-container { max-width: none; padding: 0; }
.ipt-doccat #primary { margin: 0; padding: 0; width: 100%; max-width: none; }
.ipt-doccat .ast-container > #primary { margin-top: 0; }

.ipt-cat-head { background: var(--ipt-blue-dark); padding: 38px 24px 42px; }
.ipt-cat-head__inner { max-width: 1240px; margin: 0 auto; }

.ipt-cat-crumbs { font-size: 14px; color: rgba(255, 255, 255, 0.72); }
.ipt-cat-crumbs a { color: rgba(255, 255, 255, 0.72); text-decoration: none; }
.ipt-cat-crumbs a:hover { color: #fff; }
.ipt-cat-crumbs__sep { color: rgba(255, 255, 255, 0.7); margin: 0 6px; }
.ipt-cat-crumbs__here { color: #fff; }

.ipt-cat-head__title { display: flex; align-items: center; gap: 13px; margin-top: 16px; }
.ipt-cat-head__icon { display: inline-flex; color: #fff; }
.ipt-cat-head__icon--alert { color: var(--ipt-red); }
.ipt-cat-head__title h1 {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	margin: 0;
}
.ipt-cat-head__text {
	font-size: 18px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.88);
	margin: 10px 0 0;
	max-width: 640px;
}
.ipt-cat-head__count { font-size: 14px; color: rgba(255, 255, 255, 0.70); margin: 12px 0 0; }

/* 1240 of CONTENT, not 1240 including the padding: the head's inner measure is 1240 and the
   cards have to start on the same line as the title above them. */
.ipt-cat-body { max-width: 1288px; margin: 0 auto; padding: 34px 24px 56px; }

.ipt-cat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }

.ipt-cat-card {
	display: block;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 22px 24px;
	text-decoration: none;
	transition: border-color 0.15s ease;
}
.ipt-cat-card:hover,
.ipt-cat-card:focus-visible { border-color: var(--ipt-line-strong); }
.ipt-cat-card__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-cat-card__text { font-size: 15px; line-height: 1.55; color: var(--ipt-muted); margin: 7px 0 0; }
.ipt-cat-card__meta { font-size: 13px; color: var(--ipt-muted-light); margin: 12px 0 0; }

.ipt-cat-empty { font-size: 16px; color: var(--ipt-muted); }

/* the other topics, so an arrival from search is not stranded on one page */
.ipt-cat-others { margin-top: 34px; padding-top: 26px; border-top: 1px solid var(--ipt-line); }
.ipt-cat-others__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted-light);
	margin: 0;
}
.ipt-cat-others__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 13px 24px;
	margin-top: 15px;
}
.ipt-cat-others__item { font-size: 16px; line-height: 1.4; color: var(--ipt-blue-link); text-decoration: none; }
.ipt-cat-others__item:hover,
.ipt-cat-others__item:focus-visible { color: var(--ipt-blue-dark); text-decoration: underline; }
.ipt-cat-others__n { font-size: 13px; color: var(--ipt-muted-light); margin-left: 5px; }

.ipt-cat-help {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	margin-top: 22px;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 22px 28px;
}
.ipt-cat-help__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ipt-ink); margin: 0;
}
.ipt-cat-help__text { font-size: 15px; line-height: 1.5; color: var(--ipt-muted); margin: 4px 0 0; }
.ipt-cat-help__btn {
	flex-shrink: 0;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 10px 20px;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ipt-blue-link);
	text-decoration: none;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ipt-cat-help__btn:hover,
.ipt-cat-help__btn:focus {
	background: #eef4fb; border-color: var(--ipt-blue-link); color: var(--ipt-blue-dark);
}

/* ---- hub topic name as the route to its category page --------------------
   A heading that behaves like a link needs to say so permanently, so it keeps
   a quiet underline rather than revealing one on hover. Hover deepens the text
   and brings the underline up to the same colour.
   -------------------------------------------------------------------------- */
.entry-content .ipt-kb-topics .ipt-kb-topic__title a {
	color: inherit;
	text-decoration: underline;
	text-decoration-color: var(--ipt-line-strong);
	text-underline-offset: 4px;
	transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.entry-content .ipt-kb-topics .ipt-kb-topic__title a:hover,
.entry-content .ipt-kb-topics .ipt-kb-topic__title a:focus-visible {
	color: var(--ipt-blue-deep);
	text-decoration-color: var(--ipt-blue-deep);
}

/* ===========================================================================
   NEWS  (/category/news/ and its posts)
   Built to design/news/. The head is the category page's head verbatim — News
   and the docs topics are siblings, so they open the same way.
   =========================================================================== */

/* Only the INDEX breaks out of Astra's container — its head is full-bleed. The article keeps
   the container, because a centred 760 column is exactly what the container already gives it. */
.ipt-newsindex .site-content > .ast-container { max-width: none; padding: 0; }
.ipt-newsindex #primary { margin: 0; padding: 0; width: 100%; max-width: none; }

.ipt-news-head { background: var(--ipt-blue-dark); padding: 38px 24px 42px; }
.ipt-news-head__inner { max-width: 1240px; margin: 0 auto; }
.ipt-news-head__inner h1 {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px; font-weight: 800; line-height: 1.15; color: #fff; margin: 16px 0 0;
}
.ipt-news-head__text {
	font-size: 18px; line-height: 1.55; color: rgba(255, 255, 255, 0.88); margin: 10px 0 0; max-width: 640px;
}
.ipt-news-head__count { font-size: 14px; color: rgba(255, 255, 255, 0.70); margin: 12px 0 0; }

.ipt-news-body { max-width: 1288px; margin: 0 auto; padding: 24px 24px 56px; }

/* ---- year chips ---------------------------------------------------------- */
.ipt-news-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ipt-news-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	border: 1px solid #d3e3f5;
	background: transparent;
	border-radius: 20px;
	padding: 6px 14px;
	font-family: 'Source Sans Pro', sans-serif;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ipt-blue-link);
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ipt-news-chip:hover,
.ipt-news-chip:focus-visible { background: #eef4fb; border-color: var(--ipt-blue-link); color: var(--ipt-blue-dark); }
.ipt-news-chip.is-current { background: var(--ipt-blue-link); border-color: var(--ipt-blue-link); color: #fff; }
.ipt-news-chip.is-current:hover { background: var(--ipt-blue-dark); border-color: var(--ipt-blue-dark); color: #fff; }
/* the reveal is a control, not a fifteenth year */
.ipt-news-chip--all { color: var(--ipt-muted); }

/* ---- a year ------------------------------------------------------------- */
.ipt-news-year {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 22px 24px;
	margin-top: 16px;
	scroll-margin-top: 24px;
}
.ipt-news-year__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.ipt-news-year__y {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px; font-weight: 700; line-height: 1.3; color: var(--ipt-blue-dark); margin: 0;
}
.ipt-news-year__c { font-size: 13px; color: var(--ipt-muted-light); white-space: nowrap; }
.ipt-news-year__list { margin-top: 12px; }

.ipt-news-row {
	display: flex;
	align-items: baseline;
	gap: 18px;
	padding: 12px 0;
	border-bottom: 1px solid var(--ipt-line);
	text-decoration: none;
}
.ipt-news-row:last-child { border-bottom: 0; }
.ipt-news-row__ver {
	flex-shrink: 0;
	/* 62px held a bare "5.1.5". The label is "WFU 5.1.5" now — the number alone identified
	   nothing on a site that sells more than the plugin — and 96px keeps the longest of them,
	   "WFU 4.24.5", on one line so the column of versions still scans straight down. */
	width: 96px;
	font-family: 'Montserrat', sans-serif;
	font-size: 14px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
}
/* an announcement has no version, so it says what it is instead */
.ipt-news-row__ver--news {
	font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ipt-red-deep);
}
.ipt-news-row__sub { flex: 1; font-size: 16px; line-height: 1.45; color: var(--ipt-ink); }
.ipt-news-row__date { flex-shrink: 0; font-size: 13px; color: var(--ipt-muted-light); white-space: nowrap; }
.ipt-news-row:hover .ipt-news-row__sub { color: var(--ipt-blue-link); }
.ipt-news-row:hover .ipt-news-row__ver { color: var(--ipt-blue-deep); }

/* ---- the article --------------------------------------------------------- */
/* Astra puts a single post in `ast-narrow-container`: a 750px FLEX row. The breadcrumb and the
   article were therefore sitting side by side as flex items rather than stacked. Turning the
   container back into a block, at the measure the design asks for, fixes both at once. */
/* MEASURED, not estimated: at 17px in this face the average character is 7.04px wide, so the old
   680px column ran to 97 characters a line. Documentation — the measure this site already reads
   comfortably and the one nobody has complained about — is 569px and 83. The article was never
   too narrow; the PAGE was, because a 760px card sat in a 1440px window with nothing beside it.
   So the column comes down to the documentation rhythm and a rail fills the space.

   660 + 40 + 340 = 1040, centred inside the 1240 shell the index and documentation both use.
   Not stretched to fill 1240: two columns cannot, without either a line length no one should
   read or a rail wider than the article it belongs to. */
.ipt-newspost .site-content > .ast-container {
	max-width: 1240px;
	display: grid;
	grid-template-columns: minmax(0, 660px) 340px;
	column-gap: 40px;
	row-gap: 0;                 /* the breadcrumb carries its own spacing, as in docs */
	justify-content: center;
	align-items: start;
}
/* Astra gives #primary a 64px bottom margin and that is what separates the page from the footer.
   Zeroing every margin to fix the centring took it away, and the nav sat flush on the footer. */
.ipt-newspost #primary { max-width: none; width: 100%; margin: 0 0 64px; float: none; }
.ipt-newspost .ipt-rail { width: auto; max-width: none; margin: 0; padding: 0; float: none; }
.ipt-newspost .ipt-crumbs { margin: 18px 0 22px; }

/* The article becomes a card like every other reading surface on the field. It was a plain white
   slab with no border and no radius, which read as nothing once the page stopped being white. */
.ipt-newspost .ast-article-single {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 40px 44px 44px;
	margin: 0;
}

/* ---- the rail ------------------------------------------------------------ */
.ipt-news-rail__facts {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 6px 16px;
	margin: 12px 0 0;
}
.ipt-news-rail__facts dt {
	font-size: 13px;
	color: var(--ipt-muted-light);
}
.ipt-news-rail__facts dd {
	margin: 0;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ipt-ink);
}
.ipt-news-rail__all {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 16px;
	font-size: 14px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-news-rail__all:hover,
.ipt-news-rail__all:focus-visible { color: var(--ipt-blue-dark); text-decoration: underline; }

.ipt-news-rail__rel {
	display: block;
	margin-top: 10px;
	padding: 11px 13px;
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	text-decoration: none;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}
.entry-content a.ipt-news-rail__rel { text-decoration: none; }
a.ipt-news-rail__rel:hover,
a.ipt-news-rail__rel:focus-visible {
	border-color: var(--ipt-line-strong);
	background: var(--ipt-surface);
}
/* an end of the list is a fact, not a dead link — it must not look pressable */
.ipt-news-rail__rel--none { border-style: dashed; background: transparent; }
.ipt-news-rail__dir { display: block; font-size: 12.5px; color: var(--ipt-muted-light); }
.ipt-news-rail__ttl {
	display: block;
	margin-top: 2px;
	font-family: 'Montserrat', sans-serif;
	font-size: 14.5px;
	font-weight: 700;
	color: var(--ipt-blue-link);
}
.ipt-news-rail__rel--none .ipt-news-rail__ttl { color: var(--ipt-muted-light); font-weight: 600; }
a.ipt-news-rail__rel:hover .ipt-news-rail__ttl,
a.ipt-news-rail__rel:focus-visible .ipt-news-rail__ttl { color: var(--ipt-blue-dark); }

/* Below the grid's own breakpoint the rail stops being a rail and simply follows the article. */
@media (max-width: 1080px) {
	.ipt-newspost .site-content > .ast-container {
		grid-template-columns: minmax(0, 1fr);
		max-width: 748px;        /* 660 card + the container's own padding */
	}
	.ipt-newspost .ipt-rail { margin-top: 28px; }
}

.ipt-news-meta { display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--ipt-muted-light); margin-top: 14px; }
.ipt-news-kind {
	font-family: 'Montserrat', sans-serif;
	font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ipt-blue-link);
}
.ipt-news-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--ipt-line-strong); display: inline-block; }
.ipt-news-stand { font-size: 19px; line-height: 1.6; color: var(--ipt-muted); margin: 10px 0 0; }

/* the four paragraphs every release note ends with: kept, but not shouted */
.ipt-news-boiler { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--ipt-line); }
.ipt-news-boiler p { font-size: 14px; line-height: 1.55; color: var(--ipt-muted-light); margin: 0 0 6px; }
.ipt-news-boiler p:last-child { margin-bottom: 0; }

/* ---- previous / all / next ----------------------------------------------- */
/* The previous / All releases / next bar that used to sit under the article was replaced by
   the rail — see ipt_render_news_rail(). Its rules are gone with it rather than left behind. */
/* The hidden attribute is a UA style, so any author `display` beats it — these components set
   display explicitly, so their collapsed state has to be restated or JS cannot hide them. */
.ipt-news-chip[hidden],
.ipt-kb-reveal[hidden],
.ipt-kb-topic[hidden],
.ipt-kb-reveal__note[hidden] { display: none; }

/* ---- news index: load more ----------------------------------------------- */
.ipt-news-more { display: flex; justify-content: center; margin-top: 22px; }
.ipt-news-more__btn {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 6px;
	padding: 10px 22px;
	font-family: 'Source Sans Pro', sans-serif;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ipt-blue-link);
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ipt-news-more__btn:hover,
.ipt-news-more__btn:focus {
	background: #eef4fb; border-color: var(--ipt-blue-link); color: var(--ipt-blue-dark);
}
/* hidden is a UA style and loses to an author display — restate it, as for the chips */
.ipt-news-year[hidden], .ipt-news-more[hidden] { display: none; }

/* ===========================================================================
   SERVICES  (/services/)
   Built to design/services/Main.dc.html. The head reuses #0c5490 — the same
   blue as the homepage band that sends people here, so the page reads as its
   continuation rather than as somewhere else.
   =========================================================================== */

/* the alignfull escape, as for the homepage and the docs hub */
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-svc-head > *,
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-svc-body > * {
	max-width: 1140px;
	margin-left: auto;
	margin-right: auto;
}

.ipt-svc-head { background: var(--ipt-blue-dark); }
.ipt-svc-eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
	color: rgba(255, 255, 255, 0.70); margin: 0;
}
.ipt-svc-head .ipt-svc-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 38px; font-weight: 800; line-height: 1.15; color: #fff;
	margin: 14px 0 0; max-width: 760px;
}
.ipt-svc-head .ipt-svc-sub {
	font-size: 19px; line-height: 1.55; color: rgba(255, 255, 255, 0.88);
	margin: 12px 0 0; max-width: 660px;
}
.ipt-svc-cta { display: flex; align-items: center; gap: 14px; margin-top: 26px; flex-wrap: wrap; }
.ipt-svc-cta__btn {
	background: var(--ipt-red-fill); color: #fff;
	font-size: 17px; font-weight: 700; line-height: 1.3;
	padding: 13px 26px; border-radius: 7px; text-decoration: none;
	transition: background-color 0.15s ease;
}
.ipt-svc-cta__btn:hover, .ipt-svc-cta__btn:focus { background: var(--ipt-red-fill-hover); color: #fff; }
.ipt-svc-cta__note { font-size: 15px; color: rgba(255, 255, 255, 0.7); }

/* as .ipt-kb-body above: the fill is on <body> now */
.ipt-svc-body .ipt-svc-h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px; font-weight: 700; line-height: 1.3; color: var(--ipt-blue-dark); margin: 0;
}
.ipt-svc-h2--work { margin-top: 48px !important; }

.ipt-svc-caps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 16px; }
.ipt-svc-cap { background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px; padding: 24px 26px; }
.ipt-svc-cap__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ipt-blue-dark); margin: 0;
}
.ipt-svc-cap__b { font-size: 15px; line-height: 1.55; color: var(--ipt-muted); margin: 8px 0 0; }

/* every one of these names is already in the capability copy — this is layout, not new claims */
.ipt-svc-tech { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.ipt-svc-tech span {
	border: 1px solid #d3e3f5; border-radius: 20px; padding: 5px 13px;
	font-size: 14px; font-weight: 600; color: var(--ipt-muted);
}

.ipt-svc-work { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 16px; }
.ipt-svc-case { background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px; padding: 24px 26px; }
.ipt-svc-case__sector {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ipt-blue-link);
}
.ipt-svc-case__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ipt-ink); margin: 7px 0 0;
}
.ipt-svc-case__b { font-size: 15px; line-height: 1.6; color: var(--ipt-muted); margin: 8px 0 0; }
.ipt-svc-case__y { font-size: 13px; color: var(--ipt-muted-light); margin: 12px 0 0; }

/* the plugin as evidence, placed after the work so it reads as proof, not a detour */
.ipt-svc-proof {
	display: flex; align-items: center; justify-content: space-between; gap: 28px;
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px;
	padding: 24px 26px; margin-top: 22px;
}
.ipt-svc-proof .ipt-svc-cap__b { max-width: 640px; }
.ipt-svc-proof__btn {
	flex-shrink: 0; border: 1px solid #d3e3f5; border-radius: 6px; padding: 10px 20px;
	font-size: 15px; font-weight: 600; color: var(--ipt-blue-link); text-decoration: none;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ipt-svc-proof__btn:hover, .ipt-svc-proof__btn:focus {
	background: #eef4fb; border-color: var(--ipt-blue-link); color: var(--ipt-blue-dark);
}

/* ---- the enquiry, on the page rather than a click away --------------------- */
.ipt-svc-enquiry {
	display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px;
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px;
	padding: 34px 36px; margin-top: 48px; scroll-margin-top: 24px;
}
.ipt-svc-enquiry__b { font-size: 16px; line-height: 1.65; color: var(--ipt-muted); margin: 10px 0 0; }
.ipt-svc-enquiry__mail { font-size: 15px; line-height: 1.6; color: var(--ipt-muted-light); margin: 16px 0 0; }
.ipt-svc-enquiry__mail a { color: var(--ipt-blue-link); font-weight: 600; }

.ipt-svc-enquiry__form p { margin: 0 0 12px; }
/* wpautop wraps both fields in ONE paragraph inside the row, so the grid has to go on that
   paragraph — putting it on the row itself gave a two-column grid with a single child. */
.ipt-svc-enquiry__form .ipt-svc-field-row > p {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12px;
	margin: 0 0 12px;
}
/* a stray <br> from wpautop would otherwise take a grid cell of its own */
.ipt-svc-enquiry__form .ipt-svc-field-row br { display: none; }
.ipt-svc-enquiry__form input[type="text"],
.ipt-svc-enquiry__form input[type="email"],
.ipt-svc-enquiry__form textarea {
	width: 100%;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	padding: 12px 14px;
	font-family: 'Source Sans Pro', sans-serif;
	font-size: 15px;
	line-height: 1.4;
	color: var(--ipt-ink);
	box-shadow: none;
}
.ipt-svc-enquiry__form input:focus,
.ipt-svc-enquiry__form textarea:focus { border-color: var(--ipt-blue); outline: none; box-shadow: none; }
.ipt-svc-enquiry__form textarea { min-height: 104px; resize: vertical; }
.ipt-svc-enquiry__form input[type="submit"] {
	background: var(--ipt-red-fill);
	border: 0;
	border-radius: 7px;
	padding: 12px 26px;
	font-family: 'Montserrat', sans-serif;
	font-size: 16px;
	font-weight: 700;
	color: #fff;
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.ipt-svc-enquiry__form input[type="submit"]:hover,
.ipt-svc-enquiry__form input[type="submit"]:focus-visible { background: var(--ipt-red-fill-hover); }
.ipt-svc-enquiry__form .wpcf7-not-valid-tip { font-size: 13px; color: var(--ipt-red-deep, #c93a3a); margin-top: 4px; }
.ipt-svc-enquiry__form .wpcf7-response-output {
	border: 1px solid var(--ipt-line-strong); border-radius: 8px;
	padding: 12px 14px; font-size: 15px; color: var(--ipt-ink); margin: 12px 0 0;
}

/* `.ast-single-post .entry-content a` underlines every link in page content, which put a rule
   under the CTA, the plugin button and the email address. */
.entry-content .ipt-svc-cta .ipt-svc-cta__btn,
.entry-content .ipt-svc-proof .ipt-svc-proof__btn,
.entry-content .ipt-svc-enquiry .ipt-svc-enquiry__mail a { text-decoration: none; }
.entry-content .ipt-svc-enquiry .ipt-svc-enquiry__mail a:hover { text-decoration: underline; }

/* ============================================================================
   CONTACT
   Direction B, "The message". The form is the page; the rail routes without
   standing in front of it. The head repeats the Services band so the two pages
   read as siblings.
   ========================================================================== */

.ipt-ct-head__copy { max-width: none; }
.entry-content .ipt-ct-eyebrow {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.70);
	margin: 0;
}
.ipt-ct-head .ipt-ct-title {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 38px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	margin: 14px 0 0;
	max-width: 780px;
}
.ipt-ct-head .ipt-ct-sub {
	font-size: 19px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.88);
	margin: 12px 0 0;
	max-width: 700px;
}

.ipt-ct-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 380px;
	gap: 30px;
	align-items: start;
}

/* ---- the form ---------------------------------------------------------- */

.ipt-ct-form {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 32px 34px;
}
.ipt-ct-form .wpcf7 form > p:first-child { margin-top: 0; }
.ipt-ct-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 18px;
}
.ipt-ct-field { margin: 0 0 18px; }
.ipt-ct-row .ipt-ct-field { margin-bottom: 0; }
.ipt-ct-row + .ipt-ct-field { margin-top: 18px; }
.ipt-ct-field label {
	display: block;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 13px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin-bottom: 7px;
}

/* Astra styles inputs at its own specificity and squares off textareas, so each control is
   named rather than relying on a bare element selector. */
.ipt-ct-form input[type="text"],
.ipt-ct-form input[type="email"],
.ipt-ct-form select,
.ipt-ct-form textarea {
	width: 100%;
	box-sizing: border-box;
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 7px;
	padding: 12px 14px;
	font-family: inherit;
	font-size: 15px;
	line-height: 1.5;
	color: var(--ipt-ink);
	margin: 0;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.ipt-ct-form textarea { height: 260px; resize: vertical; display: block; }
.ipt-ct-form select {
	/* native arrow removed so the control matches the inputs on every platform */
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%237d94ab' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6.4 4 4 4-4'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 13px center;
	padding-right: 40px;
}
.ipt-ct-form input[type="text"]:focus,
.ipt-ct-form input[type="email"]:focus,
.ipt-ct-form select:focus,
.ipt-ct-form textarea:focus {
	border-color: var(--ipt-blue);
	box-shadow: 0 0 0 3px rgba(40, 120, 255, 0.16);
	outline: none;
}
.ipt-ct-form ::placeholder { color: var(--ipt-muted-light); opacity: 1; }

.ipt-ct-send {
	display: flex;
	align-items: center;
	gap: 18px;
	margin-top: 22px;
	flex-wrap: wrap;
}
.ipt-ct-form input[type="submit"] {
	flex-shrink: 0;
	background: var(--ipt-red-fill);
	color: #fff;
	border: 0;
	border-radius: 7px;
	padding: 13px 28px;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.2;
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.ipt-ct-form input[type="submit"]:hover,
.ipt-ct-form input[type="submit"]:focus { background: var(--ipt-red-fill-hover); }
/* The one line on this page that makes a claim about us. It states a limit rather than a
   promise, because there is no published response time and inventing one would be a lie. */
.ipt-ct-note {
	flex: 1 1 260px;
	font-size: 14px;
	line-height: 1.55;
	color: var(--ipt-muted);
}

/* CF7's own messages, which are otherwise unstyled browser defaults. */
.ipt-ct-form .wpcf7-not-valid-tip {
	font-size: 13.5px;
	color: var(--ipt-red-deep);
	margin-top: 6px;
}
.ipt-ct-form .wpcf7-form-control.wpcf7-not-valid { border-color: var(--ipt-red); }
.ipt-ct-form .wpcf7-response-output {
	margin: 22px 0 0;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
	padding: 13px 16px;
	font-size: 14.5px;
	line-height: 1.55;
	color: var(--ipt-ink);
	background: var(--ipt-surface);
}
.ipt-ct-form form.invalid .wpcf7-response-output,
.ipt-ct-form form.failed .wpcf7-response-output {
	border-color: var(--ipt-red);
	background: #fdf0f0;
	color: var(--ipt-red-deep);
}
.ipt-ct-form .wpcf7-spinner { margin: 0 0 0 12px; }

/* ---- the rail ---------------------------------------------------------- */

.ipt-ct-rail { display: flex; flex-direction: column; gap: 16px; margin: 0; }
.ipt-ct-card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 22px 24px;
}
.ipt-ct-card--svc { border-color: var(--ipt-line-strong); background: var(--ipt-surface); }
.ipt-ct-card__head { display: flex; align-items: center; gap: 9px; }
.ipt-ct-icon { flex-shrink: 0; color: var(--ipt-blue); }
.ipt-ct-card .ipt-ct-card__t {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 15.5px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.entry-content .ipt-ct-card__b {
	font-size: 15px;
	line-height: 1.55;
	color: var(--ipt-muted);
	margin: 8px 0 0;
}
.entry-content .ipt-ct-card__head + .ipt-ct-card__b { margin-top: 9px; }
.ipt-ct-mail a { font-size: 16px; font-weight: 600; }
.entry-content .ipt-ct-card__go { margin: 12px 0 0; }
.ipt-ct-card__go a {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
}
.ipt-ct-card__go a:hover { color: var(--ipt-blue-dark); }

/* `.ast-single-post .entry-content a` underlines every link in page content, which would put a
   rule under the rail links and the email address. Hover restores it on the two that are plain
   text links, where the underline reads as affordance rather than as decoration. */
.entry-content .ipt-ct-card__go a,
.entry-content .ipt-ct-mail a { text-decoration: none; }
.entry-content .ipt-ct-mail a:hover { text-decoration: underline; }

@media (max-width: 921px) {
	.ipt-ct-grid { grid-template-columns: minmax(0, 1fr); gap: 22px; }
}
@media (max-width: 544px) {
	.ipt-ct-head .ipt-ct-title { font-size: 30px; }
	.ipt-ct-head .ipt-ct-sub { font-size: 17px; }
	.ipt-ct-form { padding: 24px 20px; }
	.ipt-ct-row { grid-template-columns: minmax(0, 1fr); gap: 18px; }
	.ipt-ct-row .ipt-ct-field:first-child { margin-bottom: 0; }
}

/* ============================================================================
   PRICING
   Direction C, "The comparison". The 33-row matrix is the page and the price
   sits at the head of the Pro column, so the number is never far from the rows
   that justify it. Replaces the chart the plugin emits into a lightyellow box.
   ========================================================================== */

.ipt-pr-head__copy { max-width: none; }
.entry-content .ipt-pr-eyebrow {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.70);
	margin: 0;
}
.ipt-pr-head .ipt-pr-title {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 38px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	margin: 14px 0 0;
	max-width: 820px;
}
.ipt-pr-head .ipt-pr-sub {
	font-size: 19px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.88);
	margin: 12px 0 0;
	max-width: 720px;
}

/* No `overflow: hidden` on the card — it would kill the sticky header. The corners are
   rounded on the head and foot rows instead, including their own tinted cells. */
.ipt-pr-table {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
}
.ipt-pr-thead,
.ipt-pr-grp,
.ipt-pr-row,
.ipt-pr-foot {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 150px 150px;
}

.ipt-pr-thead {
	position: sticky;
	top: 0;
	z-index: 2;
	background: #fff;
	border-bottom: 1px solid var(--ipt-line);
	border-radius: 10px 10px 0 0;
}
.ipt-pr-thead__name { padding: 26px 24px; }
.ipt-pr-table .ipt-pr-prod {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 19px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.entry-content .ipt-pr-prod__b {
	font-size: 15px;
	line-height: 1.55;
	color: var(--ipt-muted);
	margin: 6px 0 0;
}
.ipt-pr-col {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 22px 12px;
	border-left: 1px solid var(--ipt-line);
	text-align: center;
}
.ipt-pr-col--pro { background: var(--ipt-surface); border-top-right-radius: 10px; }
.ipt-pr-col__t { font-family: Montserrat, system-ui, sans-serif; font-size: 17px; font-weight: 700; color: var(--ipt-ink); }
.ipt-pr-col--pro .ipt-pr-col__t { color: var(--ipt-blue-dark); }
.ipt-pr-col__p { font-family: Montserrat, system-ui, sans-serif; font-size: 30px; font-weight: 800; color: var(--ipt-ink); margin-top: 8px; }
.ipt-pr-col--pro .ipt-pr-col__p { color: var(--ipt-blue-dark); }
.ipt-pr-col__n { font-size: 13px; color: var(--ipt-muted-light); margin-top: 6px; }
.ipt-pr-col--pro .ipt-pr-col__n { color: var(--ipt-muted); }

.ipt-pr-grp { background: var(--ipt-surface); border-top: 1px solid var(--ipt-line); }
.ipt-pr-grp > div:first-child {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ipt-blue-dark);
	padding: 11px 0 11px 24px;
}
/* the Pro column keeps its tint through the group bands too, so it reads as one column */
.ipt-pr-grp > div:nth-child(3) { background: #eaf2fb; }

.ipt-pr-row { border-top: 1px solid var(--ipt-line); }
.ipt-pr-feat {
	font-size: 15px;
	line-height: 1.45;
	color: var(--ipt-ink);
	padding: 11px 14px 11px 24px;
	align-self: center;
}
.ipt-pr-mark { display: flex; align-items: center; justify-content: center; padding: 11px 0; }
.ipt-pr-mark--pro { background: #f7fbfe; }
.ipt-pr-yes { color: var(--ipt-blue); }
.ipt-pr-no { color: var(--ipt-line-strong); }

.ipt-pr-foot { border-top: 1px solid var(--ipt-line); border-radius: 0 0 10px 10px; }
.ipt-pr-lic { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; padding: 22px 24px; }
.ipt-pr-lic__t { display: block; font-family: Montserrat, system-ui, sans-serif; font-size: 16px; font-weight: 700; color: var(--ipt-ink); }
.ipt-pr-lic__b { display: block; font-size: 13.5px; line-height: 1.5; color: var(--ipt-muted); margin-top: 3px; }
.ipt-pr-act { display: flex; align-items: center; justify-content: center; padding: 20px 12px; border-left: 1px solid var(--ipt-line); }
.ipt-pr-act--pro { background: var(--ipt-surface); border-bottom-right-radius: 10px; }
.ipt-pr-table .ipt-pr-buy {
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 16px;
	font-weight: 700;
	padding: 12px 26px;
	border-radius: 7px;
	transition: background-color 0.15s ease;
}
.ipt-pr-table .ipt-pr-buy:hover, .ipt-pr-table .ipt-pr-buy:focus { background: var(--ipt-red-fill-hover); color: #fff; }
.ipt-pr-table .ipt-pr-free { font-size: 14.5px; font-weight: 600; color: var(--ipt-blue-link); }
.ipt-pr-table .ipt-pr-free:hover, .ipt-pr-table .ipt-pr-free:focus { color: var(--ipt-blue-dark); }

.entry-content .ipt-pr-note {
	font-size: 14px;
	line-height: 1.6;
	color: var(--ipt-muted);
	margin: 16px 0 0;
	max-width: 900px;
}

/* `.ast-single-post .entry-content a` is (0,2,1); a bare `.entry-content .ipt-pr-free` is
   (0,2,0) and loses. Qualifying with the element tag ties the count and wins on order. */
.entry-content a.ipt-pr-buy,
.entry-content a.ipt-pr-free { text-decoration: none; }
.entry-content a.ipt-pr-free:hover { text-decoration: underline; }

/* single flow child of the constrained group, so nothing inside it gets auto-centred */
.ipt-pr-wrap { max-width: none; }

@media (max-width: 921px) {
	.ipt-pr-thead,
	.ipt-pr-grp,
	.ipt-pr-row,
	.ipt-pr-foot { grid-template-columns: minmax(0, 1fr) 110px 110px; }
	.ipt-pr-feat { padding-left: 16px; font-size: 14.5px; }
	.ipt-pr-grp > div:first-child { padding-left: 16px; }
	.ipt-pr-thead__name,
	.ipt-pr-lic { padding-left: 16px; padding-right: 16px; }
	.ipt-pr-lic { grid-template-columns: minmax(0, 1fr); gap: 12px; }
}
@media (max-width: 544px) {
	.ipt-pr-head .ipt-pr-title { font-size: 30px; }
	.ipt-pr-head .ipt-pr-sub { font-size: 17px; }
	.ipt-pr-thead,
	.ipt-pr-grp,
	.ipt-pr-row,
	.ipt-pr-foot { grid-template-columns: minmax(0, 1fr) 64px 64px; }
	.ipt-pr-feat { font-size: 13.5px; padding: 10px 8px 10px 12px; }
	.ipt-pr-grp > div:first-child { padding-left: 12px; font-size: 11px; }
	.ipt-pr-thead__name { padding: 18px 12px; }
	.ipt-pr-col { padding: 14px 4px; }
	.ipt-pr-col__p { font-size: 22px; }
	.ipt-pr-col__t { font-size: 14px; }
	.ipt-pr-col__n { font-size: 11px; }
	.ipt-pr-act { padding: 14px 6px; }
	.ipt-pr-table .ipt-pr-buy { font-size: 13px; padding: 10px 10px; }
	.ipt-pr-table .ipt-pr-free { font-size: 13px; }
}

/* Astra sets the header CTA inline from the Customizer:
   `.ast-header-button-1 .ast-custom-button{color:#fff;background:#f06060}` at (0,2,0).
   At 16px/500 that is 3.21:1 — the least accessible text on the site, on its most clicked
   button. Overridden here at (0,2,1) so it wins on specificity rather than load order. */
body .ast-header-button-1 .ast-custom-button { background: var(--ipt-red-fill); }
body .ast-header-button-1 .ast-custom-button:hover,
body .ast-header-button-1 .ast-custom-button:focus-visible { background: var(--ipt-red-fill-hover); }

/* ============================================================================
   FOOTER ALIGNMENT
   Astra's footer builder lays its rows out on its own 1200px container, while
   every page on this site uses a 1140px measure. That put the footer columns at
   x=120 while all the content above them starts at x=150 — a 30px step visible
   on every page. Both footer rows are brought onto the site's measure.
   ========================================================================== */

.site-footer .ast-builder-footer-grid-columns.site-primary-footer-inner-wrap,
.site-footer .ast-builder-footer-grid-columns.site-below-footer-inner-wrap {
	max-width: 1140px;
}

/* The 24px lives on the OUTER row, not the 1140 wrap — putting it on the wrap would shrink the
   measure to 1092 and push the columns to 174. This way the sums match the page groups exactly:
   at 1440 the inner centres at 150, and below 1140 it keeps the same 24px gutter the content has,
   instead of running into the edge of the screen. */
.site-footer .site-primary-footer-wrap,
.site-footer .site-below-footer-wrap {
	padding-left: 24px;
	padding-right: 24px;
}

/* Astra's inline CSS carries `a:hover,a:focus{color:#2878ff}` at (0,1,1). Two problems on this
   site: #2878ff is 4.02:1 on white, so every hovered or focused link drops below AA — and it
   LIGHTENS the resting #0c5490, which inverts the hover rule the rest of the theme follows.
   Deepened instead, to the same colour the wordmark uses on hover. */
body a:hover,
body a:focus { color: var(--ipt-blue-deep); }

/* ============================================================================
   FILE UPLOAD PAGE
   The plugin front door. Nine tabs became a hero, a chip row, three cards and
   seven real sections; the changelog moved to its own indexed block below.
   ========================================================================== */

.ipt-fu-head__grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 60px; align-items: center; }
.ipt-fu-eyebrow {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
	color: rgba(255, 255, 255, 0.70); margin: 0;
}
.ipt-fu-head .ipt-fu-title {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 38px; font-weight: 800; line-height: 1.15; color: #fff; margin: 14px 0 0; max-width: 700px;
}
.ipt-fu-head .ipt-fu-sub {
	font-size: 19px; line-height: 1.55; color: rgba(255, 255, 255, 0.88); margin: 12px 0 0; max-width: 640px;
}
.ipt-fu-cta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 26px; }
.ipt-fu-btn, .ipt-fu-btn2 {
	display: inline-block; font-family: Montserrat, system-ui, sans-serif;
	font-size: 17px; font-weight: 700; border-radius: 7px; transition: background-color 0.15s ease;
}
.ipt-fu-btn  { background: var(--ipt-red-fill); color: #fff; padding: 13px 28px; }
.ipt-fu-btn:hover, .ipt-fu-btn:focus { background: var(--ipt-red-fill-hover); color: #fff; }
.ipt-fu-btn2 { background: #fff; border: 1px solid #d3e3f5; color: var(--ipt-blue-link); padding: 12px 27px; }
.ipt-fu-btn2:hover, .ipt-fu-btn2:focus { background: var(--ipt-surface); color: var(--ipt-blue-dark); border-color: var(--ipt-line-strong); }

.ipt-fu-mark { display: flex; flex-direction: column; align-items: center; gap: 16px; }
/* White, not the translucent tile the drawn mark used: the logo is an opaque white PNG, so any
   other fill would frame it with a visible square inside the rounded corner. Same surface, no
   seam — and it reads as a product mark on the banner rather than as a pasted-in screenshot. */
/* 200, not the drawn mark's 128: this artwork is an illustration with the product name inside it,
   and at 128 that name was too small to read. The column is 300 wide, so the space was already
   there — the placeholder was sized for a glyph, not for a picture. */
.ipt-fu-mark__tile {
	width: 200px;
	height: 200px;
	border-radius: 36px;
	background: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}
.ipt-fu-mark__img { display: block; width: 100%; height: 100%; object-fit: contain; }

.ipt-fu-wrap { max-width: none; }
.ipt-fu-h2 { font-family: Montserrat, system-ui, sans-serif; font-size: 22px; font-weight: 700; color: var(--ipt-blue-dark); margin: 44px 0 0; }
.ipt-fu-chips { display: flex; flex-wrap: wrap; gap: 9px; }
.ipt-fu-chip {
	display: inline-flex; align-items: center; background: #fff; border: 1px solid #d3e3f5;
	border-radius: 999px; padding: 7px 15px; font-size: 14.5px; color: var(--ipt-ink);
}
.entry-content a.ipt-fu-chip { text-decoration: none; color: var(--ipt-blue-link); }
.entry-content a.ipt-fu-chip:hover,
.entry-content a.ipt-fu-chip:focus { color: var(--ipt-blue-dark); border-color: var(--ipt-line-strong); background: var(--ipt-surface); }

.ipt-fu-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-top: 16px; }
.ipt-fu-card { background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px; padding: 22px 24px; }
.ipt-fu-card__t { font-family: Montserrat, system-ui, sans-serif; font-size: 17px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0; }
.entry-content .ipt-fu-card__b { font-size: 15px; line-height: 1.55; color: var(--ipt-muted); margin: 8px 0 0; }

/* A <figure> now that it holds a real screenshot, so the browser's own figure margin is reset
   and the surrounding rhythm stays the theme's. */
.ipt-fu-shot {
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px;
	overflow: hidden; margin: 16px 0 0;
}
.ipt-fu-shot__bar {
	background: var(--ipt-surface); border-bottom: 1px solid var(--ipt-line); padding: 12px 20px;
	display: flex; align-items: center; justify-content: space-between; gap: 16px;
	font-size: 14px; font-weight: 600; color: var(--ipt-ink);
}
/* The diagonal hatching is gone with the placeholder it belonged to — hatching means "nothing
   here yet", and there is something here now. An inset fill, which is allowed because this sits
   inside a card. */
.ipt-fu-shot__body {
	display: flex; align-items: center; justify-content: center; padding: 32px 28px;
	background: var(--ipt-surface);
}
/* The screenshot is 515px wide and is shown at its own size: enlarging a raster is exactly how
   the 2013 image it replaced came to look the way it did. It shrinks on narrow screens only. */
.ipt-fu-shot__img {
	display: block;
	max-width: 100%;
	height: auto;
	border: 1px solid var(--ipt-line);
	border-radius: 6px;
	background: #fff;
}
.ipt-fu-shot__cap {
	padding: 12px 20px 14px;
	border-top: 1px solid var(--ipt-line);
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--ipt-muted);
}

/* ---- "The detail" accordion -------------------------------------------------
   Artboard B, value for value: one card, rows split by a 1px line, header
   16px/24px with the open row on --ipt-surface, title Montserrat 16.5px/700 in
   --ipt-blue-dark, chevron in --ipt-blue-link rotating 180 when open, body
   padded 0 24px 20px. Collapse is by script (inc-plugin-page.php), never here.
   -------------------------------------------------------------------------- */

.ipt-fu-acc {
	margin-top: 18px;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	overflow: hidden;
}
.ipt-fu-sec + .ipt-fu-sec { border-top: 1px solid var(--ipt-line); }

/* the heading is real; the button inside it carries the appearance */
.ipt-fu-acc .ipt-fu-sec__h { margin: 0; font-size: inherit; font-weight: inherit; }

.ipt-fu-sec__head {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 16px 24px;
	background: #fff;
	border: 0;
	cursor: pointer;
	text-align: left;
	font: inherit;
}
.ipt-fu-sec__t {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 16.5px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
}
/* colour AND background on both states: Astra's global `button:hover,button:focus`
   supplies `color:#fff` for whichever of the two a rule leaves out. */
.ipt-fu-sec__head:hover,
.ipt-fu-sec__head:focus { background: var(--ipt-surface); color: var(--ipt-ink); }
.ipt-fu-sec[data-ipt-fu-open] > .ipt-fu-sec__h > .ipt-fu-sec__head { background: var(--ipt-surface); }

/* the artboard's 18px chevron, drawn rather than shipped as markup */
.ipt-fu-sec__head::after {
	content: "";
	flex-shrink: 0;
	width: 9px;
	height: 9px;
	border-right: 2px solid var(--ipt-blue-link);
	border-bottom: 2px solid var(--ipt-blue-link);
	transform: rotate(45deg) translate(-2px, -2px);
	transition: transform 0.15s ease;
}
.ipt-fu-sec[data-ipt-fu-open] .ipt-fu-sec__head::after {
	transform: rotate(225deg) translate(-2px, -2px);
}

.ipt-fu-sec__body {
	/* The rhythm rule below zeroes every child's own top margin, so this padding is the ONLY
	   thing holding the first line off the section header — 8px was not enough once the header
	   gained its open-state fill and the two started reading as one block. */
	padding: 20px 24px 24px;
	font-size: 15px;
	line-height: 1.65;
	color: var(--ipt-muted);
}
/* `hidden` is a UA style and loses to an author display — restated, as elsewhere */
.ipt-fu-sec__body[hidden] { display: none; }
.ipt-fu-sec__body ul, .ipt-fu-sec__body ol { padding-left: 22px; }
.ipt-fu-sec__body li { margin-bottom: 6px; }

/* ONE vertical rhythm for a section body. Every block owned its own spacing before this, so the
   same prose sat at three different distances: 24px after a paragraph, 12px after the <ol> in
   Installation, and 4px after the link rows in Privacy — where a sentence introducing the SECOND
   pair of links was closer to the first pair than to the text it belonged with.
   Margins are zeroed and re-applied top-only, so the gap never depends on which of two adjacent
   blocks declares the larger margin, or on whether they collapse at all — a flex container like
   .ipt-fu-go collapses differently from a <p>.
   Scoped under .entry-content to clear Astra's `.entry-content p` (0,1,1), and placed after the
   ul/ol rule above, which it ties with on specificity and so wins only by order. */
.entry-content .ipt-fu-sec__body > * { margin-top: 0; margin-bottom: 0; }
.entry-content .ipt-fu-sec__body > * + * { margin-top: 24px; }

@media (max-width: 544px) {
	.ipt-fu-sec__head { padding: 14px 16px; }
	.ipt-fu-sec__t { font-size: 15.5px; }
	.ipt-fu-sec__body { padding: 0 16px 18px; }
}

.ipt-fu-pro {
	display: flex; align-items: center; justify-content: space-between; gap: 36px;
	background: var(--ipt-surface); border: 1px solid var(--ipt-line-strong); border-radius: 10px;
	padding: 24px 26px; margin-top: 20px;
}
.entry-content .ipt-fu-pro__b { font-size: 15px; line-height: 1.55; color: var(--ipt-muted); margin: 7px 0 0; max-width: 760px; }

/* `.ast-single-post .entry-content a` is (0,2,1) and underlines every link in page content.
   Tag-qualified here so the count ties and this wins on order, as on the other pages. */
.entry-content a.ipt-fu-btn,
.entry-content a.ipt-fu-btn2 { text-decoration: none; }
.ipt-fu-dl { display: flex; flex-wrap: wrap; gap: 12px; margin: 16px 0 0; }

/* ============================================================================
   RELEASE NOTES
   Indexed by major version, because these entries carry no dates and the News
   year grouping does not transfer. Version numbers ship; change text is fetched.
   ========================================================================== */

.ipt-rn { margin-top: 44px; }
.ipt-rn__top { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; }
.ipt-rn__h { font-family: Montserrat, system-ui, sans-serif; font-size: 22px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0; }
.entry-content .ipt-rn__count { font-size: 14px; color: var(--ipt-muted); margin: 0; white-space: nowrap; }
.entry-content .ipt-rn__intro { font-size: 15px; line-height: 1.55; color: var(--ipt-muted); margin: 8px 0 0; max-width: 820px; }

.ipt-rn-major { margin-top: 26px; }
.ipt-rn-major__meta { font-size: 13.5px; color: var(--ipt-muted); white-space: nowrap; }

.ipt-rn-list { background: #fff; border: 1px solid var(--ipt-line); border-top: 0; border-radius: 0 0 10px 10px; }
.ipt-rn-row + .ipt-rn-row { border-top: 1px solid var(--ipt-line); }
.ipt-rn-row__head {
	width: 100%; display: grid; grid-template-columns: 110px auto 1fr auto; align-items: center; gap: 14px;
	background: #fff; border: 0; padding: 13px 22px; cursor: pointer; text-align: left; font: inherit;
}
/* colour is stated as well as background: Astra's global `button:hover,button:focus` supplies
   `color:#fff` for whichever of the two a rule omits, which put white on the near-white fill. */
.ipt-rn-row__head:hover,
.ipt-rn-row__head:focus { background: var(--ipt-surface); color: var(--ipt-ink); }
.ipt-rn-row__head[aria-expanded="true"] { background: var(--ipt-surface); }
.ipt-rn-row__v { font-family: Montserrat, system-ui, sans-serif; font-size: 15.5px; font-weight: 700; color: var(--ipt-ink); }
.ipt-rn-row__n { font-size: 14px; color: var(--ipt-muted); }
.ipt-rn-sec {
	justify-self: start;
	background: #fdf0f0; border: 1px solid var(--ipt-red); color: var(--ipt-red-ink);
	font-family: Montserrat, system-ui, sans-serif; font-size: 11px; font-weight: 700;
	letter-spacing: 0.04em; text-transform: uppercase; padding: 2px 8px; border-radius: 4px;
}
/* The chevron is drawn here rather than shipped as markup: at 153 rows an inline SVG cost 27 KB. */
.ipt-rn-row__head::after {
	content: "";
	grid-column: 4;
	justify-self: end;
	width: 8px; height: 8px;
	border-right: 2px solid var(--ipt-blue-link);
	border-bottom: 2px solid var(--ipt-blue-link);
	transform: rotate(45deg) translate(-2px, -2px);
	transition: transform 0.15s ease;
}
.ipt-rn-row__head[aria-expanded="true"]::after { transform: rotate(225deg) translate(-2px, -2px); }

.ipt-rn-row__items { margin: 0; padding: 2px 22px 18px 52px; list-style: disc; }
.ipt-rn-row__items:empty { display: none; }
.ipt-rn-row__items li { font-size: 14.5px; line-height: 1.55; color: var(--ipt-muted); margin-bottom: 6px; }
/* Collapsed by SCRIPT: the attribute is added on load, so without JavaScript every list is open. */
.ipt-rn-row[data-ipt-rn-collapsed] .ipt-rn-row__items { display: none; }
.ipt-rn-major[data-ipt-rn-loading] .ipt-rn-list { opacity: 0.55; }

.entry-content .ipt-rn__src { font-size: 14px; line-height: 1.6; color: var(--ipt-muted); margin: 20px 0 0; }

@media (max-width: 921px) {
	.ipt-fu-head__grid { grid-template-columns: minmax(0, 1fr); gap: 32px; }
	.ipt-fu-mark { align-items: flex-start; }
	.ipt-fu-cards { grid-template-columns: minmax(0, 1fr); }
	.ipt-fu-pro { flex-direction: column; align-items: flex-start; gap: 18px; }
	.ipt-rn-row__head { grid-template-columns: 88px auto 1fr auto; gap: 10px; padding: 13px 16px; }
	/* the items' own padding is set with the rest of the marker styles, further down the file —
	   it has to be, because an equal-specificity rule up here loses to it on source order and a
	   media query adds no specificity of its own. */
}
@media (max-width: 544px) {
	.ipt-fu-head .ipt-fu-title { font-size: 30px; }
	.ipt-fu-head .ipt-fu-sub { font-size: 17px; }
	.ipt-rn__top { flex-direction: column; gap: 4px; }
	.ipt-rn-row__head { grid-template-columns: 1fr auto; row-gap: 4px; }
	.ipt-rn-row__n, .ipt-rn-sec { grid-column: 1; }
}

/* ---- collapsible majors + the older-versions button ------------------------- */

/* `hidden` is a UA style and loses to an author display — restated, as everywhere else here */



/* the release notes sit inside an accordion section now, so the section supplies the spacing */
.ipt-fu-sec__body > .ipt-rn { margin-top: 0; }

/* ============================================================================
   COMMENTS ON A PAGE-BUILDER PAGE
   Astra's page-builder layout removes the container. The Gutenberg groups carry
   their own 1140 measure, but the comment template sits outside them and
   inherits nothing — so #comments rendered 1440 wide at x=0 while the content
   above it started at x=150.

   Scoped to the body class Astra puts on exactly the pages that lose the
   container, so docs articles and news posts — which have their own
   constraints — are untouched.

   1188 - 48 = 1140 inner, centred: content lands at x=150 at a 1440 viewport
   and keeps a 24px gutter below 1188. Same arithmetic as the footer rows.
   ========================================================================== */

.ast-page-builder-template .comments-area {
	max-width: 1188px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 24px;
	padding-right: 24px;
	box-sizing: border-box;
}

/* ---- the majors, as a tab strip ---------------------------------------------
   A tab REPLACES rather than reveals, so it cannot be mistaken for the version
   rows beneath it. This strip also replaces the chip index, the four major
   headers and the older-versions button, which were three controls doing
   overlapping jobs.
   -------------------------------------------------------------------------- */

.ipt-rn-tabs {
	display: flex;
	gap: 4px;
	margin-top: 16px;
	border-bottom: 2px solid var(--ipt-line);
	overflow-x: auto;            /* never wraps to two ragged lines */
	-webkit-overflow-scrolling: touch;
	/* The strip stays scrollable — it has to be, once "Older" adds two more tabs on a narrow
	   screen — but the bar itself is hidden. A scrollbar under five tabs reads as a defect
	   rather than an affordance, and nothing here is reachable ONLY by dragging it: the tabs
	   are a roving-tabindex group, so arrow keys walk the whole set including the ones
	   off-screen, and touch scrolls the strip directly. */
	scrollbar-width: none;       /* Firefox */
	-ms-overflow-style: none;    /* old Edge */
}
.ipt-rn-tabs::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* The row is the visual strip; the tablist inside it holds only tabs, because that is all a
   tablist may hold. Both are plain flex rows, so the two nest to exactly one rendered row. */
.ipt-rn-tabs__list {
	display: flex;
	gap: 4px;
	flex-shrink: 0;
}
.ipt-rn-tab {
	flex-shrink: 0;
	display: inline-flex;
	align-items: baseline;
	gap: 7px;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 15px;
	font-weight: 700;
	color: var(--ipt-muted);
	background: transparent;
	border: 0;
	border-bottom: 2px solid transparent;
	margin-bottom: -2px;         /* the selected rule sits over the strip's own line */
	padding: 11px 18px;
	cursor: pointer;
	white-space: nowrap;
	font: inherit;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 15px;
	font-weight: 700;
}
/* colour AND background on both states — Astra's global `button:hover,button:focus`
   supplies white-on-#2878ff for whichever of the two a rule leaves out. */
.ipt-rn-tab:hover,
.ipt-rn-tab:focus {
	background: var(--ipt-surface);
	color: var(--ipt-blue-dark);
}
/* The strip's two element types arrive with opposite defaults: the anchors pick up a dotted ring
   on a mouse click, the <button> is stripped to `outline: none` and had NO focus indicator at all
   — its only signal was a #f2f7fc tint, 1.05:1 against white. Stated here for both, so the strip
   behaves as one control: nothing on click, where the selected tab already says where you are,
   and a solid ring for the keyboard. Inset by 3px because the strip is an overflow-x scroller
   and an outer ring on a scrolling child gets clipped. */
.ipt-rn-tab:focus { outline: none; }
.ipt-rn-tab:focus-visible {
	outline: 3px solid var(--ipt-blue-dark);
	outline-offset: -3px;
}
.ipt-rn-tab[aria-selected="true"] {
	color: var(--ipt-blue-dark);
	background: #fff;
	border-bottom-color: var(--ipt-blue-dark);
}
.ipt-rn-tab__n {
	font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
	font-size: 13px;
	font-weight: 400;
	color: var(--ipt-muted);
}
.ipt-rn-tab[aria-selected="true"] .ipt-rn-tab__n { color: var(--ipt-blue-dark); }
.ipt-rn-tab--more { color: var(--ipt-blue-link); }
/* `hidden` is a UA style and loses to an author display — restated, as everywhere here */
.ipt-rn-tab[hidden], .ipt-rn-major[hidden], .ipt-rn-loading[hidden], .ipt-rn-list[hidden] { display: none; }
.entry-content a.ipt-rn-tab { text-decoration: none; }

.ipt-rn-major { margin-top: 0; }
.ipt-rn-major__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px 20px;
	padding: 12px 2px 10px;
	font-size: 13.5px;
	color: var(--ipt-muted);
}

/* The fetch finally has a visible moment — that is the point of the switch. */
.ipt-rn-loading {
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	padding: 28px;
	text-align: center;
	font-size: 14.5px;
	color: var(--ipt-muted);
}

.ipt-rn-list { border-radius: 8px; border-top: 1px solid var(--ipt-line); }

@media (max-width: 544px) {
	.ipt-rn-tab { padding: 10px 13px; font-size: 14px; }
}

/* ---- section content: link rows and the translator credits ------------------
   THE LINK RULE, applied mechanically: strip the <a> and see what remains.
   Nothing left  -> navigation: no underline, an arrow, underline on hover.
   A sentence left -> prose: keep Astra's underline, which is the only
   affordance a link has mid-paragraph.
   -------------------------------------------------------------------------- */

.ipt-fu-go { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; margin: 12px 0 4px; }
.ipt-fu-go__a {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 6px 0;
	font-weight: 600;
	color: var(--ipt-blue-link);
}
.entry-content a.ipt-fu-go__a { text-decoration: none; }
.entry-content a.ipt-fu-go__a:hover,
.entry-content a.ipt-fu-go__a:focus { color: var(--ipt-blue-dark); text-decoration: underline; }

/* Term and definition. Four of the twelve entries have no credit at all, so the second column is
   simply empty for them — which reads correctly, where a bold label with a trailing colon does not. */
.ipt-fu-langs {
	display: grid;
	grid-template-columns: 132px minmax(0, 1fr);
	gap: 2px 20px;
	margin: 12px 0 0;
}
.ipt-fu-langs dt {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ipt-ink);
	padding: 5px 0;
}
.ipt-fu-langs dd {
	margin: 0;
	padding: 5px 0;
	font-size: 14.5px;
	color: var(--ipt-muted);
}

@media (max-width: 544px) {
	.ipt-fu-langs { grid-template-columns: minmax(0, 1fr); gap: 0; }
	.ipt-fu-langs dt { padding-bottom: 0; }
	.ipt-fu-langs dd:not(:empty) { padding-top: 2px; padding-bottom: 10px; }
	.ipt-fu-langs dd:empty { padding: 0 0 10px; }
}


/* ============================================================================
   THE PAGE FIELD — one background, sitewide
   ---------------------------------------------------------------------------
   Design decision: Option A, "Bookends". The field runs the whole page; the
   header and footer are both white, so the chrome bookends the content and the
   grey between them reads as ground rather than as a gap.

   Three steps, no fourth:
     field   var(--ipt-field)    the page
     card    #fff                where reading happens
     inset   var(--ipt-surface)  ONLY inside a card

   Everything below is a surface that used to be transparent and inherited
   white from <body>. On a grey field each one has to be decided, not defaulted.
   ========================================================================== */

/* NOT a bare `body` rule. Astra paints the page from the container class it puts on <body>
   — `.ast-plain-container, .ast-page-builder-template { background-color: var(--ast-global-color-4) }`
   — which is (0,1,0) and beats `body` (0,0,1) no matter how late it loads. Every template
   carries one of these five, so each is named and tag-qualified to (0,1,1). */
body.ast-plain-container,
body.ast-page-builder-template,
body.ast-narrow-container,
body.ast-separate-container,
body.ast-two-container {
	background-color: var(--ipt-field);
}

/* Astra's header is white already; only its rule was foreign — a neutral
   #d1d5db with no blue in it, where every other line on the site is
   --ipt-line. Now that the header borders ONTO the field rather than onto
   more white, that difference is visible. */
.ast-primary-header-bar,
.ast-header-break-point .ast-primary-header-bar,
.main-header-bar {
	background-color: #fff;
	border-bottom-color: var(--ipt-line);
}

/* The footer was #f9f9f9 — an Astra default, a neutral grey with no blue in
   it at all, and never part of this palette. On white it was invisible; beside
   a cool field it reads as a dirty smudge across the full width. It becomes
   the same white as the header, which is what makes this Option A.
   Astra targets it as `.site-primary-footer-wrap[data-section="…"]` (0,2,1), so the class alone
   loses however late it loads; the descendant plus the attribute takes this to (0,3,0). */
.site-footer .site-primary-footer-wrap[data-section],
.site-footer .ast-footer-overlay {
	background-color: #fff;
}
.site-footer .site-primary-footer-wrap[data-section],
.site-footer .site-below-footer-wrap[data-section] {
	border-top: 1px solid var(--ipt-line);
}

/* A gap before the footer, on every template.
   Astra zeroes the bottom margin of the last content block (`.entry-content > :last-child`), so
   content has always butted the footer on every page — it was simply invisible while both were
   white. The homepage is where it shows: it ends on a full-bleed blue band, and the blue ran
   straight into the white footer with nothing between. Put on the footer rather than on that one
   band, because the condition is not homepage-specific and because a rule on the band would have
   to out-specify Astra's last-child reset to have any effect at all.
   The gap shows the field, which is what separates content from chrome everywhere else. */
.site-footer {
	margin-top: 56px;
}

/* Comments become a card — but ONLY where the site's own comment design is not already doing
   it. On an .ipt-thread view #comments is a deliberately transparent WRAPPER holding a
   discussions card and an "Ask a question" card as siblings; giving the wrapper a fill there
   would put a card inside a card. This is the fallback for every other template that renders
   comments, so nothing sits bare on the field. */
body:not(.ipt-thread) .comments-area {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 28px 32px 32px;
	margin-top: 32px;
}
/* What has to line up CHANGED when this became a card. While the comments area was
   invisible, the thing to align was the text inside it, so the old rule was 1188 wide with a
   24px pad — 1140 of inner column at x=150. A card has a visible EDGE, and an edge inset 24px
   from the content above it reads as a mistake, so the card itself is now 1140 at x=150 and its
   padding is internal. min() keeps the 24px gutter the old padding used to provide once the
   viewport drops below the measure. */
.ast-page-builder-template .comments-area {
	width: min(1140px, 100% - 48px);
	max-width: none;
	margin-left: auto;
	margin-right: auto;
}

@media (max-width: 544px) {
	body:not(.ipt-thread) .comments-area {
		border-radius: 10px;
		padding: 20px 16px 24px;
	}
	.ast-page-builder-template .comments-area {
		width: min(1140px, 100% - 32px);
	}
}

/* WooCommerce marks required fields with a pure-red asterisk of its own. It never passed on
   white either (3.99:1), but the field takes it to 3.65 and it is the one element this change
   made measurably worse, so it moves to the palette red that carries text — 5.06:1 on white,
   4.71:1 here. The asterisk is the only signal that a field is required, so it has to be read,
   not just seen. */
.required,
.wpcf7 .required,
/* WooCommerce ships `.woocommerce-js form .form-row .required` (0,3,0), so the plain class
   loses; this matches its depth and adds the tag to clear it outright. */
body .woocommerce-js form .form-row .required,
body .woocommerce form .form-row .required {
	color: var(--ipt-red-ink);
	text-decoration: none;
}


/* ============================================================================
   INSTALL STEPS
   Eight steps that are really three phases: done once, a choice between two
   things, and what you see afterwards. The numbering stays continuous 1–8
   across the groups (<ol start>), so it still reads as one job.
   ========================================================================== */

.ipt-fu-steps__group + .ipt-fu-steps__group { margin-top: 26px; }

.ipt-fu-steps__phase {
	display: flex;
	align-items: center;
	gap: 10px;
	font-family: 'Montserrat', sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-blue-dark);
	margin-bottom: 10px;
}
/* the rule runs to the end of the line, so the phase reads as a divider rather than a heading
   competing with the section's own <h2> */
.ipt-fu-steps__phase::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--ipt-line);
}

.entry-content ol.ipt-fu-steps {
	list-style: none;
	margin: 0;
	padding: 0;
}
.entry-content ol.ipt-fu-steps > li.ipt-fu-step {
	display: grid;
	grid-template-columns: 30px minmax(0, 1fr);
	gap: 14px;
	align-items: start;
	margin: 0;
	padding: 9px 0;
}
.ipt-fu-step__n {
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line-strong);
	color: var(--ipt-blue-dark);
	font-family: 'Montserrat', sans-serif;
	font-size: 13.5px;
	font-weight: 700;
	display: flex;
	align-items: center;
	justify-content: center;
}
.ipt-fu-step__body { display: block; padding-top: 4px; }
.ipt-fu-step__text { display: block; font-size: 15px; line-height: 1.55; color: var(--ipt-ink); }

/* The shortcode was set as bold text inside the sentence, where it read as emphasis rather than
   as something to copy. On its own line it is unmistakably a thing you paste. */
.entry-content code.ipt-fu-step__code {
	display: inline-block;
	margin-top: 8px;
	padding: 5px 10px;
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 6px;
	font-size: 13px;
	color: var(--ipt-blue-dark);
}
.ipt-fu-step__note {
	display: block;
	margin-top: 6px;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--ipt-muted);
}
.entry-content .ipt-fu-step__note code {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 5px;
	padding: 1px 5px;
	font-size: 0.92em;
}

@media (max-width: 544px) {
	.entry-content ol.ipt-fu-steps > li.ipt-fu-step { grid-template-columns: 26px minmax(0, 1fr); gap: 11px; }
	.ipt-fu-step__n { width: 26px; height: 26px; font-size: 12.5px; }
}


/* ============================================================================
   RELEASE NOTE ITEMS
   The changelog was already typed — "Added" opens about 37% of entries, the fix
   words about 23% — and a disc threw that away. The marker is derived from the
   first word; the sentence still begins with that word, so colour is never the
   only signal and the marker is reinforcement rather than information.
   ========================================================================== */

/* The row header carries 22px of padding; zeroing the list's own padding to drop the disc's
   indent took that away too, so the markers hung 22px OUTSIDE the row's content box, to the left
   of the version number they belong to. The padding is restored explicitly and matched to the
   header, so a marker lines up under its version rather than beside it. */
.entry-content ul.ipt-rn-row__items {
	list-style: none;
	margin: 0;
	padding: 4px 22px 16px;
}
.entry-content ul.ipt-rn-row__items > li.ipt-rn-item {
	display: grid;
	grid-template-columns: 20px minmax(0, 1fr);
	gap: 11px;
	align-items: start;
	margin: 0;
	padding: 7px 0;
}
.ipt-rn-item__mark {
	width: 20px;
	height: 20px;
	margin-top: 1px;
	border-radius: 6px;
	border: 1px solid var(--ipt-line);
	background: var(--ipt-surface);
	display: flex;
	align-items: center;
	justify-content: center;
}
.ipt-rn-item__mark::after {
	content: "";
	width: 7px;
	height: 7px;
	border-radius: 2px;
	background: var(--ipt-muted);
}
.ipt-rn-item__text { font-size: 14.5px; line-height: 1.55; color: var(--ipt-muted); }

.ipt-rn-item--added   .ipt-rn-item__mark { background: #eaf3ff; border-color: var(--ipt-line-strong); }
.ipt-rn-item--added   .ipt-rn-item__mark::after { background: var(--ipt-blue-link); }
.ipt-rn-item--fixed   .ipt-rn-item__mark { background: #fdeeee; border-color: #eab8b8; }
.ipt-rn-item--fixed   .ipt-rn-item__mark::after { background: var(--ipt-red-fill); }
.ipt-rn-item--changed .ipt-rn-item__mark { background: #eef6f0; border-color: #bcd9c4; }
.ipt-rn-item--changed .ipt-rn-item__mark::after { background: #2f7d4f; }

/* "(Pro version)" was on 287 entries. At the end of a line, repeated that many times, it read as
   noise; as a tag it is scannable and stops interrupting the sentence. */
.ipt-rn-pro {
	display: inline-block;
	margin-left: 2px;
	vertical-align: 1px;
	font-family: 'Montserrat', sans-serif;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--ipt-blue-dark);
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 4px;
	padding: 1px 6px;
	white-space: nowrap;
}

/* Follows the row header, which drops to 16px of padding at this width. This lives AFTER the
   base rule rather than beside the other 921px rules: the two selectors are equally specific,
   a media query adds no specificity, so source order is the only thing that decides. */
@media (max-width: 921px) {
	.entry-content ul.ipt-rn-row__items { padding: 4px 16px 14px; }
}


/* ============================================================================
   MY ACCOUNT
   The last page still wearing WooCommerce defaults. Nothing here changes what
   WooCommerce does — the markup comes from woocommerce/myaccount/ overrides in
   this theme, and these are their styles.
   ========================================================================== */

/* ---- the banner, as on every other page ---------------------------------- */
.ipt-acc-banner {
	background: var(--ipt-blue-dark);
	margin: 0 calc(-50vw + 50%);
	width: 100vw;
	padding: 44px 0 46px;
}
.ipt-acc-banner__in { max-width: 1240px; margin: 0 auto; padding: 0 24px; }
.ipt-acc-eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
	color: rgba(255, 255, 255, 0.70); margin: 0;
}
.ipt-acc-crumbs { font-size: 13.5px; color: rgba(255, 255, 255, 0.70); }
.ipt-acc-crumbs a { color: rgba(255, 255, 255, 0.70); text-decoration: none; }
.ipt-acc-crumbs a:hover, .ipt-acc-crumbs a:focus-visible { color: #fff; text-decoration: underline; }
.ipt-acc-crumbs__sep { margin: 0 7px; }
.ipt-acc-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px; font-weight: 800; color: #fff; line-height: 1.15; margin: 8px 0 0;
}
.ipt-acc-sub { font-size: 17px; line-height: 1.55; color: rgba(255, 255, 255, 0.88); margin: 8px 0 0; max-width: 620px; }

/* ---- the shell ----------------------------------------------------------- */
/* Astra's plain container is a FLEX row — it exists to put #primary beside a sidebar — so the
   banner became a flex item and took half the width, with the content squeezed into the rest.
   The news post hit exactly this. Back to a block, at the 1240 shell docs and news both use. */
.ipt-account .site-content > .ast-container {
	display: block;
	max-width: 1240px;
}
.ipt-account #primary { max-width: none; width: 100%; margin: 0; float: none; }
/* account-page spacing only — the order-received page shares .ipt-acc-ui but starts with a
   full-bleed band, and 34px here printed a pale strip above it */
.ipt-account .entry-content > .woocommerce { margin-top: 34px; }

.ipt-acc {
	display: grid;
	grid-template-columns: 260px minmax(0, 1fr);
	gap: 40px;
	align-items: start;
}
/* WooCommerce ships its own float layout — `.woocommerce-account .woocommerce-MyAccount-navigation
   { float: left; width: 30% }` at (0,2,0) — which inside a 260px grid column resolves to 78px and
   collapses the rail. The grid owns the layout here, so both floats are released at (0,3,0). */
.ipt-account .ipt-acc > .woocommerce-MyAccount-navigation,
.ipt-account .ipt-acc > .woocommerce-MyAccount-content {
	float: none;
	width: auto;
	margin: 0;
}

/* ---- rail ---------------------------------------------------------------- */
.ipt-acc-ui .entry-content .ipt-acc-nav ul {
	list-style: none; margin: 0; padding: 8px;
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 12px;
}
.ipt-acc-ui .entry-content .ipt-acc-nav li { margin: 0; padding: 0; border: 0; }
.ipt-acc-ui .entry-content .ipt-acc-nav a {
	display: flex;
	align-items: center;
	gap: 11px;
	padding: 11px 13px;
	border-radius: 8px;
	font-size: 14.5px;
	color: var(--ipt-muted);
	text-decoration: none;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.ipt-acc-nav__dot {
	width: 7px; height: 7px; border-radius: 2px;
	background: var(--ipt-line-strong); flex-shrink: 0;
	transition: background-color 0.15s ease;
}
.ipt-acc-ui .entry-content .ipt-acc-nav a:hover,
.ipt-acc-ui .entry-content .ipt-acc-nav a:focus-visible { background: var(--ipt-surface); color: var(--ipt-blue-dark); }
.ipt-acc-ui .entry-content .ipt-acc-nav .is-active a {
	background: var(--ipt-surface);
	color: var(--ipt-blue-dark);
	font-weight: 700;
}
.ipt-acc-nav .is-active .ipt-acc-nav__dot { background: var(--ipt-blue-link); }

/* ---- cards --------------------------------------------------------------- */
.ipt-acc-stack { display: flex; flex-direction: column; gap: 18px; }
.ipt-acc-card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 24px 26px 26px;
}
.ipt-acc-card--flush { padding: 0; overflow: hidden; }
.ipt-acc-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; }
.ipt-acc-card__head--pad { padding: 22px 26px 14px; }
.ipt-acc-card__meta { font-size: 13.5px; color: var(--ipt-muted); }
.ipt-acc-card__more { font-size: 14px; font-weight: 600; }

.ipt-acc-ui .entry-content .ipt-acc-h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0;
}
.ipt-acc-ui .entry-content .ipt-acc-h2--pad { padding: 22px 26px 14px; }
.ipt-acc-ui .entry-content .ipt-acc-h3 {
	font-family: 'Montserrat', sans-serif;
	font-size: 15.5px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0 0 8px;
}
.ipt-acc-ui .entry-content .ipt-acc-lede { font-size: 15px; line-height: 1.6; color: var(--ipt-muted); margin: 8px 0 18px; }
.ipt-acc-ui .entry-content .ipt-acc-note { font-size: 14px; line-height: 1.55; color: var(--ipt-muted); margin: 0 0 14px; }
.ipt-acc-ui .entry-content .ipt-acc-foot { font-size: 14px; color: var(--ipt-muted); margin: 0; }
.ipt-acc-ui .entry-content .ipt-acc-empty { font-size: 14.5px; color: var(--ipt-muted); margin: 0; padding: 18px 26px 24px; }
.ipt-acc-ui .entry-content .ipt-acc-go { margin: 0; }
.ipt-acc-go a, .ipt-acc-card__more { font-weight: 600; }
.ipt-acc-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }

/* ---- buttons ------------------------------------------------------------- */
/* Astra's global button is white on --ipt-blue, which is 4.02:1 and fails at this size. Both
   states are stated so `button:hover,button:focus` cannot fill in whichever one is missing. */
/* `body` is carried on the front of both button selectors deliberately. The theme's own link
   colour rule is `body:not(.ast-page-builder-template) .entry-content a` — (0,2,2), because the
   :not() argument counts — so a plain `.entry-content a.ipt-acc-btn` at (0,2,1) loses to it and
   the button renders with blue text on the red fill. */
.ipt-acc-ui .entry-content a.ipt-acc-btn,
.ipt-acc-btn {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	background: var(--ipt-red-fill);
	color: #fff;
	border: 0;
	border-radius: 7px;
	padding: 12px 22px;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.ipt-acc-ui .entry-content a.ipt-acc-btn:hover, .ipt-acc-ui .entry-content a.ipt-acc-btn:focus,
.ipt-acc-btn:hover, .ipt-acc-btn:focus { background: var(--ipt-red-fill-hover); color: #fff; }

.ipt-acc-ui .entry-content a.ipt-acc-btn2,
.ipt-acc-btn2 {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	background: #fff;
	color: var(--ipt-blue-link);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
	padding: 8px 15px;
	font-size: 13.5px;
	font-weight: 600;
	text-decoration: none;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.ipt-acc-ui .entry-content a.ipt-acc-btn2:hover, .ipt-acc-ui .entry-content a.ipt-acc-btn2:focus,
.ipt-acc-btn2:hover, .ipt-acc-btn2:focus {
	background: var(--ipt-surface); color: var(--ipt-blue-dark); border-color: var(--ipt-blue-dark);
}
.ipt-acc-ui .entry-content .ipt-acc-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 0; }
.ipt-acc-actions__aside { font-size: 14px; color: var(--ipt-muted); }

/* ---- order rows ---------------------------------------------------------- */
.ipt-acc-thead,
.ipt-acc-row {
	display: grid;
	grid-template-columns: 96px minmax(0, 1fr) 104px 108px 92px 84px;
	gap: 16px;
	align-items: center;
}
.ipt-acc-thead {
	padding: 13px 26px;
	background: var(--ipt-surface);
	border-bottom: 1px solid var(--ipt-line);
	font-family: 'Montserrat', sans-serif;
	font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ipt-muted);
}
.ipt-acc-thead__r { text-align: right; }
.ipt-acc-row { padding: 15px 26px; border-top: 1px solid var(--ipt-line); font-size: 14.5px; }
.ipt-acc-card--flush .ipt-acc-thead + .ipt-acc-row { border-top: 0; }
.ipt-acc-ui .entry-content a.ipt-acc-row__ref { font-family: 'Montserrat', sans-serif; font-weight: 700; text-decoration: none; }
.ipt-acc-row__items { color: var(--ipt-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ipt-acc-row__date { color: var(--ipt-muted); }
.ipt-acc-row__total { text-align: right; font-family: 'Montserrat', sans-serif; font-weight: 700; color: var(--ipt-ink); }
.ipt-acc-row__go { display: flex; justify-content: flex-end; }

.ipt-acc-badge {
	display: inline-block;
	font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
	border-radius: 4px; padding: 2px 8px; white-space: nowrap;
}
.ipt-acc-badge--good    { color: #2f7d4f; background: #eef6f0; border: 1px solid #bcd9c4; }
.ipt-acc-badge--wait    { color: #8a5a00; background: #fff6e8; border: 1px solid #e8c99a; }
.ipt-acc-badge--bad     { color: var(--ipt-red-ink); background: #fdeeee; border: 1px solid #eab8b8; }
.ipt-acc-badge--neutral { color: var(--ipt-muted); background: var(--ipt-surface); border: 1px solid var(--ipt-line); }

.ipt-acc-pager { display: flex; align-items: center; gap: 16px; margin-top: 18px; }
.ipt-acc-pager__at { font-size: 13.5px; color: var(--ipt-muted); }

/* ---- downloads ----------------------------------------------------------- */
.ipt-acc-dl { display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; gap: 20px; align-items: center; }
.ipt-acc-dl__icon {
	width: 56px; height: 56px; border-radius: 14px;
	background: var(--ipt-surface); border: 1px solid var(--ipt-line-strong);
	display: flex; align-items: center; justify-content: center; color: var(--ipt-blue-dark);
}
.ipt-acc-dl__icon svg { width: 26px; height: 26px; }
.ipt-acc-ui .entry-content .ipt-acc-dl__meta { font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); margin: 6px 0 0; }
.ipt-acc-ui .entry-content .ipt-acc-dl__facts { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0 0; }
.ipt-acc-fact {
	font-size: 12.5px; color: var(--ipt-ink);
	background: var(--ipt-surface); border: 1px solid var(--ipt-line);
	border-radius: 999px; padding: 4px 12px;
}
.ipt-acc-ui .entry-content .ipt-acc-dl__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 19px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0;
}
.ipt-acc-dl__go { white-space: nowrap; }

.ipt-acc-dlrow {
	display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: 16px; align-items: center;
	background: var(--ipt-surface); border: 1px solid var(--ipt-line); border-radius: 8px;
	padding: 16px 18px; margin-top: 14px;
}
.ipt-acc-dlrow__icon {
	width: 48px; height: 48px; border-radius: 12px; background: #fff;
	border: 1px solid var(--ipt-line-strong); display: flex; align-items: center; justify-content: center;
	color: var(--ipt-blue-dark);
}
.ipt-acc-dlrow__icon svg { width: 22px; height: 22px; }
.ipt-acc-dlrow__t { display: block; font-family: 'Montserrat', sans-serif; font-size: 15.5px; font-weight: 700; color: var(--ipt-ink); }
.ipt-acc-dlrow__m { display: block; font-size: 14px; color: var(--ipt-muted); margin-top: 3px; }

/* ---- one order ----------------------------------------------------------- */
.ipt-acc-facts { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.ipt-acc-facts__list { display: flex; gap: 40px; flex-wrap: wrap; }
.ipt-acc-fact-item__k {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ipt-muted);
}
.ipt-acc-fact-item__v { display: block; font-size: 15.5px; color: var(--ipt-ink); margin-top: 5px; }
.ipt-acc-facts__go { display: flex; gap: 8px; flex-wrap: wrap; }

.ipt-acc-item {
	display: grid; grid-template-columns: minmax(0, 1fr) 60px 100px; gap: 16px; align-items: center;
	padding: 14px 26px; border-top: 1px solid var(--ipt-line); font-size: 14.5px;
}
/* __n is the item name, __q the quantity, __t the price — the same three across the receipt
   and the account order view, so the two screens read identically. */
.ipt-acc-item__n { font-family: 'Montserrat', sans-serif; font-weight: 700; color: var(--ipt-ink); }
.ipt-acc-item__q { color: var(--ipt-muted); text-align: right; }
.ipt-acc-item__t { text-align: right; font-family: 'Montserrat', sans-serif; font-weight: 700; color: var(--ipt-ink); }
.ipt-acc-totals { border-top: 1px solid var(--ipt-line); background: var(--ipt-surface); padding: 14px 26px 18px; }
/* `auto` with a floor, not a hard 100px: the rows carry prices AND text — "Credit / Debit Card"
   wrapped onto three lines in a fixed 100px column. */
.ipt-acc-total { display: grid; grid-template-columns: minmax(0, 1fr) minmax(100px, auto); gap: 16px; padding: 5px 0; font-size: 14px; color: var(--ipt-muted); }
.ipt-acc-total__k { text-align: left; }
.ipt-acc-total__v { text-align: right; font-family: 'Montserrat', sans-serif; }
.ipt-acc-total--grand { font-size: 16px; color: var(--ipt-ink); font-weight: 700; }
/* Woo puts a 1px box and 14.5px of padding on `address`, drawing a second frame inside the
   Billing card. */
.ipt-acc-ui .entry-content .ipt-acc-address,
.ipt-acc-address { font-style: normal; font-size: 14.5px; line-height: 1.7; color: var(--ipt-muted); border: 0; padding: 0; border-radius: 0; }

/* ---- signed out ---------------------------------------------------------- */
.ipt-acc-login {
	display: grid;
	grid-template-columns: minmax(0, 460px) minmax(0, 320px);
	gap: 40px;
	justify-content: center;
	align-items: start;
	margin-top: 34px;
}
/* WooCommerce gives .woocommerce-form-login its own border, padding and radius, which inside the
   card above it renders as a box drawn inside a box. The card is the surface; the form is not. */
.ipt-acc-login form.woocommerce-form-login {
	border: 0;
	padding: 0;
	border-radius: 0;
	background: none;
}
/* Woo ships `.woocommerce form.login { border: 1px solid #d1d5db; padding: 20px; margin: 2em 0 }`,
   which drew a second rounded box inside the card and left 59px of empty card below the button. */
.ipt-acc-ui .entry-content form.login,
.ipt-acc-ui .entry-content form.register,
.ipt-acc-ui .entry-content form.lost_reset_password {
	border: 0;
	padding: 0;
	margin: 0;
	border-radius: 0;
}
.ipt-acc-ui .entry-content .ipt-acc-field { display: flex; flex-direction: column; gap: 7px; margin: 0 0 18px; }
.ipt-acc-field__row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ipt-acc-ui .entry-content .ipt-acc-field label {
	font-family: 'Montserrat', sans-serif;
	font-size: 13.5px; font-weight: 700; color: var(--ipt-ink);
}
.ipt-acc-ui .entry-content .ipt-acc-field__aside { font-size: 13.5px; font-weight: 400; }
.ipt-acc-login input[type="text"],
.ipt-acc-login input[type="password"] {
	width: 100%;
	height: 44px;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
	background: #fff;
	padding: 0 13px;
	font-size: 15px;
	color: var(--ipt-ink);
}
.ipt-acc-login input[type="text"]:focus,
.ipt-acc-login input[type="password"]:focus {
	border-color: var(--ipt-blue-dark);
	outline: 2px solid var(--ipt-blue-dark);
	outline-offset: 1px;
}
.ipt-acc-ui .entry-content .ipt-acc-remember { margin: 0 0 20px; }
.ipt-acc-ui .entry-content .ipt-acc-remember label {
	display: flex; align-items: center; gap: 9px;
	font-size: 14.5px; font-weight: 400; color: var(--ipt-muted);
}
.ipt-acc-ui .entry-content .ipt-acc-submit { margin: 0; }
.ipt-acc-submit .ipt-acc-btn { width: 100%; justify-content: center; }

.ipt-acc-ui .entry-content .ipt-acc-aside__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 16px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0 0 8px;
}
.ipt-acc-ui .entry-content .ipt-acc-login__aside p { font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); margin: 0 0 14px; }
.ipt-acc-login__aside { border-color: var(--ipt-line-strong); }
.ipt-acc-ui .entry-content .ipt-acc-aside__go { font-weight: 600; margin-bottom: 0; }
.ipt-acc-ui .entry-content .ipt-acc-aside__note {
	margin: 18px 0 0; padding-top: 16px; border-top: 1px solid var(--ipt-line); font-size: 14px;
}

/* ---- empty states -------------------------------------------------------- */
.ipt-acc-blank { text-align: center; padding: 30px 28px 32px; }
.ipt-acc-ui .entry-content .ipt-acc-blank p { font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); max-width: 460px; margin: 8px auto 0; }
.ipt-acc-ui .entry-content .ipt-acc-blank .ipt-acc-go { margin-top: 16px; }

/* ---- narrow -------------------------------------------------------------- */
@media (max-width: 921px) {
	.ipt-acc { grid-template-columns: minmax(0, 1fr); gap: 22px; }
	.ipt-acc-login { grid-template-columns: minmax(0, 1fr); gap: 20px; }
	.ipt-acc-pair { grid-template-columns: minmax(0, 1fr); }
	.ipt-acc-title { font-size: 28px; }
	/* the row becomes two lines rather than six squeezed columns */
	.ipt-acc-thead { display: none; }
	.ipt-acc-row {
		grid-template-columns: minmax(0, 1fr) auto;
		row-gap: 6px;
		padding: 16px 18px;
	}
	.ipt-acc-row__items { grid-column: 1 / -1; white-space: normal; }
	.ipt-acc-row__total { text-align: left; }
	/* the icon column gave the card three left edges on a 320px measure — title and chips at
	   one, button and footnote at another. It is decorative, so it goes. */
	.ipt-acc-dl { grid-template-columns: minmax(0, 1fr); }
	.ipt-acc-dl__icon { display: none; }
	.ipt-acc-dl__go { grid-column: 1 / -1; justify-content: center; }
	.ipt-acc-dlrow { grid-template-columns: 48px minmax(0, 1fr); }
	.ipt-acc-dlrow .ipt-acc-btn { grid-column: 1 / -1; justify-content: center; }
}


/* ---- addresses and the account form -------------------------------------- */
/* Replaces .ipt-acc-addrbox, a tinted panel that was 846x192 around five short lines with the
   Edit button stranded 730px from the text. The card is the surface; the address needs no second
   one. The button sits beside the address so the thing and the action that changes it read as one
   group. */
.ipt-acc-addr {
	display: flex;
	align-items: flex-end;
	gap: 28px;
	flex-wrap: wrap;
}
.ipt-account .ipt-acc-addr .ipt-acc-address {
	font-style: normal;
	font-size: 15px;
	line-height: 1.75;
	color: var(--ipt-ink);
	margin: 0;
	padding: 0 0 0 16px;
	border: 0;
	border-left: 3px solid var(--ipt-line-strong);
	background: none;
	/* <address> is set to 100% elsewhere, which fills the flex row and pushes the button onto a
	   line of its own — the same separation this change exists to remove. */
	width: auto;
	flex: 0 1 auto;
}

/* ---- the address form ---------------------------------------------------- */
.ipt-acc-addr-form { margin: 0; }
/* The Who/Where/Contact fieldsets and their legends are gone: wc-address-i18n.js re-appends every
   .form-row into the field wrapper sorted by data-priority whenever the country changes, so any
   grouping in the markup lasted until the first interaction. The order is carried by those
   priorities now — see ipt_account_address_priorities(). */

/* Six columns. WooCommerce's own form-row-first/last/wide are stripped in the template, so the
   only thing setting a field's width is its span class. */
.ipt-acc-cols {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 16px 18px;
}
.ipt-acc-ui .entry-content .ipt-acc-cols .form-row { margin: 0; padding: 0; }
.ipt-acc-col--1 { grid-column: span 1; }
.ipt-acc-col--2 { grid-column: span 2; }
.ipt-acc-col--3 { grid-column: span 3; }
.ipt-acc-col--4 { grid-column: span 4; }
.ipt-acc-col--5 { grid-column: span 5; }
.ipt-acc-col--6 { grid-column: span 6; }

.ipt-acc-ui .entry-content .ipt-acc-cols label {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 13px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin-bottom: 7px;
}
.ipt-acc-cols input[type="text"],
.ipt-acc-cols input[type="email"],
.ipt-acc-cols input[type="tel"],
.ipt-acc-cols select,
.ipt-acc-cols .select2-container .select2-selection--single {
	width: 100%;
	height: 42px;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
	background: #fff;
	padding: 0 13px;
	font-size: 14.5px;
	color: var(--ipt-ink);
	box-sizing: border-box;
}
.ipt-acc-cols input:focus,
.ipt-acc-cols select:focus {
	border-color: var(--ipt-blue-dark);
	outline: 2px solid var(--ipt-blue-dark);
	outline-offset: 1px;
}
/* select2 is WooCommerce's country/state widget; it renders its own box inside the field */
.ipt-acc-cols .select2-container .select2-selection--single { display: flex; align-items: center; }
.ipt-acc-cols .select2-container--default .select2-selection--single .select2-selection__rendered {
	line-height: normal; padding: 0; color: var(--ipt-ink);
}
.ipt-acc-cols .select2-container--default .select2-selection--single .select2-selection__arrow { height: 40px; }
.ipt-acc-ui .entry-content .ipt-acc-cols .optional { color: var(--ipt-muted); font-weight: 400; }

.ipt-acc-ui .entry-content .ipt-acc-save { display: flex; align-items: center; gap: 18px; margin: 26px 0 0; padding-top: 22px; border-top: 1px solid var(--ipt-line); }
.ipt-acc-cancel { font-size: 14.5px; font-weight: 600; }

@media (max-width: 921px) {
	.ipt-acc-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ipt-acc-col--1, .ipt-acc-col--2, .ipt-acc-col--3 { grid-column: span 1; }
	.ipt-acc-col--4, .ipt-acc-col--5, .ipt-acc-col--6 { grid-column: span 2; }
}
@media (max-width: 544px) {
	.ipt-acc-cols { grid-template-columns: minmax(0, 1fr); }
	.ipt-acc-col--1, .ipt-acc-col--2, .ipt-acc-col--3,
	.ipt-acc-col--4, .ipt-acc-col--5, .ipt-acc-col--6 { grid-column: span 1; }
	.ipt-acc-addr { align-items: flex-start; flex-direction: column; gap: 16px; }
}


/* ---- account details ----------------------------------------------------- */
/* Uses the same .ipt-acc-cols six-column grid as the address form, so the two forms in this
   account share one measure instead of each inventing its own. */
.ipt-acc-form .ipt-acc-card + .ipt-acc-card { margin-top: 16px; }
.ipt-acc-ui .entry-content .ipt-acc-hint {
	display: block;
	font-size: 13px;
	line-height: 1.5;
	color: var(--ipt-muted);
	margin-top: 6px;
}

.ipt-acc-pw__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	flex-wrap: wrap;
}
.ipt-acc-ui .entry-content .ipt-acc-pw__note { margin: 5px 0 0; }
.ipt-acc-pw__toggle svg { transition: transform 0.18s ease; }
.ipt-acc-pw[data-ipt-pw-open] { border-color: var(--ipt-line-strong); }
.ipt-acc-pw[data-ipt-pw-open] .ipt-acc-pw__toggle svg { transform: rotate(180deg); }
.ipt-acc-pw__body { margin-top: 20px; }
/* `hidden` is a UA style and loses to an author display — restated, as everywhere here */
.ipt-acc-pw__body[hidden] { display: none; }

.ipt-acc-ui .entry-content .ipt-acc-save {
	display: flex;
	align-items: center;
	gap: 18px;
	flex-wrap: wrap;
	margin: 20px 0 0;
	padding-top: 0;
	border-top: 0;
}

/* The address form keeps its rule above the buttons; the account form does not need one, because
   its two cards already separate the sections. */
.ipt-acc-addr-form .ipt-acc-save {
	padding-top: 22px;
	border-top: 1px solid var(--ipt-line);
	margin-top: 26px;
}


/* ============================================================================
   ABOUT (/nickolas/)
   Same shape as SERVICES above — the CSS on this site is prefix-scoped per
   page rather than shared, so this block mirrors .ipt-svc-* rather than
   reusing it. Two rules per new wrapper are mandatory and easy to forget: the
   alignfull escape, and switching Astra's link underline back off.
   ========================================================================== */

/* Astra's page-builder template lets an .alignfull group span the viewport; its children then
   need the measure putting back, or the banner copy runs to the window edge. */
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-ab-head > *,
.ast-page-builder-template .entry-content[ast-blocks-layout] > .alignfull.ipt-ab-body > * {
	max-width: 1140px;
	margin-left: auto;
	margin-right: auto;
}

.ipt-ab-head { background: var(--ipt-blue-dark); }
.ipt-ab-eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
	color: rgba(255, 255, 255, 0.70);
	margin: 0;
}
.entry-content .ipt-ab-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 38px; font-weight: 800; line-height: 1.15; color: #fff;
	max-width: 860px;
	margin: 10px 0 0;
}
.entry-content .ipt-ab-sub {
	font-size: 19px; line-height: 1.55; color: rgba(255, 255, 255, 0.88);
	max-width: 700px;
	margin: 14px 0 0;
}

/* ---- lead: portrait beside the statement --------------------------------- */
.ipt-ab-lead {
	display: grid;
	grid-template-columns: 340px minmax(0, 1fr);
	gap: 40px;
	align-items: start;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 32px 34px 34px;
}
.ipt-ab-portrait {
	display: block;
	width: 340px;
	height: auto;
	border-radius: 12px;
	background: var(--ipt-surface);
}
.entry-content .ipt-ab-lead__name {
	font-family: 'Montserrat', sans-serif;
	font-size: 19px; font-weight: 800; color: var(--ipt-blue-dark);
	margin: 16px 0 0;
}
.entry-content .ipt-ab-lead__role { font-size: 14.5px; color: var(--ipt-muted); margin: 3px 0 0; }
.entry-content .ipt-ab-lead__links { display: flex; gap: 16px; margin: 10px 0 0; font-size: 14.5px; font-weight: 600; }

.entry-content .ipt-ab-lead__copy p { font-size: 16px; line-height: 1.65; color: var(--ipt-muted); margin: 0 0 14px; text-wrap: pretty; }
/* AFTER the paragraph rule and one class deeper than it: the opening line is a lede, and the
   generic rule above would otherwise flatten it back to body copy. */
.entry-content .ipt-ab-lead__copy p.ipt-ab-lede {
	font-size: 19px; line-height: 1.6; color: var(--ipt-ink);
	margin: 0 0 16px;
	text-wrap: pretty;
}
.entry-content .ipt-ab-cta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 20px 0 0; }
.ipt-ab-cta__note { font-size: 14px; color: var(--ipt-muted); }

.entry-content a.ipt-ab-btn {
	display: inline-block;
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 16px; font-weight: 700;
	padding: 13px 26px;
	border-radius: 7px;
	text-decoration: none;
	transition: background-color 0.15s ease;
}
.entry-content a.ipt-ab-btn:hover,
.entry-content a.ipt-ab-btn:focus { background: var(--ipt-red-fill-hover); color: #fff; }

/* ---- sections ------------------------------------------------------------ */
.entry-content .ipt-ab-h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px; font-weight: 700; color: var(--ipt-blue-dark);
	margin: 44px 0 0;
}
.entry-content .ipt-ab-h2--gap { margin-top: 52px; }
/* No max-width. It had one, and the paragraph then stopped 322px short of a column the reader can
   see — which reads as a fault rather than as a measure. The notes are written short enough to sit
   on one line instead.

   The .ipt-ab-notewrap around it is still load-bearing: Gutenberg's constrained layout sets
   `margin-left:auto !important` on every DIRECT child of the group, so anything narrower than the
   column gets centred and no selector can win, !important beating specificity. The wrapper is the
   direct child; the paragraph inside it is not. */
.entry-content .ipt-ab-note {
	font-size: 16px; line-height: 1.6; color: var(--ipt-muted);
	margin: 10px 0 0;
}

.ipt-ab-caps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin-top: 22px; }
.ipt-ab-caps--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ipt-ab-cap {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px 26px;
}
.entry-content .ipt-ab-cap__k {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ipt-blue-link);
	margin: 0 0 6px;
}
.entry-content .ipt-ab-cap__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; color: var(--ipt-blue-dark);
	margin: 0;
}
.entry-content .ipt-ab-cap__b { font-size: 15px; line-height: 1.55; color: var(--ipt-muted); margin: 8px 0 0; }

/* the line that turns "can scale" from a claim into a record */
.ipt-ab-proof {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 10px;
	padding: 20px 24px;
	margin-top: 18px;
}
.entry-content .ipt-ab-proof__b { font-size: 16px; line-height: 1.6; color: var(--ipt-ink); margin: 0; text-wrap: pretty; }

/* ---- track record -------------------------------------------------------- */
.ipt-ab-work { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 22px; }
.ipt-ab-case {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px 26px;
}
.entry-content .ipt-ab-case__sector {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ipt-blue-link);
	margin: 0;
}
.entry-content .ipt-ab-case__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px; font-weight: 700; color: var(--ipt-ink);
	margin: 7px 0 0;
}
.entry-content .ipt-ab-case__b { font-size: 15px; line-height: 1.6; color: var(--ipt-muted); margin: 8px 0 0; }
.entry-content .ipt-ab-case__y { font-size: 13px; color: var(--ipt-muted-light); margin: 12px 0 0; }

/* ---- credentials --------------------------------------------------------- */

.ipt-ab-creds { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.ipt-ab-creds span {
	font-size: 14px;
	color: var(--ipt-muted);
	background: #fff;
	border: 1px solid #d3e3f5;
	border-radius: 20px;
	padding: 7px 15px;
}
.ipt-ab-creds strong { color: var(--ipt-ink); font-weight: 700; }

/* ---- narrow -------------------------------------------------------------- */
@media (max-width: 921px) {
	.entry-content .ipt-ab-title { font-size: 30px; }
	.entry-content .ipt-ab-sub { font-size: 17px; }
	.ipt-ab-lead { grid-template-columns: minmax(0, 1fr); gap: 26px; }
	.ipt-ab-portrait { width: 260px; }
	.ipt-ab-caps, .ipt-ab-caps--two, .ipt-ab-work { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 544px) {
	.entry-content .ipt-ab-title { font-size: 26px; }
	.ipt-ab-lead { padding: 24px 20px 26px; }
	.ipt-ab-portrait { width: 100%; max-width: 260px; }
	.entry-content .ipt-ab-cta { gap: 12px; }
}

/* ===========================================================================
   SHORTCODE OPTION REFERENCES — /upload-form-options/ and /file-viewer-options/

   177 attributes across two pages. The problems this solves, in order of how
   much they cost a reader:

     1. There was no way to find an option. One 144-row table, no search, no
        jump navigation, no per-option address. A support reply could only say
        "scroll down to".
     2. The default was the last sentence of a paragraph, in fifteen phrasings.
        It is a field now, in the same place in every entry.
     3. Examples and Variables sat below every option — roughly fifteen screens
        down, which is the same as not existing. They are tabs now.
     4. The old category rows were white on rgba(33,117,155,0.5): 1.52:1, and
        the source of this site's remaining contrast failures.

   Collapse and filtering happen in inc-options.php, never here: everything is
   in the served HTML so Ctrl+F, printing and crawlers still see all 177.
   =========================================================================== */

/* The reference needs more room than an article measure. The docs shell is
   240 | 660 | 260; on these two pages the middle track takes what the rail
   does not need for a list of category names. */
.ipt-options.ipt-doc .site-content > .ast-container {
	grid-template-columns: 240px minmax(0, 1fr) 230px;
}

.ipt-opt { margin-top: 26px; }

/* ---- the bar: tabs and filter, stuck to the top of the viewport ----------- */
.ipt-opt__bar {
	position: sticky;
	top: 0;
	z-index: 6;
	/* The article card has 44px of padding; the bar spans it edge to edge so the
	   rule under the tabs reads as the card's own divider, not a floating line. */
	margin: 0 -44px;
	padding: 0 44px;
	background: #fff;
	border-bottom: 1px solid var(--ipt-line);
}
.ipt-opt__tabs { display: flex; }
.ipt-opt__tablist { display: flex; gap: 4px; flex-shrink: 0; }
.entry-content .ipt-opt__tab {
	flex-shrink: 0;
	display: inline-flex;
	align-items: baseline;
	gap: 7px;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 15px;
	font-weight: 700;
	color: var(--ipt-muted);
	background: transparent;
	border: 0;
	border-bottom: 2px solid transparent;
	padding: 13px 18px;
	cursor: pointer;
	white-space: nowrap;
}
/* colour AND background on both states — Astra's global `button:hover,button:focus`
   supplies white-on-#2878ff for whichever of the two a rule leaves out. */
.entry-content .ipt-opt__tab:hover,
.entry-content .ipt-opt__tab:focus {
	background: var(--ipt-surface);
	color: var(--ipt-blue-dark);
}
.entry-content .ipt-opt__tab:focus { outline: none; }
.entry-content .ipt-opt__tab:focus-visible {
	outline: 3px solid var(--ipt-blue-dark);
	outline-offset: -3px;
}
.entry-content .ipt-opt__tab[aria-selected="true"] {
	color: var(--ipt-blue-dark);
	background: #fff;
	border-bottom-color: var(--ipt-blue-dark);
}
.ipt-opt__tab-n {
	font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
	font-size: 13px;
	font-weight: 400;
	color: var(--ipt-muted);
	font-variant-numeric: tabular-nums;
}
.ipt-opt__tab[aria-selected="true"] .ipt-opt__tab-n { color: var(--ipt-blue-dark); }
/* A filter that matches in a tab you are not looking at is the whole reason the
   filter crosses panels. The count says so; these two states make it visible. */
.ipt-opt__tab[data-hit] .ipt-opt__tab-n { font-weight: 700; color: var(--ipt-blue-dark); }
.ipt-opt__tab[data-zero] .ipt-opt__tab-n { color: #b6c7d8; }

.ipt-opt__filter { padding: 12px 0 14px; }
.ipt-opt__field {
	display: flex;
	align-items: center;
	gap: 9px;
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 9px;
	padding: 9px 13px;
	color: var(--ipt-muted);
}
.ipt-opt__field:focus-within {
	background: #fff;
	border-color: var(--ipt-blue-dark);
	box-shadow: 0 0 0 3px rgba(12, 84, 144, 0.13);
}
.entry-content .ipt-opt__input {
	flex: 1;
	font-family: inherit;
	font-size: 16px;
	color: var(--ipt-ink);
	background: none;
	border: 0;
	padding: 0;
	box-shadow: none;
	outline: none;
	-webkit-appearance: none;
	appearance: none;
}
.ipt-opt__input::placeholder { color: #8ba3ba; opacity: 1; }

/* ---- groups --------------------------------------------------------------- */
.ipt-opt__cat[hidden], .ipt-opt__sub[hidden], .ipt-opt__item[hidden] { display: none; }

.ipt-opt__cat { margin-top: 34px; }
.ipt-opt__cat:first-child { margin-top: 24px; }
body:not(.ast-page-builder-template) .entry-content .ipt-opt__cat-title {
	display: flex;
	align-items: baseline;
	gap: 10px;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 26px;
	font-weight: 600;
	color: var(--ipt-blue-dark);
	margin: 0 0 4px;
	scroll-margin-top: 120px;
}
/* Astra colours every heading in .entry-content at (0,2,2) — the :not() argument counts.
   A subcategory is a LABEL over a group, not a heading competing with the category above it,
   so it is muted; matching the theme's shape is what makes the rule win. */
body:not(.ast-page-builder-template) .entry-content .ipt-opt__sub-title {
	display: flex;
	align-items: baseline;
	gap: 9px;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin: 26px 0 0;
}
.ipt-opt__n {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 12px;
	font-weight: 700;
	color: var(--ipt-muted);
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 99px;
	padding: 3px 9px;
	font-variant-numeric: tabular-nums;
	text-transform: none;
	letter-spacing: 0;
}

/* ---- one option ----------------------------------------------------------- */
.ipt-opt__item {
	padding: 20px 0 18px;
	border-top: 1px solid var(--ipt-line);
	scroll-margin-top: 130px;   /* the sticky bar must not cover a deep-linked entry */
}
.ipt-opt__sub-title + .ipt-opt__item,
.ipt-opt__cat-title + .ipt-opt__item,
.ipt-opt__sub > .ipt-opt__item:first-child { border-top: 0; padding-top: 14px; }
.ipt-opt__item[data-targeted] {
	background: #fffbe9;
	box-shadow: 0 0 0 10px #fffbe9;
	border-radius: 3px;
}

.ipt-opt__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
}
body:not(.ast-page-builder-template) .entry-content .ipt-opt__name {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 8px;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 17px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--ipt-ink);
	margin: 0;
}
body:not(.ast-page-builder-template) .entry-content .ipt-opt__name--var {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 16px;
	color: var(--ipt-blue-dark);
}
/* The anchor is an affordance, not a link in the prose: invisible until the row is hovered
   or it takes keyboard focus. Same specificity shape as the theme rule it has to beat. */
body:not(.ast-page-builder-template) .entry-content a.ipt-opt__hash {
	color: transparent;
	text-decoration: none;
	font-weight: 400;
}
body:not(.ast-page-builder-template) .entry-content .ipt-opt__item:hover a.ipt-opt__hash,
body:not(.ast-page-builder-template) .entry-content a.ipt-opt__hash:focus-visible { color: var(--ipt-line-strong); }

.ipt-opt__badge {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	border-radius: 99px;
	padding: 3px 8px;
	white-space: nowrap;
}
/* Pro and an add-on are different purchases, so they are different badges.
   #7a4a12 on #fdf3e2 is 6.4:1; #0c5490 on #eaf2fb is 7.6:1. */
.ipt-opt__badge--pro { color: #7a4a12; background: #fdf3e2; }
.ipt-opt__badge--ext { color: var(--ipt-blue-dark); background: #eaf2fb; }

.entry-content button.ipt-opt__attr {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	flex: none;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 14px;
	font-weight: 500;
	color: var(--ipt-blue-dark);
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
	padding: 5px 9px;
	cursor: pointer;
}
.entry-content button.ipt-opt__attr:hover,
.entry-content button.ipt-opt__attr:focus {
	background: #eaf2fb;
	color: var(--ipt-blue-dark);
}
.entry-content button.ipt-opt__attr:focus { outline: none; }
.entry-content button.ipt-opt__attr:focus-visible { outline: 3px solid var(--ipt-blue-dark); outline-offset: 2px; }
/* A variable names itself in its own heading, so the copy control carries only the icon. */
.ipt-opt__attr--icon { padding: 6px 8px; }
.ipt-opt__attr svg { opacity: 0.5; }
.ipt-opt__attr[data-copied] svg { opacity: 0; }
.ipt-opt__attr[data-copied]::after {
	content: "copied";
	font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
	font-size: 12px;
	color: #1c7a4a;
	margin-left: -14px;
}

.ipt-opt__def,
.ipt-opt__choices,
.ipt-opt__vars {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 8px;
	margin: 11px 0 0;
}
.ipt-opt__k {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	flex: none;
}
.ipt-opt__def-v {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 14px;
	color: var(--ipt-ink);
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 5px;
	padding: 2px 8px;
	overflow-wrap: anywhere;
}
/* Where the plugin states no default, the entry says so rather than showing an
   invented one. Thirty-eight attributes are in this state. */
.ipt-opt__def-v--none {
	font-family: inherit;
	font-style: italic;
	color: var(--ipt-muted);
	background: none;
	border: 0;
	padding: 0;
}
.ipt-opt__def-note { font-size: 13px; font-style: italic; color: var(--ipt-muted); }

.entry-content .ipt-opt__desc {
	font-size: 16px;
	line-height: 1.7;
	color: #3d5771;
	margin: 10px 0 0;
}
.entry-content .ipt-opt__desc code,
.entry-content .ipt-opt__choices code {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 13.5px;
	background: var(--ipt-surface);
	border-radius: 4px;
	padding: 1px 5px;
	color: var(--ipt-blue-dark);
}
.entry-content .ipt-opt__desc a { color: var(--ipt-blue-link); }

body:not(.ast-page-builder-template) .entry-content a.ipt-opt__var {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 13px;
	color: var(--ipt-blue-link);
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line);
	border-radius: 5px;
	padding: 2px 7px;
	text-decoration: none;
}
body:not(.ast-page-builder-template) .entry-content a.ipt-opt__var:hover { background: #eaf2fb; }
.ipt-opt__vars--none { font-size: 14.5px; font-style: italic; color: var(--ipt-muted); }
.entry-content .ipt-opt__needs { font-size: 14.5px; color: var(--ipt-muted); margin: 9px 0 0; }
.entry-content .ipt-opt__needs a { color: var(--ipt-blue-link); }

/* ---- examples ------------------------------------------------------------- */
.ipt-opt__rec {
	margin-top: 20px;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	overflow: hidden;
	scroll-margin-top: 130px;
}
.ipt-opt__rec[hidden] { display: none; }
.ipt-opt__rec-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	padding: 12px 16px;
	background: var(--ipt-surface);
	border-bottom: 1px solid var(--ipt-line);
}
body:not(.ast-page-builder-template) .entry-content .ipt-opt__rec-title {
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin: 0;
}
.entry-content button.ipt-opt__copy {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	flex: none;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 12px;
	font-weight: 600;
	color: var(--ipt-blue-dark);
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 6px;
	padding: 5px 10px;
	cursor: pointer;
}
.entry-content button.ipt-opt__copy:hover,
.entry-content button.ipt-opt__copy:focus { background: #eaf2fb; color: var(--ipt-blue-dark); }
.entry-content button.ipt-opt__copy:focus { outline: none; }
.entry-content button.ipt-opt__copy:focus-visible { outline: 3px solid var(--ipt-blue-dark); outline-offset: 2px; }
.ipt-opt__copy[data-copied] span::after { content: "d"; }

.entry-content pre.ipt-opt__code {
	margin: 0;
	padding: 14px 16px;
	background: #fff;
	border: 0;
	border-radius: 0;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 13px;
	line-height: 1.7;
	color: #2c4a68;
	/* The longest example is 700 characters. Wrapping beats a scrollbar here:
	   the reader needs to see the whole shortcode to understand the recipe. */
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}
.ipt-opt__code .a { color: var(--ipt-blue-dark); font-weight: 500; }
.ipt-opt__code .s { color: #1c7a4a; }
.ipt-opt__code .v { color: #a8551c; font-weight: 500; }

.ipt-opt__uses {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0;
	padding: 0 16px 14px;
}
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__uses a {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 11.5px;
	color: var(--ipt-blue-dark);
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line);
	border-radius: 5px;
	padding: 3px 7px;
	text-decoration: none;
}
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__uses a:hover { background: #eaf2fb; }

/* ---- nothing matched ------------------------------------------------------ */
.ipt-opt__empty { margin: 30px 0; font-size: 16px; color: var(--ipt-muted); }
.entry-content button[data-ipt-opt-clear] {
	font: inherit;
	color: var(--ipt-blue-link);
	background: none;
	border: 0;
	padding: 0;
	text-decoration: underline;
	cursor: pointer;
}

/* ---- PARAGRAPH SPACING ----------------------------------------------------
   Every field row in an entry is a <p>, and Astra sets paragraph margins inside
   .entry-content at a specificity a single class cannot beat — which showed up
   as a 19.55px hole under the chips in every example card. Reset once here,
   then restate what each row actually needs. Stated last so it is the last
   word, and in the theme's own selector shape so it wins by specificity
   rather than by !important. */
body:not(.ast-page-builder-template) .entry-content .ipt-opt p { margin: 0; }
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__def,
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__choices,
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__vars  { margin-top: 11px; }
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__desc  { margin-top: 10px; }
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__needs { margin-top: 9px; }
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__uses  { padding: 0 16px 14px; }
body:not(.ast-page-builder-template) .entry-content p.ipt-opt__empty { margin: 30px 0; }

/* ---- the rail carries counts on these pages ------------------------------- */
.ipt-options .ipt-toc__list a { display: flex; justify-content: space-between; gap: 10px; }
.ipt-options .ipt-toc__list em {
	font-style: normal;
	font-size: 13px;
	color: #9db3c8;
	font-variant-numeric: tabular-nums;
}
.ipt-options .ipt-toc__item.is-empty a { color: #b6c7d8; }
.ipt-options .ipt-toc__item.is-empty em { color: #cfdced; }

@media (max-width: 1200px) {
	.ipt-options.ipt-doc .site-content > .ast-container {
		grid-template-columns: 220px minmax(0, 1fr);
	}
}
@media (max-width: 921px) {
	.ipt-options.ipt-doc .site-content > .ast-container { grid-template-columns: minmax(0, 1fr); }
	.ipt-opt__bar { margin: 0 -20px; padding: 0 20px; }
	.ipt-opt__head { flex-direction: column; align-items: flex-start; gap: 8px; }
}
/* ---- a call to action inside an article -----------------------------------
   /file-upload-security/ carried a button in Esteem markup — call-to-action-button,
   with the link colour set inline to #ffffff. Esteem is gone, so the button had no
   fill: white text on the white article card, invisible, on the page whose whole
   job is to send the reader to the full security study. One instance sitewide.

   Replaced with a component rather than by reviving the dead theme's class, so any
   article can use it. Blue rather than red: red is reserved for Go Pro, and this
   points at another article, not at a purchase. White on --ipt-blue-dark is 7.6:1.
   -------------------------------------------------------------------------- */
.ipt-doc-cta { margin: 34px 0 0; text-align: center; }
body:not(.ast-page-builder-template) .entry-content a.ipt-doc-cta__btn {
	display: inline-block;
	background: var(--ipt-blue-dark);
	color: #fff;
	font-family: Montserrat, system-ui, sans-serif;
	font-size: 16px;
	font-weight: 700;
	padding: 13px 28px;
	border-radius: 7px;
	text-decoration: none;
	transition: background-color 0.15s ease;
}
body:not(.ast-page-builder-template) .entry-content a.ipt-doc-cta__btn:hover,
body:not(.ast-page-builder-template) .entry-content a.ipt-doc-cta__btn:focus {
	background: var(--ipt-blue-deep);
	color: #fff;
}
body:not(.ast-page-builder-template) .entry-content a.ipt-doc-cta__btn:focus { outline: none; }
body:not(.ast-page-builder-template) .entry-content a.ipt-doc-cta__btn:focus-visible {
	outline: 3px solid var(--ipt-blue-dark);
	outline-offset: 3px;
}

/* ===========================================================================
   RESPONSIVE REPAIRS

   Measured, not guessed: 12 pages rendered at 1440 / 1200 / 992 / 768 / 600 /
   414 / 360 in a real viewport, 84 combinations. Five overflowed, all of them
   on documentation pages at 414 and below, from three separate causes. The
   rest of the site was clean and is untouched.
   =========================================================================== */

/* ---- 1. the docs shell keeps its own layout on a phone ---------------------
   Astra's mobile CSS puts the container back to `display: flex` and hangs a
   `margin-right: -15.75px` on it to cancel its own gutters. On the docs pages
   that margin is 16px of page wider than the screen — the whole document
   scrolled sideways — and the flex row is not the layout this shell is built
   on. The earlier media query only restated grid-template-columns, which does
   nothing once display has been flipped out from under it.
   -------------------------------------------------------------------------- */
/* Specificity, not source order: Astra targets this with an ID —
   `.ast-left-sidebar #content > .ast-container` is (1,2,1) — so the earlier
   `.ipt-doc .site-content > .ast-container` at (0,2,1) never had a chance,
   whichever stylesheet loaded last. body + the id takes this to (1,2,2). */
@media (max-width: 921px) {
	body.ipt-doc #content > .ast-container {
		/* box-sizing FIRST: this container is content-box, so side padding is added to a
		   100% width rather than taken out of it. Without this the padding below is 40px
		   of page wider than the screen — the very bug this block exists to fix. */
		box-sizing: border-box;
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		margin-left: 0;
		margin-right: 0;
		padding-left: 20px;
		padding-right: 20px;
	}
}

/* ---- 2. grid items must be allowed to shrink -------------------------------
   A grid item's automatic minimum size is its min-content, so `min-width: auto`
   quietly refuses to go narrower than the widest unbreakable thing inside it.
   On /upload-form-options/ that was the tab strip — three nowrap tabs, 383px —
   which held #primary at 473px inside a 360px track and pushed the page 113px
   sideways. The container track was already minmax(0, 1fr); the ITEM needed
   the same permission.
   -------------------------------------------------------------------------- */
.ipt-doc #secondary,
.ipt-doc #primary,
.ipt-doc .ipt-rail,
.ipt-doc .site-main,
.ipt-doc .ast-article-single { min-width: 0; }

/* ---- 3. the tab strip scrolls rather than stretching the page --------------
   Same treatment the release-notes strip already has: the tabs stay one row
   and the row scrolls, with the bar itself hidden. Nothing is reachable only
   by dragging — the tabs are a roving-tabindex group, so arrow keys walk the
   whole set including any off-screen, and touch scrolls the strip directly.
   -------------------------------------------------------------------------- */
.ipt-opt__tabs {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;      /* Firefox */
	-ms-overflow-style: none;   /* old Edge */
}
.ipt-opt__tabs::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ---- 4. the current-page marker in the docs navigation --------------------
   `.ipt-docsnav__item.is-current a` pulls itself 14px left so the 3px marker
   sits in the gutter and the label stays in line with its siblings. The box was
   content-box, so the 11px padding and 3px border were ADDED to a full-width
   block: 374px of link in a 360px sidebar, starting at -6. Fine while the
   sidebar was a 240px column with room beside it; wrong the moment it became
   the full width of a phone.

   border-box plus a matching width keeps the pull without growing the box: the
   link occupies exactly -14px to the right edge, and nothing overflows.
   -------------------------------------------------------------------------- */
.ipt-docsnav__item.is-current a {
	box-sizing: border-box;
	width: calc(100% + 14px);
}

/* ---- 5. article padding on a small screen ---------------------------------
   The card's 44px of side padding is right at 660px of column. At 360 it left
   272px for the text — a 38-character measure, and 88px of the screen given to
   white space. 20px keeps the card reading as a card.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
	.ipt-doc .ast-separate-container .ast-article-single,
	.ipt-doc .ast-article-single { padding: 26px 20px 30px; }
	/* The 38px rule is written as `.ipt-doc.page .ast-article-single .entry-title` (0,3,1),
	   so a plain `.ipt-doc .entry-title` in a media query never reached it. Same shape. */
	.ipt-doc.single .ast-article-single .entry-title,
	.ipt-doc.page .ast-article-single .entry-title,
	.ipt-doc .ast-article-single > .entry-title,
	.ipt-doc h1.entry-title { font-size: 30px; }
	/* the sticky bar spans the card, so its bleed has to match the new padding */
	.ipt-opt__bar { margin: 0 -20px; padding: 0 20px; }
}

/* ---- 6. three things that could not wrap ----------------------------------
   Found at 320px, the narrowest phone still worth supporting. Each is a string
   that was told never to break, in a place where breaking is the only option.
   -------------------------------------------------------------------------- */

/* A shortcode is one long unbreakable token — [wordpress_file_upload_browser]
   is 244px on its own. Unconditional rather than in a media query: the next
   shortcode added to a step could be longer than any breakpoint allows. */
.entry-content code.ipt-fu-step__code {
	max-width: 100%;
	overflow-wrap: anywhere;
}

/* "Most recent: 20 December 2019" was set nowrap so it would sit on one line
   beside the heading. Below 600 it is on its own line anyway, so the nowrap
   only stops it fitting. */
@media (max-width: 600px) {
	.ipt-thread .ipt-comments-head__recent { white-space: normal; }
}

/* Astra lays the comment author and date out as an .ast-row, which does not
   wrap: a long display name plus a full date is wider than a 320px screen. */
@media (max-width: 480px) {
	.ipt-thread .ast-comment-meta {
		display: flex;
		flex-wrap: wrap;
		gap: 2px 8px;
	}
	.ipt-thread .ast-comment-meta > * { float: none; }
}

/* ---- 7. reply indentation on a phone --------------------------------------
   Comments nest five deep on the product page, and every level adds 34px of
   padding to its .children list. At depth 5 on a 320px screen that is 136px of
   indent and 94px of comment — narrower than the author name and date sitting
   in it, which is what still overflowed after everything else was fixed.

   The indent exists to show WHO is replying to WHOM. Two levels carry that;
   beyond it the thread is better read flat than shredded into a column three
   words wide.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
	.ipt-thread .ast-comment-list .children { padding-left: 16px; }
}
@media (max-width: 480px) {
	.ipt-thread .ast-comment-list .children { padding-left: 12px; }
	/* past the third reply the indent stops buying clarity and starts costing
	   the whole measure */
	.ipt-thread .ast-comment-list .depth-3 .children { padding-left: 0; }
}

/* ---- 8. comment pagination wraps ------------------------------------------
   .ipt-cpag is a nowrap flex row holding a label and a list of page numbers.
   Six links come to 256px, which does not fit beside the label on a 320px
   screen. Wrapping is the whole answer: the numbers drop to their own line.
   -------------------------------------------------------------------------- */
@media (max-width: 480px) {
	.ipt-cpag { flex-wrap: wrap; gap: 8px 16px; }
	.ipt-cpag__links { flex-wrap: wrap; }
}

/* ===========================================================================
   TOUCH TARGETS

   Measured at 375px on the real pages. Most controls were already fine — the
   option tabs come out at 44px, the variable chips at 29 — but four were not.
   =========================================================================== */

/* The per-option anchor is a POINTER affordance: invisible until the row is
   hovered, and duplicating a link the reader can get from the address bar. On
   a touch device there is no hover, so it is 12x23px of unreachable target
   repeated 147 times a page. Keyed off (hover: none) rather than a width,
   because that is the actual condition. */
@media (hover: none) {
	.ipt-opt__hash { display: none; }
}

/* The docs navigation is the primary way around the documentation, and on a
   phone it is the full width of the screen. 30px tall was thin for a thumb. */
@media (max-width: 921px) {
	.ipt-docsnav__item a { padding: 10px 0; }
	.ipt-doc #secondary .sub-menu a { padding-top: 10px; padding-bottom: 10px; }
}

/* Copying an attribute name is the single most-used action on the option
   pages, and the chip was 26px tall. */
@media (max-width: 600px) {
	.entry-content button.ipt-opt__attr { padding: 9px 11px; }
}

/* "Reply" was 18x30px — the smallest control on the site. */
@media (max-width: 600px) {
	.ipt-thread .comment-reply-link {
		display: inline-flex;
		align-items: center;
		min-height: 36px;
		padding: 0 10px;
		margin-left: -10px;
	}
}

/* ===========================================================================
   CARD GRIDS THAT NEVER COLLAPSED

   Seven multi-column card grids were written with a fixed repeat() and no
   breakpoint, so they kept their desktop column count all the way down. They
   never triggered an overflow check — minmax(0, 1fr) lets a column shrink
   indefinitely — they just got narrower until they stopped being readable.
   Measured at 375px before this block:

     .ipt-kb-read           3 columns   401px -> 97px    8-line titles
     .ipt-kb-topics         2 columns   611px -> 155px
     .ipt-svc-caps          2 columns   561px -> 155px
     .ipt-svc-work          2 columns   561px -> 155px
     .ipt-svc-enquiry       2 columns   513px -> 107px
     .ipt-cat-grid          2 columns   611px -> 147px
     .ipt-cat-others__grid  4 columns   292px -> 60px

   The rule used below: a card carrying a heading and a sentence needs about
   300px before the title starts breaking into stacks of single words, so a
   two-column grid drops to one at 660px and a three-column grid drops to two
   at 992. Short chips need less, so the four-up steps down later.

   .ipt-fu-step and .ipt-rn-item also keep their column count at every width
   and are deliberately left alone: their first track is a 20-30px icon
   gutter, not a card.
   =========================================================================== */

@media (max-width: 992px) {
	.ipt-kb-read { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 768px) {
	.ipt-cat-others__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 660px) {
	.ipt-kb-read,
	.ipt-kb-topics,
	.ipt-svc-caps,
	.ipt-svc-work,
	.ipt-svc-enquiry,
	.ipt-cat-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 420px) {
	.ipt-cat-others__grid { grid-template-columns: minmax(0, 1fr); }
}

/* ===========================================================================
   THE CONTENTS RAIL ON NARROW SCREENS

   Below 1200px the rail was simply hidden, and below 921 the documentation
   navigation was ordered to the very bottom. On /upload-form-options/ that put
   the nav at 38,924px down a 40,339px page and removed the category jump list
   altogether — so a phone had the filter and nothing else.

   The rail now moves ABOVE the article instead of disappearing. It is the
   contents of what you are about to read, which is exactly where a contents
   list belongs when there is no room beside the text.
   =========================================================================== */

@media (max-width: 1199px) {
	/* Two tracks at this width — nav, then content. The rail takes the content
	   track above the article rather than becoming a third column. */
	.ipt-doc .ipt-rail {
		display: flex;
		position: static;
		grid-column: 2;
		grid-row: 1;
		margin-bottom: 20px;
	}
	.ipt-doc #secondary { grid-column: 1; grid-row: 1 / span 2; }
	.ipt-doc #primary   { grid-column: 2; grid-row: 2; }

	/* "Still stuck?" is an after-the-reading card and must not lead the page.
	   Nothing is lost: the article already ends with "Did this solve your
	   problem?" and the footer carries Contact. */
	.ipt-doc .ipt-rail__help { display: none; }

	/* A column of links is a sidebar device. Across the top they read better as
	   chips that wrap into rows, and cost two lines instead of twelve. */
	.ipt-doc .ipt-toc__list { flex-direction: row; flex-wrap: wrap; gap: 8px; }
	.ipt-doc .ipt-toc__item a {
		border-left: 0;
		padding: 6px 12px;
		background: var(--ipt-field);
		border: 1px solid var(--ipt-line);
		border-radius: 99px;
	}
	.ipt-doc .ipt-toc__item a:hover,
	.ipt-doc .ipt-toc__item.is-current a {
		background: #eaf2fb;
		border-color: var(--ipt-line-strong);
	}
	.ipt-doc .ipt-toc__item--h3 a { padding-left: 12px; }
	.ipt-doc .ipt-toc__thread { margin-top: 12px; }
}

@media (max-width: 921px) {
	/* One track: explicit placement comes off and plain ordering takes over —
	   contents, article, then the documentation index. */
	.ipt-doc .ipt-rail,
	.ipt-doc #primary,
	.ipt-doc #secondary { grid-column: auto; grid-row: auto; }
	.ipt-doc .ipt-rail  { order: 1; }
	.ipt-doc #primary   { order: 2; }
	.ipt-doc #secondary { order: 3; }
}

/* ---- 9. inline geometry baked into old imported content -------------------
   Three articles carry eight hard-coded horizontal margins, and thirty pixel
   widths are scattered through the content. One of them — a
   `margin-right: 100px` on an anchor, spacing two screenshots side by side on
   /improve-styling-of-wordpress-file-upload-plugin/ — held the page 59px wider
   than a 360px phone. The image itself was correctly capped at 100%; the line
   box was not, which is why nothing showed up as an over-wide element and only
   the parent scrollWidth gave it away.

   Inline styles beat any stylesheet, so this needs !important. It is scoped by
   attribute, so it reaches only the elements actually carrying the declaration,
   and only at widths where there is no room for it. Like the justify override,
   this is a patch over content pollution: the real repair is to strip the
   inline styles from the database.
   -------------------------------------------------------------------------- */
@media (max-width: 700px) {
	body:not(.ast-page-builder-template) .entry-content [style*="margin-right"],
	body:not(.ast-page-builder-template) .entry-content [style*="margin-left"] {
		margin-right: 0 !important;
		margin-left: 0 !important;
	}
	body:not(.ast-page-builder-template) .entry-content [style*="width"] {
		max-width: 100% !important;
	}
}

/* ===========================================================================
   LEGAL PAGES — /privacy/, /terms-of-sale/, /refunds/

   A policy nobody reads protects nobody, so these are set to be read: an
   "In short" box carrying the four facts somebody came for, numbered
   sections, and a table where the content is a table rather than prose
   pretending to be one.

   The three share one prefix and one stylesheet block; there is no
   per-document styling, because a reader who has learnt one should not have
   to learn the next.
   =========================================================================== */

.ipt-legal { margin-top: 8px; }

/* The draft notice. Amber rather than red: this is a caveat, not an error,
   and it is removed by deleting one paragraph once a lawyer has signed off. */
body:not(.ast-page-builder-template) .entry-content p.ipt-legal-draft {
	margin: 0 0 28px;
	padding: 14px 18px;
	background: #fdf3e2;
	border: 1px solid #f0dcb8;
	border-left: 4px solid #c98a2a;
	border-radius: 8px;
	font-size: 15.5px;
	line-height: 1.6;
	color: #7a4a12;
}
.ipt-legal-draft strong { color: #5e380d; }

/* ---- the summary ---------------------------------------------------------
   Four sentences at the top, in the reader's own terms. Same shape as the
   documentation "Short answer" box, because it does the same job. */
.ipt-legal-gist {
	background: var(--ipt-surface);
	border: 1px solid #d3e3f5;
	border-left: 4px solid var(--ipt-blue-link);
	border-radius: 8px;
	padding: 18px 22px 20px;
	margin: 0 0 34px;
}
.ipt-legal-gist__k {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ipt-blue-link);
}
body:not(.ast-page-builder-template) .entry-content .ipt-legal-gist ul {
	list-style: none;
	margin: 10px 0 0;
	padding: 0;
}
body:not(.ast-page-builder-template) .entry-content .ipt-legal-gist li {
	position: relative;
	padding: 5px 0 5px 20px;
	margin: 0;
	font-size: 16px;
	line-height: 1.6;
	color: var(--ipt-ink);
}
.ipt-legal-gist li::before {
	content: "";
	position: absolute;
	left: 2px;
	top: 14px;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--ipt-blue-link);
}

/* ---- numbered sections ---------------------------------------------------
   The number is a reference, not decoration: "clause 4" has to mean something
   when somebody quotes it back at you. Muted, so the heading still reads
   first. */
body:not(.ast-page-builder-template) .entry-content .ipt-legal h2 {
	font-size: 22px;
	margin: 38px 0 12px;
	scroll-margin-top: 24px;
}
.ipt-legal-n {
	font-family: 'Montserrat', sans-serif;
	font-size: 13px;
	font-weight: 700;
	/* #9db3c8 measured 2.16:1 — it reads as decoration but it is text, and a
	   clause number is the one thing somebody quotes back at you. --ipt-muted
	   is 4.9:1 and still sits behind the heading. */
	color: var(--ipt-muted);
	margin-right: 9px;
}

/* ---- a table where the content is tabular -------------------------------- */
/* Astra draws a BOX around every cell — `table, td, th { border: 1px solid }`
   plus `td, th { border-width: 0 1px 1px 0 }`, in #d1d5db, the same foreign
   grey already corrected on the header and the footer. That vertical rule sat
   hard against the next column's text, because the gutter here is padding-right
   and there is no padding-left. Every border comes off; the only rule kept is
   the horizontal one under each row, which is what separates the rows. */
body:not(.ast-page-builder-template) .entry-content table.ipt-legal-table,
body:not(.ast-page-builder-template) .entry-content table.ipt-legal-table th,
body:not(.ast-page-builder-template) .entry-content table.ipt-legal-table td {
	border: 0;
}
body:not(.ast-page-builder-template) .entry-content table.ipt-legal-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 15.5px;
	margin: 4px 0 24px;
}
/* Columns sized rather than left to the browser: auto layout gave the first
   column 201px and the last 371, so "Name, email address, billing address,
   country" wrapped to three lines while the reason beside it sat on one. */
.ipt-legal-table th:nth-child(1), .ipt-legal-table td:nth-child(1) { width: 32%; }
.ipt-legal-table th:nth-child(2), .ipt-legal-table td:nth-child(2) { width: 24%; }
.ipt-legal-table th:nth-child(3), .ipt-legal-table td:nth-child(3) { width: 44%; }

.ipt-legal-table th {
	text-align: left;
	font-family: 'Montserrat', sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	/* the gutter belongs BETWEEN columns, so it is padding-right on all but the
	   last — the old rule put 14px on the right of every cell including the
	   last, which pulled the table off the card's right edge */
	padding: 0 24px 10px 0;
	border-bottom: 1px solid var(--ipt-line) !important;
}
.ipt-legal-table td {
	padding: 13px 24px 13px 0;
	border-bottom: 1px solid var(--ipt-line) !important;
	color: #3d5771;
	vertical-align: top;
	line-height: 1.6;
}
.ipt-legal-table th:last-child,
.ipt-legal-table td:last-child { padding-right: 0; }
.ipt-legal-table tr:last-child td { border-bottom: 0 !important; }
.ipt-legal-table tr td:first-child { font-weight: 600; color: var(--ipt-ink); }

/* ---- who else touches your data ------------------------------------------ */
.ipt-legal-defn {
	margin: 0 0 20px;
	padding-left: 16px;
	border-left: 2px solid var(--ipt-line);
}
.ipt-legal-defn dt {
	font-family: 'Montserrat', sans-serif;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin-top: 12px;
}
.ipt-legal-defn dd {
	margin: 3px 0 0;
	font-size: 15.5px;
	line-height: 1.65;
	color: #3d5771;
}

body:not(.ast-page-builder-template) .entry-content p.ipt-legal-stamp {
	margin: 36px 0 0;
	padding-top: 18px;
	border-top: 1px solid var(--ipt-line);
	font-size: 14px;
	color: var(--ipt-muted);
}

/* ---- the page is the card ------------------------------------------------
   These pages render in Astra plain container: no article card, and the text
   would otherwise run the full 1200px — about 170 characters a line. Rather
   than change the template, the wrapper IS the card, which also centres it.

   `.entry-content .ipt-legal` and not `.ipt-legal`: a single class loses to
   Astra plain-container width rules, and max-width computed to 1200 until the
   selector matched their weight. 820 minus the padding gives a 730px measure,
   the same order as the documentation. */
body:not(.ast-page-builder-template) .entry-content .ipt-legal {
	max-width: 820px;
	margin: 0 auto;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 40px 44px 44px;
}
@media (max-width: 600px) {
	body:not(.ast-page-builder-template) .entry-content .ipt-legal { padding: 26px 20px 30px; }
}

/* ---- the six plugin app documents ----------------------------------------
   Same card, same type as /privacy/ — they are the same kind of document and a
   reader who has learnt one should not have to learn the next. Only two things
   differ, and both exist because there are SIX of them with near-identical
   names: a kicker saying which thing the document governs, and links to the
   other five at the foot.
   -------------------------------------------------------------------------- */
body:not(.ast-page-builder-template) .entry-content p.ipt-legal-kicker {
	font-family: 'Montserrat', sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin: 0 0 22px;
}
/* These pages open straight into prose rather than an "In short" box, so the
   first paragraph needs the space the box would otherwise have given it. */
.ipt-legal--app > h2:first-of-type { margin-top: 24px; }

.ipt-legal-sibs {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
	margin: 30px 0 0;
	padding-top: 20px;
	border-top: 1px solid var(--ipt-line);
}
.ipt-legal-sibs__k {
	font-family: 'Montserrat', sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin-right: 4px;
}
body:not(.ast-page-builder-template) .entry-content .ipt-legal-sibs a {
	font-size: 13px;
	color: var(--ipt-blue-link);
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line);
	border-radius: 99px;
	padding: 5px 11px;
	text-decoration: none;
}
body:not(.ast-page-builder-template) .entry-content .ipt-legal-sibs a:hover {
	background: #eaf2fb;
	border-color: var(--ipt-line-strong);
}

/* ---- /release-notes/ -----------------------------------------------------
   The component prints its own "Release notes" heading, which is right inside
   the File Upload page and a duplicate here: Astra already prints the page
   title as the h1 directly above it. */
/* This page is on the page-builder template, so the site type rules — all
   scoped body:not(.ast-page-builder-template) — never reach its title. It was
   rendering as Astra default #1e293b at the page edge while the card sat 250px
   in. The title is brought onto the card's column and into the brand colour. */
.ipt-relnotes-page .entry-title,
.ipt-relnotes-page .ast-archive-title {
	max-width: 900px;
	margin-left: auto;
	margin-right: auto;
	font-family: 'Montserrat', sans-serif;
	font-size: 38px;
	font-weight: 700;
	line-height: 1.15;
	color: var(--ipt-blue-dark);
}
.ipt-relnotes-page .ipt-rn__h { display: none; }
.ipt-relnotes-page .ipt-rn__top { margin-top: 0; }
.ipt-relnotes-page .ipt-rn {
	max-width: 900px;
	margin: 8px auto 0;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 30px 34px 34px;
}
@media (max-width: 600px) {
	.ipt-relnotes-page .ipt-rn { padding: 22px 20px 26px; }
}

/* ===========================================================================
   FOOTER

   Was ten links in three ragged columns — four, four, two — with a third of
   the width empty, no statement of what Iptanus is, contact only as an email
   buried in the copyright line, and no route to a single legal document.

   Now: a brand block in a wider first column, three even link columns, and a
   legal bar under a rule. Legal is a BAR and not a fourth column on purpose —
   six legal documents do not deserve the weight of the product, but they have
   to be reachable from every page, and they were reachable from none.

   Astra caps footer widgets at four without Astra Pro, so the legal bar lives
   in the copyright component rather than a fifth widget.
   =========================================================================== */

/* The brand column carries more than a list, so it earns more width.

   The selector matters: `-4-equal` is on the CONTAINER, and the grid Astra
   actually lays the columns out on is `.ast-builder-grid-row` INSIDE it —
   see its own rule, `.ast-builder-grid-row-4-equal .ast-builder-grid-row`.
   Targeting the container instead turns the wrapper into a four-column grid
   and squeezes the real row into its first column: 464px of footer inside
   1440px of page, with every heading wrapping mid-word. */
.site-footer .ast-builder-grid-row-4-equal > .ast-builder-grid-row-container-inner > .ast-builder-grid-row {
	grid-template-columns: 1.5fr 1fr 1fr 1fr;
}

.ipt-foot-brand__mark {
	display: inline-flex;
	align-items: center;
	gap: 11px;
	text-decoration: none;
	margin-bottom: 14px;
}
.ipt-foot-brand__mark img { display: block; width: 36px; height: 36px; }
.ipt-foot-brand__mark span {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
}
.site-footer .ipt-foot-brand__text {
	font-size: 15px;
	line-height: 1.65;
	color: var(--ipt-muted);
	margin: 0 0 18px;
	max-width: 300px;
}
.site-footer a.ipt-foot-brand__mail {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.site-footer a.ipt-foot-brand__mail svg { opacity: 0.75; flex: none; }
.site-footer a.ipt-foot-brand__mail:hover { color: var(--ipt-blue-deep); }

/* ---- the legal bar -------------------------------------------------------
   Links left, the copyright right, one rule above. It sits in the below-footer
   row, which Astra centres by default — this is a full-width bar, so it does
   not want centring. */
.site-footer .ast-footer-copyright { width: 100%; }
.ipt-foot-legal {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px 26px;
	width: 100%;
}
.site-footer ul.ipt-foot-legal__links {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
	list-style: none;
	margin: 0;
	padding: 0;
}
.ipt-foot-legal__links li { margin: 0; }
.site-footer .ipt-foot-legal__links a {
	font-size: 14px;
	color: var(--ipt-muted);
	text-decoration: none;
}
.site-footer .ipt-foot-legal__links a:hover { color: var(--ipt-blue-link); }
.site-footer p.ipt-foot-legal__id {
	margin: 0;
	font-size: 13.5px;
	color: var(--ipt-muted-light);
}
.ipt-foot-legal__id b { color: var(--ipt-muted); font-weight: 600; }

@media (max-width: 921px) {
	.site-footer .ast-builder-grid-row-4-equal > .ast-builder-grid-row-container-inner > .ast-builder-grid-row { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 600px) {
	.site-footer .ast-builder-grid-row-4-equal > .ast-builder-grid-row-container-inner > .ast-builder-grid-row { grid-template-columns: 1fr; }
	.ipt-foot-legal { flex-direction: column; align-items: flex-start; gap: 12px; }
}



/* ===========================================================================
   SEARCH RESULTS
   Astra rendered these as blog cards — featured image, author, date. What a
   searcher needs is what kind of thing each result is, where it sits, and the
   sentence that contains the match.
   =========================================================================== */

/* Full-bleed head, same neutralisation as the docs category index. */
.ipt-searchpage .site-content > .ast-container { max-width: none; padding: 0; }
.ipt-searchpage #primary { margin: 0; padding: 0; width: 100%; max-width: none; }
.ipt-searchpage .ast-container > #primary { margin-top: 0; }

.ipt-search-head { background: var(--ipt-blue-dark); padding: 34px 24px 38px; }
.ipt-search-head__inner { max-width: 1240px; margin: 0 auto; }

.ipt-search-crumbs { font-size: 14px; color: rgba(255, 255, 255, 0.72); }
.ipt-search-crumbs a { color: rgba(255, 255, 255, 0.9); text-decoration: none; }
.ipt-search-crumbs a:hover { color: #fff; text-decoration: underline; }
/* 0.4 alpha measures 2.57:1 on the brand band. 0.7 is 4.71:1. */
.ipt-search-crumbs__sep { color: rgba(255, 255, 255, 0.7); margin: 0 6px; }

.ipt-search-head__title {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px;
	font-weight: 700;
	line-height: 1.15;
	color: #fff;
	margin: 16px 0 0;
}
/* The echoed query is lighter than the label, so the eye lands on the word typed. */
.ipt-search-head__title em { font-style: normal; color: #9fc6ee; }
.ipt-search-head__count { font-size: 15.5px; color: rgba(255, 255, 255, 0.8); margin: 10px 0 0; }

.ipt-search-field {
	display: flex;
	align-items: center;
	gap: 10px;
	background: #fff;
	border-radius: 10px;
	padding: 12px 16px;
	margin: 20px 0 0;
	max-width: 620px;
}
.ipt-search-field svg { color: var(--ipt-muted); flex-shrink: 0; }
.ipt-search-field input[type="search"] {
	flex: 1;
	min-width: 0;
	border: 0;
	background: transparent;
	padding: 0;
	font-family: inherit;
	font-size: 16.5px;
	color: var(--ipt-ink);
}
.ipt-search-field input[type="search"]:focus { outline: none; box-shadow: none; background: transparent; }
.ipt-search-field input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }

.ipt-search-body {
	max-width: 1288px;
	margin: 0 auto;
	padding: 26px 24px 56px;
	display: grid;
	grid-template-columns: minmax(0, 1fr) 280px;
	gap: 40px;
	align-items: start;
}

/* ---- the type filter ---- */
.ipt-search-filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 22px; }
.ipt-search-f {
	display: inline-flex;
	align-items: baseline;
	gap: 7px;
	font-family: 'Montserrat', sans-serif;
	font-size: 14px;
	font-weight: 600;
	color: var(--ipt-muted);
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 99px;
	padding: 7px 14px;
	text-decoration: none;
}
.ipt-search-f:hover { border-color: var(--ipt-line-strong); color: var(--ipt-blue-dark); }
/* The design's #9db3c8 measured 2.4:1 and #7d95ad 3.1:1 on white — both fail at 13px.
   --ipt-muted is 4.71:1 and still reads as secondary against the 600-weight label. */
.ipt-search-f i { font-style: normal; font-family: inherit; font-size: 13px; font-weight: 400; color: var(--ipt-muted); }
.ipt-search-f.is-on { background: var(--ipt-blue-dark); border-color: var(--ipt-blue-dark); color: #fff; }
.ipt-search-f.is-on i { color: rgba(255, 255, 255, 0.78); }

/* ---- one result ---- */
.ipt-search-res {
	display: block;
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 18px 22px;
	margin-bottom: 12px;
	text-decoration: none;
}
.ipt-search-res:hover { border-color: var(--ipt-line-strong); }
.ipt-search-res__top { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }

/* One neutral badge for all four kinds. Colour on this site says what STATE something is in —
   Pro, draft, awaiting — never what KIND it is: that is the badge's own word and the filter
   row's job, and both are already on screen. */
.ipt-search-res__kind {
	font-family: 'Montserrat', sans-serif;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 99px;
	padding: 2px 8px;
	white-space: nowrap;
}
.ipt-search-res__where { font-size: 13px; color: var(--ipt-muted); }
.ipt-search-res__title {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 18px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--ipt-ink);
}
.ipt-search-res:hover .ipt-search-res__title { color: var(--ipt-blue-dark); }
.ipt-search-res__text { display: block; font-size: 15.5px; line-height: 1.6; color: #3d5771; margin-top: 7px; }
.ipt-search-res__text mark { background: #fff2c2; color: inherit; border-radius: 3px; padding: 0 2px; }

/* ---- the folded changelog ---- */
.ipt-search-fold {
	background: #fff;
	border: 1px dashed var(--ipt-line-strong);
	border-radius: 10px;
	padding: 16px 22px;
	margin-bottom: 12px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
}
.ipt-search-fold p { margin: 0; font-size: 15.5px; line-height: 1.6; color: var(--ipt-muted); }
.ipt-search-fold b { color: var(--ipt-ink); font-weight: 600; }
.ipt-search-fold a {
	flex: none;
	font-family: 'Montserrat', sans-serif;
	font-size: 14px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-search-fold a:hover { text-decoration: underline; }

/* ---- arrived from a documentation search box ---- */
.ipt-search-scoped {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	background: var(--ipt-surface);
	border: 1px solid #d3e3f5;
	border-left: 4px solid var(--ipt-blue-link);
	border-radius: 8px;
	padding: 13px 18px;
	margin: 0 0 16px;
}
.ipt-search-scoped p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--ipt-ink); }
.ipt-search-scoped b { font-weight: 600; }
.ipt-search-scoped a {
	flex: none;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-search-scoped a:hover { text-decoration: underline; }

/* ---- nothing found ---- */
.ipt-search-empty {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 40px 24px 34px;
	text-align: center;
}
.ipt-search-empty svg { color: var(--ipt-muted); opacity: 0.35; }
.ipt-search-empty h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 20px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin: 14px 0 6px;
}
.ipt-search-empty p { margin: 0 auto; max-width: 430px; font-size: 15.5px; line-height: 1.65; color: var(--ipt-muted); }
.ipt-search-empty a { color: var(--ipt-blue-link); }
.ipt-search-tries { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 18px; }
.ipt-search-tries a {
	font-size: 14px;
	color: var(--ipt-blue-link);
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line);
	border-radius: 99px;
	padding: 6px 13px;
	text-decoration: none;
}
.ipt-search-tries a:hover { border-color: var(--ipt-line-strong); }

/* ---- rail ---- */
.ipt-search-rail__card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 16px 18px;
}
.ipt-search-rail__card + .ipt-search-rail__card { margin-top: 18px; }
.ipt-search-rail__k {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin: 0 0 12px;
}
.ipt-search-rail__card p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); }
.ipt-search-rail__card a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-search-rail__card a:hover { text-decoration: underline; }
.ipt-search-sug { list-style: none; margin: 0; padding: 0; }
.ipt-search-sug li { margin: 0 0 8px; }
.ipt-search-sug li:last-child { margin-bottom: 0; }
.ipt-search-sug a { font-size: 14.5px; }

/* ---- pagination ---- */
.ipt-searchpage .navigation.pagination { margin-top: 26px; }
.ipt-searchpage .nav-links { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ipt-searchpage .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 38px;
	height: 38px;
	padding: 0 12px;
	font-size: 15px;
	color: var(--ipt-blue-link);
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	text-decoration: none;
}
.ipt-searchpage .page-numbers:hover { border-color: var(--ipt-line-strong); }
.ipt-searchpage .page-numbers.current {
	background: var(--ipt-blue-dark);
	border-color: var(--ipt-blue-dark);
	color: #fff;
}
.ipt-searchpage .page-numbers.dots { border-color: transparent; background: transparent; color: var(--ipt-muted); }

@media (max-width: 1099px) {
	.ipt-search-body { grid-template-columns: minmax(0, 1fr); gap: 26px; }
	/* The rail is a set of offers, not context — it belongs after the results on narrow. */
	.ipt-search-rail { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; }
	.ipt-search-rail__card + .ipt-search-rail__card { margin-top: 0; }
}
@media (max-width: 600px) {
	.ipt-search-head { padding: 26px 20px 30px; }
	.ipt-search-head__title { font-size: 26px; }
	.ipt-search-body { padding: 22px 20px 44px; }
	.ipt-search-fold,
	.ipt-search-scoped { flex-direction: column; align-items: flex-start; gap: 10px; }
	.ipt-search-res__top { flex-wrap: wrap; gap: 8px; }
}


/* ===========================================================================
   HOME PAGE — SEARCH BAND
   Sits between the feature cards and the services band, i.e. AFTER the pitch.
   Someone still scanning the offer is not looking for a search box; someone
   who scrolled past it and is still reading has a question the page has not
   answered. Two hairlines rather than a fourth surface colour, so it reads as
   a plate on the field like the proof strip, not a new kind of section.
   =========================================================================== */

.ipt-homesearch {
	border-top: 1px solid var(--ipt-line);
	border-bottom: 1px solid var(--ipt-line);
}
.ipt-homesearch h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 28px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-homesearch__sub {
	font-size: 17px;
	line-height: 1.55;
	color: var(--ipt-muted);
	margin: 10px 0 0;
}
.ipt-homesearch__fall {
	font-size: 15px;
	color: var(--ipt-muted);
	margin: 18px 0 0;
}
.ipt-homesearch__fall a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-homesearch__fall a:hover { text-decoration: underline; }

/* The same object at the same width as the field on the results page, so the box
   typed into and the box landed on are recognisably one thing.

   Both selectors are doubled up on purpose. Gutenberg's constrained-layout rule
   (`.wp-container-… > *`) caps children at the group's 720px content size, and Astra's
   input rule sets its own padding, border and font-size — both print AFTER the child
   stylesheet, so at equal specificity they win. Measured before the fix: 720px wide and
   68px tall instead of 620 and 52. */
.ipt-homesearch .ipt-sitesearch {
	display: flex;
	align-items: center;
	gap: 10px;
	max-width: 620px;
	margin: 26px auto 0;
	background: #fff;
	border: 1.5px solid var(--ipt-line-strong);
	border-radius: 10px;
	padding: 13px 18px;
}
.ipt-sitesearch__icon { color: var(--ipt-muted); flex-shrink: 0; display: block; }
.ipt-homesearch input.ipt-sitesearch__field {
	flex: 1;
	min-width: 0;
	height: auto;
	border: 0;
	border-radius: 0;
	/* Astra puts a resting inset shadow on every input; inside a bordered wrapper it draws a
	   second rectangle around the text. Cleared at rest, not only on focus. */
	box-shadow: none;
	background: transparent;
	padding: 0;
	font-family: inherit;
	font-size: 17px;
	line-height: 1.4;
	color: var(--ipt-ink);
}
.ipt-homesearch input.ipt-sitesearch__field::placeholder { color: var(--ipt-muted); opacity: 1; }
.ipt-homesearch input.ipt-sitesearch__field:focus { outline: none; box-shadow: none; background: transparent; }
.ipt-homesearch input.ipt-sitesearch__field::-webkit-search-cancel-button { -webkit-appearance: none; }
/* A boundary, not text — 3:1 applies, and #2878ff measures 4.02:1. */
.ipt-homesearch .ipt-sitesearch:focus-within {
	border-color: var(--ipt-blue);
	box-shadow: 0 0 0 3px rgba(40, 120, 255, 0.18);
}

@media (max-width: 782px) {
	.ipt-homesearch h2 { font-size: 23px; }
	.ipt-homesearch__sub { font-size: 16px; }
	.ipt-homesearch .ipt-sitesearch { padding: 12px 14px; }
	/* 16px is a floor, not a preference: below it iOS zooms the viewport on focus. */
	.ipt-homesearch input.ipt-sitesearch__field { font-size: 16px; }
}


/* ===========================================================================
   SINGLE PRODUCT
   WooCommerce's default is a shop layout for a physical object — a 600px photo
   beside a 20px title and a 113px button. This is software costing €40, so the
   page is bands in the same vocabulary as the home page and the search results.
   =========================================================================== */

/* Full-bleed, same neutralisation as the docs category index and the search page. */
.ipt-pdpage .site-content > .ast-container { max-width: none; padding: 0; }
.ipt-pdpage #primary { margin: 0; padding: 0; width: 100%; max-width: none; }
.ipt-pdpage .ast-container > #primary { margin-top: 0; }
.ipt-pdpage .ipt-pd { margin: 0; }
/* Woo prints its own wrappers around the template; they must not re-cap the width. */

/* ---- head ------------------------------------------------------------- */
.ipt-pd-head { background: var(--ipt-blue-dark); padding: 34px 24px 38px; }
.ipt-pd-head__inner { max-width: 1140px; margin: 0 auto; }

.ipt-pd-crumbs { font-size: 14px; color: rgba(255, 255, 255, 0.72); margin: 0; }
.ipt-pd-crumbs a { color: rgba(255, 255, 255, 0.9); text-decoration: none; }
.ipt-pd-crumbs a:hover { color: #fff; text-decoration: underline; }
.ipt-pd-crumbs__sep { color: rgba(255, 255, 255, 0.7); margin: 0 6px; }

.ipt-pd-eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.72);
	margin: 18px 0 0;
}
.ipt-pd-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 38px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	max-width: 820px;
	margin: 10px 0 0;
}
.ipt-pd-stand {
	font-size: 19px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.88);
	max-width: 720px;
	margin: 12px 0 0;
}

/* ---- proof strip ------------------------------------------------------ */
.ipt-pd-proof { background: #fff; border-bottom: 1px solid var(--ipt-line); padding: 20px 24px; }
.ipt-pd-proof__inner {
	max-width: 1140px;
	margin: 0 auto;
	display: flex;
	flex-wrap: wrap;
	justify-content: space-around;
	align-items: center;
	gap: 18px 34px;
	font-size: 15px;
	color: var(--ipt-ink);
}
.ipt-pd-proof__inner b { font-weight: 700; }
.ipt-pd-stars { display: inline-flex; align-items: center; gap: 8px; }

/* The star glyph. Woo's own is #fda256 — 1.99:1, below even the 3:1 a non-text
   indicator needs. --ipt-blue-dark is 7.82:1 on white; amber belongs to state
   and red to the buy action, so neither was available. */
.ipt-pd-stars__glyphs { display: inline-flex; gap: 2px; }
.ipt-pd-star { position: relative; display: inline-block; width: 16px; height: 16px; line-height: 0; }
.ipt-pd-star__on { position: absolute; inset: 0; overflow: hidden; line-height: 0; }
.ipt-pd-star svg { display: block; }
.ipt-pd-star--on { fill: var(--ipt-blue-dark); }
.ipt-pd-star--off { fill: #cfdcea; }

/* ---- buy -------------------------------------------------------------- */
.ipt-pd-buy { background: var(--ipt-field); padding: 40px 24px 52px; }
.ipt-pd-buy__inner {
	max-width: 1140px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr) 400px;
	gap: 40px;
	align-items: start;
}
.ipt-pd-shot__cap { font-size: 13.5px; line-height: 1.6; color: var(--ipt-muted); margin: 14px 0 0; }

.ipt-pd-card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 26px 24px 24px;
}
.ipt-pd-price { display: flex; align-items: baseline; gap: 10px; margin: 0; flex-wrap: wrap; }
.ipt-pd-price b {
	font-family: 'Montserrat', sans-serif;
	font-size: 40px;
	font-weight: 800;
	line-height: 1;
	color: var(--ipt-blue-dark);
}
.ipt-pd-price span { font-size: 14px; color: var(--ipt-muted); }
.ipt-pd-lic { font-size: 14.5px; line-height: 1.5; color: var(--ipt-muted); margin: 12px 0 0; }

.ipt-pd-add { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--ipt-line); }

.ipt-pd-assure { list-style: none; margin: 18px 0 0; padding: 0; display: grid; row-gap: 9px; }
.ipt-pd-assure li {
	position: relative;
	padding-left: 24px;
	font-size: 14.5px;
	line-height: 1.5;
	color: var(--ipt-muted);
	margin: 0;
}
/* A tick carrying no text of its own, so --ipt-blue is allowed here. */
.ipt-pd-assure li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.36em;
	width: 13px;
	height: 8px;
	border-left: 2px solid var(--ipt-blue);
	border-bottom: 2px solid var(--ipt-blue);
	transform: rotate(-45deg);
}
.ipt-pd-assure a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-pd-assure a:hover { text-decoration: underline; }

.ipt-pd-free { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--ipt-line); }
.ipt-pd-free a {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-pd-free a:hover { text-decoration: underline; }
.ipt-pd-free span { display: block; font-size: 13.5px; color: var(--ipt-muted); margin-top: 4px; }

.ipt-pd-spec {
	margin: 18px 0 0;
	padding-top: 18px;
	border-top: 1px solid var(--ipt-line);
	display: grid;
	grid-template-columns: auto 1fr;
	row-gap: 7px;
	column-gap: 18px;
	font-size: 13.5px;
}
.ipt-pd-spec dt { color: var(--ipt-muted); margin: 0; }
.ipt-pd-spec dd { color: var(--ipt-ink); margin: 0; }

/* ---- the buttons ------------------------------------------------------
   White on --ipt-blue #2878ff measured 4.02:1. --ipt-red-fill is 5.06:1 and is
   already this site's buy action, which is exactly what this button is. */
/* `form.cart` is in the selector because Astra's woocommerce-grid.min.css carries
   `.woocommerce-js div.product form.cart .button { width: auto }` at (0,3,2) — it beat the
   plainer (0,3,0) rule and left a 138px button in a 312px card. */
.ipt-pdpage .ipt-pd-buy .ipt-pd-add form.cart .button.single_add_to_cart_button,
.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart .button.single_add_to_cart_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 54px;
	/* Astra's Woo grid gives this button `margin: 0 0 17px -17px` for its own inline layout —
	   the 17px was making the form 71px tall and knocking it off the ghost's baseline. */
	margin: 0;
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.3;
	border: 0;
	border-radius: 7px;
	padding: 15px 28px;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}
/* Deepen on hover, never dim — a lighter fill would drop the ratio. */
.ipt-pdpage .ipt-pd-buy .ipt-pd-add form.cart .button.single_add_to_cart_button { width: 100%; }
.ipt-pdpage .ipt-pd-buy .ipt-pd-add form.cart .button.single_add_to_cart_button:hover,
.ipt-pdpage .ipt-pd-buy .ipt-pd-add form.cart .button.single_add_to_cart_button:focus,
.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart .button.single_add_to_cart_button:hover,
.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart .button.single_add_to_cart_button:focus { background: #ad2f2f; color: #fff; }
.ipt-pdpage .ipt-pd-buy .ipt-pd-add form.cart .button.single_add_to_cart_button:focus-visible,
.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart .button.single_add_to_cart_button:focus-visible {
	outline: 3px solid var(--ipt-blue-link);
	outline-offset: 2px;
}
/* Sold individually, so Woo already renders the quantity input as type="hidden" — but its
   wrapper still takes 17px, which pushed the close-band button off the ghost’s baseline.
   The input keeps submitting its value of 1; display:none does not exclude it. */
.ipt-pdpage form.cart .quantity { display: none; }
.ipt-pdpage form.cart { margin: 0; display: block; }

.ipt-pd-ghost {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 54px;
	font-family: 'Montserrat', sans-serif;
	font-size: 17px;
	font-weight: 700;
	color: #fff;
	border: 2px solid rgba(255, 255, 255, 0.55);
	border-radius: 7px;
	padding: 0 26px;
	text-decoration: none;
}
.ipt-pd-ghost:hover { border-color: #fff; color: #fff; }

/* ---- capabilities ----------------------------------------------------- */
.ipt-pd-what { background: #fff; padding: 62px 24px; border-top: 1px solid var(--ipt-line); }
.ipt-pd-what__inner { max-width: 1140px; margin: 0 auto; }
.ipt-pd-what h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 32px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	text-align: center;
	margin: 0;
}
.ipt-pd-what__sub {
	font-size: 17px;
	line-height: 1.6;
	color: var(--ipt-muted);
	text-align: center;
	max-width: 720px;
	margin: 12px auto 0;
}
.ipt-pd-what__sub a { color: var(--ipt-blue-link); text-decoration: none; font-weight: 600; }
.ipt-pd-what__sub a:hover { text-decoration: underline; }

.ipt-pd-groups {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
	margin-top: 40px;
}
.ipt-pd-group {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px 22px 26px;
	height: 100%;
}
.ipt-pd-content .ipt-pd-group__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ipt-blue-dark);
	margin: 0 0 12px;
	padding-bottom: 12px;
	border-bottom: 1px solid var(--ipt-line);
}
.ipt-pd-group ul { list-style: none; margin: 0; padding: 0; }
.ipt-pd-group li {
	position: relative;
	padding-left: 22px;
	margin: 9px 0 0;
	font-size: 15px;
	line-height: 1.5;
	color: var(--ipt-ink);
}
.ipt-pd-group li:first-child { margin-top: 0; }
.ipt-pd-group li strong { font-weight: 600; color: var(--ipt-ink); }
.ipt-pd-group li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.42em;
	width: 12px;
	height: 7px;
	border-left: 2px solid var(--ipt-blue);
	border-bottom: 2px solid var(--ipt-blue);
	transform: rotate(-45deg);
}

/* ---- destinations ----------------------------------------------------- */
.ipt-pd-dest { background: var(--ipt-field); padding: 52px 24px; }
.ipt-pd-dest__inner { max-width: 1140px; margin: 0 auto; }
.ipt-pd-dest h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 28px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-pd-dest__sub { font-size: 16px; color: var(--ipt-muted); margin: 8px 0 0; }
.ipt-pd-tiles {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16px;
	margin-top: 26px;
}
.ipt-pd-tile {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 18px 16px;
}
.ipt-pd-tile h3 {
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin: 0;
}
.ipt-pd-tile p { font-size: 13.5px; line-height: 1.5; color: var(--ipt-muted); margin: 5px 0 0; }

/* ---- docs & support --------------------------------------------------- */
.ipt-pd-help { background: #fff; padding: 52px 24px; border-top: 1px solid var(--ipt-line); }
.ipt-pd-help__inner {
	max-width: 1140px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 32px;
	align-items: start;
}
.ipt-pd-help h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 20px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin: 0 0 14px;
}
.ipt-pd-help p { font-size: 15.5px; line-height: 1.7; color: #3d5771; margin: 0 0 12px; }
.ipt-pd-help a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-pd-help a:hover { text-decoration: underline; }
.ipt-pd-links { list-style: none; margin: 0; padding: 0; }
.ipt-pd-links li { margin: 0 0 12px; }
.ipt-pd-links a { display: block; font-size: 16px; font-weight: 600; }
.ipt-pd-links span { display: block; font-size: 13.5px; color: var(--ipt-muted); margin-top: 2px; }

/* ---- questions -------------------------------------------------------- */
.ipt-pd-qa { background: var(--ipt-field); padding: 52px 24px; }
.ipt-pd-qa__inner { max-width: 900px; margin: 0 auto; }
.ipt-pd-qa__head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.ipt-pd-qa h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 28px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-pd-qa__head p { font-size: 14px; color: var(--ipt-muted); margin: 0; }

.ipt-pd-qa__list { list-style: none; margin: 26px 0 0; padding: 0; }
.ipt-pd-q {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 18px 20px;
	margin: 0 0 12px;
}
.ipt-pd-q__by { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px; color: var(--ipt-muted); margin: 0 0 6px; }
.ipt-pd-q__by b { font-weight: 600; color: var(--ipt-ink); }
.ipt-pd-q__text p { font-size: 15.5px; line-height: 1.65; color: #3d5771; margin: 0 0 8px; }
.ipt-pd-q__text p:last-child { margin-bottom: 0; }
.ipt-pd-q__reply {
	margin: 14px 0 0;
	padding: 14px 0 0 16px;
	border-top: 1px solid var(--ipt-line);
	border-left: 3px solid var(--ipt-line-strong);
	padding-left: 16px;
}

.ipt-pd-qa__more {
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-dark);
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	padding: 11px 22px;
	cursor: pointer;
}
.ipt-pd-qa__more:hover { background: #eaf2fb; }
.ipt-pd-qa__note { font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); margin: 18px 0 0; }
.ipt-pd-qa__note a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-pd-qa__note a:hover { text-decoration: underline; }

/* ---- close ------------------------------------------------------------ */
.ipt-pd-close { background: var(--ipt-blue-dark); padding: 46px 24px 50px; }
.ipt-pd-close__inner { max-width: 1140px; margin: 0 auto; }
.ipt-pd-close h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 28px;
	font-weight: 700;
	color: #fff;
	margin: 0;
}
.ipt-pd-close p { font-size: 17px; line-height: 1.6; color: rgba(255, 255, 255, 0.86); margin: 10px 0 0; max-width: 720px; }
.ipt-pd-close__btns { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 24px; }

/* ===========================================================================
   WOOCOMMERCE CHROME, SITE-WIDE
   "Return to shop" was 1.37:1 — the anchor kept the theme link colour while
   .button inherited --ipt-blue as its background: blue text on blue fill. The
   fix must set background AND colour on one selector or it reopens.
   =========================================================================== */
.woocommerce .return-to-shop .button,
.woocommerce .wc-backward,
.woocommerce .button.wc-forward,
.woocommerce-page .return-to-shop .button,
.woocommerce-page .wc-backward {
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	color: var(--ipt-blue-dark);
	font-family: 'Montserrat', sans-serif;
	font-size: 16px;
	font-weight: 600;
	border-radius: 7px;
	padding: 13px 24px;
	text-decoration: none;
}
.woocommerce .return-to-shop .button:hover,
.woocommerce .wc-backward:hover,
.woocommerce .button.wc-forward:hover,
.woocommerce-page .return-to-shop .button:hover,
.woocommerce-page .wc-backward:hover { background: #eaf2fb; color: #093f6d; }


@media (max-width: 1099px) {
	.ipt-pd-buy__inner { grid-template-columns: minmax(0, 1fr) 340px; gap: 28px; }
	.ipt-pd-groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ipt-pd-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 921px) {
	.ipt-pd-title { font-size: 34px; }
	.ipt-pd-stand { font-size: 18px; }
	/* The price must not fall below the mockup on a narrow screen. */
	.ipt-pd-buy__inner { grid-template-columns: minmax(0, 1fr); }
	.ipt-pd-shot { order: 2; }
	.ipt-pd-card { order: 1; }
	.ipt-pd-help__inner { grid-template-columns: minmax(0, 1fr); gap: 26px; }
}
@media (max-width: 600px) {
	.ipt-pd-head { padding: 26px 20px 30px; }
	.ipt-pd-title { font-size: 28px; }
	.ipt-pd-stand { font-size: 17px; }
	.ipt-pd-buy { padding: 26px 20px 36px; }
	.ipt-pd-what,
	.ipt-pd-dest,
	.ipt-pd-help,
	.ipt-pd-qa { padding: 38px 20px; }
	.ipt-pd-close { padding: 34px 20px 38px; }
	.ipt-pd-what h2 { font-size: 25px; }
	.ipt-pd-dest h2,
	.ipt-pd-qa h2,
	.ipt-pd-close h2 { font-size: 23px; }
	.ipt-pd-groups { grid-template-columns: minmax(0, 1fr); gap: 16px; }
	.ipt-pd-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
	.ipt-pd-card { padding: 20px 18px; }
	.ipt-pd-price b { font-size: 34px; }
	/* 42px at the desktop padding — under the 44px touch-target floor. */
	.ipt-pdpage .ipt-pd-buy .ipt-pd-add form.cart .button.single_add_to_cart_button,
	.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart .button.single_add_to_cart_button,
	.ipt-pdpage .ipt-pd-ghost { min-height: 48px; padding-top: 13px; padding-bottom: 13px; }
	.ipt-pd-close__btns { flex-direction: column; align-items: stretch; }
	.ipt-pd-ghost { text-align: center; }
	.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart,
	.ipt-pdpage .ipt-pd-close .ipt-pd-close__btns form.cart .button.single_add_to_cart_button { width: 100%; }
}

/* ---- the plugin logo, in the head band --------------------------------
   On a white plate rather than straight onto #0c5490: the wordmark and the
   globe's landmasses are the same dark navy as the band and vanish on it. */
.ipt-pd-head__cols {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 380px;
	gap: 40px;
	align-items: center;
	margin-top: 18px;
}
.ipt-pd-head__cols > div:first-child > .ipt-pd-eyebrow { margin-top: 0; }
.ipt-pd-mark {
	background: #fff;
	border-radius: 12px;
	padding: 18px 22px;
	box-shadow: 0 18px 44px rgba(4, 32, 64, 0.24);
}
.ipt-pd-mark__img { display: block; width: 100%; height: auto; }

/* ---- leave a review --------------------------------------------------- */
.ipt-pd-form {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px 24px 26px;
	margin-top: 22px;
}
.ipt-pd-form__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 20px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin: 0;
}
.ipt-pd-form__note { font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); margin: 8px 0 18px; }
.ipt-pd-form__gate { font-size: 15px; color: var(--ipt-muted); margin: 0; }
.ipt-pd-form__row { margin: 0 0 16px; }
.ipt-pd-form label {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin-bottom: 6px;
}
.ipt-pd-form .required { color: var(--ipt-red-ink); }
.ipt-pd-form input[type="text"],
.ipt-pd-form input[type="email"],
.ipt-pd-form select,
.ipt-pd-form textarea {
	width: 100%;
	max-width: 420px;
	font-family: inherit;
	font-size: 16px;
	color: var(--ipt-ink);
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	padding: 11px 14px;
	box-shadow: none;
}
.ipt-pd-form textarea { max-width: 100%; line-height: 1.6; }
.ipt-pd-form input:focus,
.ipt-pd-form select:focus,
.ipt-pd-form textarea:focus {
	outline: none;
	border-color: var(--ipt-blue);
	box-shadow: 0 0 0 3px rgba(40, 120, 255, 0.18);
}
.ipt-pd-form .comment-form-cookies-consent { display: flex; align-items: flex-start; gap: 9px; margin: 0 0 16px; }
.ipt-pd-form .comment-form-cookies-consent input { width: auto; margin-top: 3px; }
.ipt-pd-form .comment-form-cookies-consent label { font-weight: 400; font-family: inherit; font-size: 14.5px; color: var(--ipt-muted); margin: 0; }
.ipt-pd-form .form-submit { margin: 0; }
/* Astra's inline CSS reaches this with `.woocommerce #respond input#submit` — TWO ids, (2,1,1).
   No number of classes beats two ids, so both have to appear here as well. */
.ipt-pdpage .ipt-pd-form #respond .form-submit input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 50px;
	width: auto;
	margin: 0;
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 16px;
	font-weight: 700;
	border: 0;
	border-radius: 7px;
	padding: 0 28px;
	cursor: pointer;
}
.ipt-pdpage .ipt-pd-form #respond .form-submit input#submit:hover,
.ipt-pdpage .ipt-pd-form #respond .form-submit input#submit:focus { background: #ad2f2f; color: #fff; }

@media (max-width: 921px) {
	.ipt-pd-head__cols { grid-template-columns: minmax(0, 1fr); gap: 24px; }
	.ipt-pd-mark { max-width: 400px; }
}

/* WooCommerce replaces the rating <select> with this widget on load. */
.ipt-pd-form .stars { margin: 0; }
.ipt-pd-form .stars a { font-size: 20px; color: var(--ipt-blue-dark); text-decoration: none; }
.ipt-pd-form .stars a:hover,
.ipt-pd-form .stars a:focus { color: var(--ipt-blue-dark); }
.ipt-pd-form .comment-form-rating > label { margin-bottom: 6px; }


/* ===========================================================================
   CART
   The header chip, the in-cart state on the product page, and the cart page.
   =========================================================================== */

/* ---- the header chip -------------------------------------------------- */
.ipt-nav-cart { display: flex; align-items: center; }
.ipt-cart-chip {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	background: var(--ipt-blue-dark);
	color: #fff;
	border-radius: 99px;
	padding: 11px 20px;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 700;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
}
/* Astra colours menu links from its own palette; this one is a button. */
.main-header-menu .ipt-nav-cart > .ipt-cart-chip,
.main-header-menu .ipt-nav-cart > .ipt-cart-chip:hover,
.main-header-menu .ipt-nav-cart > .ipt-cart-chip:focus { color: #fff; }
.ipt-cart-chip:hover { background: #093f6d; }
.ipt-cart-chip__n {
	background: #fff;
	color: var(--ipt-blue-dark);
	border-radius: 99px;
	min-width: 20px;
	height: 20px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 12.5px;
	font-weight: 700;
	padding: 0 6px;
}

/* ---- the product page, once it is in the cart ------------------------- */
.ipt-pd-incart {
	display: flex;
	align-items: center;
	gap: 9px;
	font-family: 'Montserrat', sans-serif;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	/* Green says STATE — this one is "done" — which is what the colour rule allows. */
	color: #1c7a4a;
	margin: 0 0 12px;
}
.ipt-pd-incart svg { flex: none; }
.ipt-pd-checkout {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 54px;
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 17px;
	font-weight: 700;
	border-radius: 7px;
	text-decoration: none;
}
.ipt-pd-checkout:hover,
.ipt-pd-checkout:focus { background: #ad2f2f; color: #fff; }
.ipt-pd-incart__links { display: flex; align-items: center; gap: 16px; margin: 12px 0 0; font-size: 14.5px; }
.ipt-pd-incart__links a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-pd-incart__links a:hover { text-decoration: underline; }
.ipt-pd-incart__rm { color: var(--ipt-muted); }
.ipt-pd-incart__rm:hover { color: var(--ipt-red-ink); }

/* ---- the cart page ---------------------------------------------------- */
.ipt-cartpage .site-content > .ast-container { max-width: none; padding: 0; }
.ipt-cartpage #primary { margin: 0; padding: 0; width: 100%; max-width: none; }
.ipt-cartpage .ast-container > #primary { margin-top: 0; }
.ipt-cartpage .entry-content > * { margin-left: 0; margin-right: 0; }

.ipt-cart-head { background: var(--ipt-blue-dark); padding: 32px 24px 34px; }
.ipt-cart-head__inner { max-width: 1140px; margin: 0 auto; }
.ipt-cart-crumbs { font-size: 14px; color: rgba(255, 255, 255, 0.72); margin: 0; }
/* The cart renders inside .entry-content, so this stylesheet's own (0,2,2) link rule
   reached the breadcrumb and painted it #1a63d8 on the blue band — 1.42:1. */
.ipt-cartpage .ipt-cart-head .ipt-cart-crumbs a { color: rgba(255, 255, 255, 0.9); text-decoration: none; }
.ipt-cartpage .ipt-cart-head .ipt-cart-crumbs a:hover { color: #fff; text-decoration: underline; }
.ipt-cart-crumbs__sep { color: rgba(255, 255, 255, 0.7); margin: 0 6px; }
.ipt-cart-head h1 {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px;
	font-weight: 800;
	color: #fff;
	margin: 12px 0 0;
}

/* 1188, not 1140: the padding is inside the box, so a 1140 cap put the cards' content
   at 174 while the head band's breadcrumb and H1 sit at 150. The body was 24px right of
   its own heading — visible the moment a notice, which aligns to the band, appeared. */
.ipt-cart__inner {
	max-width: 1188px;
	margin: 0 auto;
	padding: 34px 24px 56px;
	display: grid;
	grid-template-columns: minmax(0, 1fr) 360px;
	gap: 32px;
	align-items: start;
}

.ipt-cart-item {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 22px 24px;
	display: grid;
	grid-template-columns: 88px minmax(0, 1fr) auto;
	gap: 20px;
	align-items: start;
	margin-bottom: 14px;
}
.ipt-cart-item__thumb {
	width: 88px;
	height: 88px;
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	overflow: hidden;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #fff;
}
.ipt-cart-item__thumb img { width: 100%; height: auto; display: block; }
.ipt-cart-item__name {
	font-family: 'Montserrat', sans-serif;
	font-size: 19px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ipt-ink);
	margin: 0;
}
/* Beats this stylesheet's own `body:not(.ast-page-builder-template) .entry-content a`, (0,2,2). */
.ipt-cartpage .ipt-cart-item .ipt-cart-item__name a { color: var(--ipt-ink); text-decoration: none; }
.ipt-cartpage .ipt-cart-item .ipt-cart-item__name a:hover { color: var(--ipt-blue-dark); }
/* .entry-content ul adds its own left margin; this list is not prose. */
.ipt-cartpage .ipt-cart-item .ipt-cart-item__terms { list-style: none; margin: 10px 0 0; padding: 0; display: grid; row-gap: 5px; }
.ipt-cart-item__terms li {
	position: relative;
	padding-left: 20px;
	font-size: 14.5px;
	line-height: 1.5;
	color: var(--ipt-muted);
}
.ipt-cart-item__terms li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.42em;
	width: 11px;
	height: 6px;
	border-left: 2px solid var(--ipt-blue);
	border-bottom: 2px solid var(--ipt-blue);
	transform: rotate(-45deg);
}
.ipt-cart-item__side { text-align: right; }
.ipt-cart-item__price {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 22px;
	font-weight: 700;
	color: var(--ipt-ink);
	white-space: nowrap;
}
.ipt-cart-item__rm { display: inline-block; margin-top: 8px; font-size: 14px; color: var(--ipt-muted); text-decoration: none; }
.ipt-cart-item__rm:hover { color: var(--ipt-red-ink); text-decoration: underline; }

.ipt-cart-coupon {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 18px 24px;
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
}
.ipt-cart-coupon label {
	font-family: 'Montserrat', sans-serif;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin: 0;
}
.ipt-cartpage .ipt-cart-coupon input#coupon_code {
	flex: 1;
	min-width: 170px;
	width: auto;
	background: var(--ipt-field);
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	padding: 11px 14px;
	font-size: 15px;
	color: var(--ipt-ink);
	box-shadow: none;
	margin: 0;
}
.ipt-cartpage .ipt-cart-coupon input#coupon_code::placeholder { color: var(--ipt-muted); opacity: 1; }
.ipt-cartpage .ipt-cart-coupon button {
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-dark);
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	padding: 11px 20px;
	margin: 0;
	min-height: 44px;
	cursor: pointer;
}
.ipt-cartpage .ipt-cart-coupon button:hover { background: #eaf2fb; color: #093f6d; }
/* Nothing to update on a fixed-quantity cart until something changes. */
/* Quieter than Apply, but still readable: #7d95ad measured 3.1:1. */
.ipt-cartpage .ipt-cart-coupon button[name="update_cart"],
.ipt-cartpage .ipt-cart-coupon button[name="update_cart"][disabled] {
	color: var(--ipt-muted);
	border-color: var(--ipt-line);
	opacity: 1;
}

.ipt-cart-back {
	display: inline-block;
	margin-top: 18px;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-cart-back:hover { text-decoration: underline; }

.ipt-cart-sum {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px;
}
.ipt-cart-sum__k {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin: 0 0 16px;
}
.ipt-cart-sum__row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.ipt-cart-sum__row span { font-size: 15px; color: var(--ipt-ink); }
/* Woo shrinks the currency symbol to `smaller`; every part of the figure is one size here. */
.ipt-cart-sum__row b,
.ipt-cart-sum__row b *,
.ipt-cart-sum__row b .amount,
.ipt-cart-sum__row b .woocommerce-Price-amount {
	font-family: 'Montserrat', sans-serif;
	font-size: 32px;
	font-weight: 800;
	line-height: 1.1;
	color: var(--ipt-blue-dark);
}
.ipt-cart-sum__line { display: flex; justify-content: space-between; gap: 16px; font-size: 14.5px; color: var(--ipt-muted); margin-top: 10px; }
.ipt-cart-sum__vat { font-size: 13.5px; line-height: 1.55; color: var(--ipt-muted); margin: 8px 0 0; }

.ipt-cart-sum__go { margin-top: 20px; }
.ipt-cartpage .ipt-cart-sum__go .checkout-button {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 54px;
	margin: 0;
	padding: 0 24px;
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 17px;
	font-weight: 700;
	border: 0;
	border-radius: 7px;
	text-decoration: none;
}
.ipt-cartpage .ipt-cart-sum__go .checkout-button:hover,
.ipt-cartpage .ipt-cart-sum__go .checkout-button:focus { background: #ad2f2f; color: #fff; }

.ipt-cart-sum__assure { list-style: none; margin: 18px 0 0; padding: 0; display: grid; row-gap: 8px; }
.ipt-cart-sum__assure li {
	position: relative;
	padding-left: 22px;
	font-size: 14px;
	line-height: 1.5;
	color: var(--ipt-muted);
}
.ipt-cart-sum__assure li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.4em;
	width: 11px;
	height: 6px;
	border-left: 2px solid var(--ipt-blue);
	border-bottom: 2px solid var(--ipt-blue);
	transform: rotate(-45deg);
}
.ipt-cart-sum__assure a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-cart-sum__assure a:hover { text-decoration: underline; }

/* ---- empty ------------------------------------------------------------ */
.ipt-cart__empty {
	max-width: 1188px;
	margin: 0 auto;
	padding: 34px 24px 56px;
}
/* This stylesheet's own `body:not(.ast-page-builder-template) .entry-content h2|p` is (0,2,2)
   and left-aligns everything rendered inside the content wrapper — the panel class is here to
   clear it. Same rule already caught the breadcrumb, the item name and the empty-state buttons. */
.ipt-cartpage .ipt-cart__empty,
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-panel h2,
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-panel p { text-align: center; }
.ipt-cart__empty-panel {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 52px 24px 44px;
}
.ipt-cart__empty > svg,
.ipt-cart__empty-panel > svg { color: var(--ipt-muted); opacity: 0.35; }
.ipt-cart__empty h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px;
	font-weight: 600;
	color: var(--ipt-ink);
	margin: 16px 0 6px;
}
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-panel p { margin: 0 auto; max-width: 460px; font-size: 15.5px; line-height: 1.65; color: var(--ipt-muted); }
.ipt-cart__empty-acts { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 22px; }
.ipt-cart__empty-primary,
.ipt-cart__empty-ghost {
	/*
	 * Block, not inline-flex. The primary label is bare text followed by an inline price span —
	 * "Iptanus File Upload Pro — <span>€40.00</span>" — and in a flex box those become two items:
	 * the space between them was stripped at desktop ("Pro —€40.00") and at 390 the label wrapped
	 * to two lines with the price parked beside it. As one line of centred text it just wraps.
	 */
	display: block;
	text-align: center;
	min-height: 50px;
	padding: 13px 26px;
	font-family: 'Montserrat', sans-serif;
	font-size: 16px;
	font-weight: 700;
	border-radius: 7px;
	text-decoration: none;
}
/* Above this stylesheet's own `body:not(...) .entry-content a`, (0,2,2). */
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-primary { background: var(--ipt-red-fill); color: #fff; }
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-primary:hover { background: #ad2f2f; color: #fff; }
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-ghost { background: #fff; border: 1px solid var(--ipt-line-strong); color: var(--ipt-blue-dark); font-weight: 600; }
.ipt-cartpage .ipt-cart__empty .ipt-cart__empty-ghost:hover { background: #eaf2fb; color: #093f6d; }

/* Woo's own empty-cart notice would repeat what the panel above already says. */
.ipt-cartpage .cart-empty.woocommerce-info,
.ipt-cartpage .return-to-shop { display: none; }

@media (max-width: 921px) {
	.ipt-cart__inner { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}
@media (max-width: 600px) {
	.ipt-cart-head { padding: 26px 20px 30px; }
	.ipt-cart-head h1 { font-size: 27px; }
	.ipt-cart__inner { padding: 26px 20px 40px; }
	.ipt-cart-item { grid-template-columns: 64px minmax(0, 1fr); gap: 14px; padding: 18px; }
	.ipt-cart-item__thumb { width: 64px; height: 64px; }
	.ipt-cart-item__side { grid-column: 1 / -1; text-align: left; display: flex; align-items: baseline; gap: 16px; }
	.ipt-cart-item__rm { margin-top: 0; }
	.ipt-cart-coupon { padding: 16px 18px; }
	.ipt-cart__empty { padding: 40px 20px 36px; }
	.ipt-cart__empty-acts { flex-direction: column; align-items: stretch; }
}

/* ===========================================================================
   THE PRODUCT ARCHIVE  /products/
   A list, not a grid. One row reads as a deliberate catalogue entry; one cell
   of a four-column grid reads as a broken grid, and the catalogue has exactly
   one public product. The same row takes the extensions later in a compact
   variant, so nothing here has to be redesigned when they ship.
   =========================================================================== */

/* Astra caps the shop's .ast-container at 1240px with 20px of padding, which boxed the
   full-bleed bands 120px in from each edge. The constraint is dropped here and the centring is
   done by each band's own __inner, exactly as on the cart and checkout. Not `100vw` margins:
   those include the scrollbar and would have added a horizontal scroll of their own. */
/* .site-content, NOT every .ast-container: the header uses the same class, and dropping its
   padding put the logo hard against the viewport edge. */
.ipt-shoppage .site-content .ast-container { max-width: 100%; padding-left: 0; padding-right: 0; }
/* Astra's `#primary { margin: 4em 0 }` is an ID selector, so the class rule that was here first
   never applied. It printed a 64px pale strip between the header and the band, and another below
   the closing strip. The band and the strip are the page's own top and bottom edges. */
.ipt-shoppage #primary { margin: 0; padding: 0; }
.ipt-shoppage .ast-woocommerce-container { padding-top: 0; margin-top: 0; }
/* the closing strip IS the page's bottom edge; the footer's own 56px gap doubled it */
.ipt-shoppage .site-footer { margin-top: 0; }

/* ---- band ------------------------------------------------------------- */
.ipt-shop-head { background: var(--ipt-blue-dark); padding: 32px 24px 36px; }
.ipt-shop-head__inner { max-width: 1140px; margin: 0 auto; }

.ipt-shop-crumbs { font-size: 14px; color: rgba(255, 255, 255, 0.72); margin: 0; }
.ipt-shoppage .ipt-shop-crumbs a { color: rgba(255, 255, 255, 0.9); text-decoration: none; }
.ipt-shoppage .ipt-shop-crumbs a:hover { color: #fff; text-decoration: underline; }
/* 0.7, not 0.4: blended against the band that measured 2.57:1 */
.ipt-shop-crumbs__sep { color: rgba(255, 255, 255, 0.7); margin: 0 6px; }

.ipt-shoppage .ipt-shop-eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.72);
	margin: 14px 0 6px;
}
.ipt-shoppage .ipt-shop-title {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	margin: 0;
}
.ipt-shoppage .ipt-shop-sub {
	font-size: 17px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.88);
	max-width: 620px;
	margin: 10px 0 0;
}

/* ---- catalogue -------------------------------------------------------- */
.ipt-shop__inner { max-width: 1188px; margin: 0 auto; padding: 44px 24px 8px; }

.ipt-shop-group { display: flex; align-items: center; gap: 12px; margin: 0 0 16px; }
.ipt-shop-group + .ipt-shop-row { margin-top: 0; }
.ipt-shop-row + .ipt-shop-group { margin-top: 38px; }
.ipt-shoppage .ipt-shop-group__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 22px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin: 0;
}
/* neutral: the pill labels a TYPE, and colour on this site means state */
.ipt-shop-pill {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 99px;
	padding: 4px 12px;
	font-size: 13px;
	font-weight: 600;
	color: var(--ipt-muted);
}

.ipt-shop-row {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 12px;
	padding: 22px 26px;
	display: grid;
	grid-template-columns: 96px minmax(0, 1fr) 264px;
	gap: 26px;
	align-items: center;
}
.ipt-shop-row + .ipt-shop-row { margin-top: 14px; }

.ipt-shop-row__logo { display: flex; align-items: center; justify-content: center; width: 96px; }
.ipt-shop-row__logo img { width: 96px; height: auto; display: block; border: 0; border-radius: 0; }

.ipt-shop-badge {
	display: inline-block;
	background: var(--ipt-blue-dark);
	color: #fff;
	border-radius: 5px;
	padding: 3px 9px;
	font-family: 'Montserrat', sans-serif;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}
.ipt-shop-badge--neutral {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line-strong);
	color: var(--ipt-muted);
}

.ipt-shoppage .ipt-shop-row__t {
	font-family: 'Montserrat', sans-serif;
	font-size: 21px;
	font-weight: 700;
	line-height: 1.25;
	margin: 9px 0 0;
}
.ipt-shoppage .ipt-shop-row__t a { color: var(--ipt-blue-dark); text-decoration: none; }
.ipt-shoppage .ipt-shop-row__t a:hover { color: #093f6d; text-decoration: underline; }

.ipt-shoppage .ipt-shop-row__d {
	font-size: 15.5px;
	line-height: 1.55;
	color: var(--ipt-muted);
	margin: 7px 0 0;
	max-width: 56ch;
}
.ipt-shoppage .ipt-shop-row__r {
	display: flex;
	align-items: center;
	gap: 9px;
	flex-wrap: wrap;
	margin: 11px 0 0;
	font-size: 14.5px;
	color: var(--ipt-muted);
}

.ipt-shop-row__side { text-align: right; }
.ipt-shoppage .ipt-shop-row__p {
	font-family: 'Montserrat', sans-serif;
	font-size: 28px;
	font-weight: 800;
	line-height: 1;
	color: var(--ipt-ink);
	margin: 0;
}
.ipt-shoppage .ipt-shop-row__p .woocommerce-Price-amount { font: inherit; color: inherit; }
.ipt-shoppage .ipt-shop-row__terms { font-size: 14px; color: var(--ipt-muted); margin: 5px 0 0; }

/* --ipt-blue-dark, not --ipt-red-fill: this goes to the product page, it does not buy anything */
.ipt-shoppage .ipt-shop-row__go {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 46px;
	margin-top: 15px;
	padding: 0 18px;
	background: var(--ipt-blue-dark);
	border-radius: 7px;
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
}
.ipt-shoppage .ipt-shop-row__go:hover { background: #093f6d; color: #fff; }
.ipt-shoppage .ipt-shop-row__go:focus-visible { outline: 3px solid var(--ipt-blue-dark); outline-offset: 2px; }

.ipt-shoppage .ipt-shop-row__free {
	display: inline-block;
	margin-top: 10px;
	font-family: 'Montserrat', sans-serif;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ipt-blue-link);
	text-decoration: none;
}
.ipt-shoppage .ipt-shop-row__free:hover { text-decoration: underline; }

/* ---- compact variant --------------------------------------------------- */
.ipt-shop-row--sm {
	grid-template-columns: 56px minmax(0, 1fr) 200px;
	padding: 16px 26px;
	align-items: center;
}
.ipt-shop-row--sm .ipt-shop-row__logo {
	width: 56px;
	height: 56px;
	border: 1px solid var(--ipt-line);
	border-radius: 9px;
	background: var(--ipt-surface);
	overflow: hidden;
}
.ipt-shop-row--sm .ipt-shop-row__logo img { width: 56px; }
.ipt-shoppage .ipt-shop-row--sm .ipt-shop-row__t { font-size: 17px; margin: 6px 0 0; }
.ipt-shoppage .ipt-shop-row--sm .ipt-shop-row__d { font-size: 14.5px; margin: 4px 0 0; }
.ipt-shoppage .ipt-shop-row--sm .ipt-shop-row__p { font-size: 21px; }
.ipt-shoppage .ipt-shop-row--sm .ipt-shop-row__go { min-height: 40px; margin-top: 10px; font-size: 14px; }

/* ---- free version ------------------------------------------------------ */
.ipt-shop-free {
	background: #fff;
	border-top: 1px solid var(--ipt-line);
	border-bottom: 1px solid var(--ipt-line);
	margin-top: 44px;
	padding: 38px 24px;
}
.ipt-shop-free__inner { max-width: 1140px; margin: 0 auto; }
.ipt-shoppage .ipt-shop-free h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 24px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-shoppage .ipt-shop-free p {
	font-size: 16.5px;
	line-height: 1.6;
	color: var(--ipt-muted);
	max-width: 68ch;
	margin: 10px 0 0;
}
.ipt-shoppage .ipt-shop-free__acts {
	display: flex;
	flex-wrap: wrap;
	gap: 22px;
	margin: 16px 0 0;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
}
.ipt-shoppage .ipt-shop-free__acts a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-shoppage .ipt-shop-free__acts a:hover { text-decoration: underline; }

/* ---- closing line ------------------------------------------------------ */
.ipt-shoppage .ipt-shop-close {
	background: var(--ipt-surface);
	margin: 0;
	padding: 20px 24px;
	text-align: center;
	font-size: 15px;
	line-height: 1.55;
	color: var(--ipt-muted);
}
.ipt-shoppage .ipt-shop-close a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-shoppage .ipt-shop-close a:hover { text-decoration: underline; }

/* ---- empty state ------------------------------------------------------- */
.ipt-shop-empty { background: #fff; border: 1px solid var(--ipt-line); border-radius: 12px; padding: 34px 26px; }
.ipt-shoppage .ipt-shop-empty h2 { font-family: 'Montserrat', sans-serif; font-size: 22px; font-weight: 700; color: var(--ipt-blue-dark); margin: 0; }
.ipt-shoppage .ipt-shop-empty p { font-size: 16px; line-height: 1.6; color: var(--ipt-muted); margin: 10px 0 0; max-width: 60ch; }

/* Woo's ordering control, back once the catalogue is worth sorting */
.ipt-shoppage .woocommerce-ordering { margin: 0 0 20px; }
.ipt-shoppage .woocommerce-ordering select {
	min-height: 42px;
	padding: 0 12px;
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	font-size: 15px;
	color: var(--ipt-ink);
}

@media (max-width: 921px) {
	.ipt-shop-row { grid-template-columns: 72px minmax(0, 1fr) 220px; gap: 20px; padding: 20px; }
	.ipt-shop-row__logo, .ipt-shop-row__logo img { width: 72px; }
	.ipt-shop-row--sm { grid-template-columns: 56px minmax(0, 1fr) 180px; }
}

@media (max-width: 600px) {
	.ipt-shop-head { padding: 22px 20px 26px; }
	.ipt-shoppage .ipt-shop-title { font-size: 27px; }
	.ipt-shoppage .ipt-shop-sub { font-size: 15.5px; }
	.ipt-shop__inner { padding: 26px 20px 0; }
	.ipt-shop-free { padding: 28px 20px; margin-top: 28px; }
	.ipt-shop-close { padding: 18px 20px; text-align: left; }

	/*
	 * One column. The mark sits beside the badge on its own row rather than above the heading,
	 * so the name, the description and the price all start at the same left edge — three
	 * different left edges inside one card is the fault this avoids.
	 */
	.ipt-shop-row,
	.ipt-shop-row--sm {
		grid-template-columns: minmax(0, 1fr);
		gap: 0;
		padding: 18px 18px 20px;
	}
	.ipt-shop-row__logo,
	.ipt-shop-row--sm .ipt-shop-row__logo { width: 56px; height: 56px; justify-content: flex-start; }
	.ipt-shop-row__logo img,
	.ipt-shop-row--sm .ipt-shop-row__logo img { width: 56px; }
	.ipt-shop-row__main { margin-top: 12px; }
	.ipt-shoppage .ipt-shop-row__t { font-size: 19px; }
	.ipt-shop-row__side { text-align: left; margin-top: 16px; }
	.ipt-shoppage .ipt-shop-row__p { font-size: 26px; }
	.ipt-shoppage .ipt-shop-row__go,
	.ipt-shoppage .ipt-shop-row--sm .ipt-shop-row__go { min-height: 48px; margin-top: 14px; font-size: 15.5px; }
	.ipt-shoppage .ipt-shop-free__acts { flex-direction: column; gap: 9px; }
}

/* IPT-NOTICE-START */
/* ===========================================================================
   WOOCOMMERCE NOTICES
   A receipt for a click, not a section of the page. The box is cut to the
   sentence: it starts at the content column's left edge and ends where the
   sentence and its action end. Before this it was a 1140px slab holding 389px
   of text with 569px of empty tint between the words and the button.

   Two markup shapes, one set of rules: success and info are
   <div class="woocommerce-message|-info">text <a class="button">…</a></div>,
   the error is <ul class="woocommerce-error"><li>text <a class="button">…</a></li></ul>.
   The icon goes on the outer element in both cases, so the only extra rule the
   <ul> needs is a flex row on its <li>.

   State is carried by a small filled disc and a coloured outline, not by a
   large pale field — the old tint measured 1.06:1 against the body and read as
   neither status nor message.
   =========================================================================== */

/* The wrapper is the alignment rail, never the box. `align-items: flex-start`
   is what shrinks both markup shapes to their content. */
.woocommerce-notices-wrapper {
	max-width: 1188px;
	margin: 0 auto;
	padding: 0 24px;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
}
.woocommerce-notices-wrapper:not(:empty) { padding-top: 24px; padding-bottom: 24px; }

/*
 * Not every notice gets the wrapper. WC_Shortcode_Checkout::order_pay() prints
 * "This order's status is X — it cannot be paid for" with a bare wc_print_notice(), so the box
 * lands as a direct child of .woocommerce and stretched the full 1440px of the page. These
 * carry the rail themselves. Same measure as the wrapper's inner width, so the two agree.
 */
/* `body` is load-bearing: this block sits ABOVE the box rule that sets `margin: 0`, and at equal
   specificity the later rule would win. One element selector settles it. */
body :is(.woocommerce, .woocommerce-page, .woocommerce-js) > :is(.woocommerce-message, .woocommerce-info, .woocommerce-error),
body .entry-content > :is(.woocommerce-message, .woocommerce-info, .woocommerce-error) {
	max-width: min(1140px, calc(100% - 48px));
	margin: 24px auto;
}

.woocommerce .woocommerce-message,
.woocommerce .woocommerce-info,
.woocommerce .woocommerce-error,
.woocommerce-page .woocommerce-message,
.woocommerce-page .woocommerce-info,
.woocommerce-page .woocommerce-error,
.woocommerce-js .woocommerce-message,
.woocommerce-js .woocommerce-info,
.woocommerce-js .woocommerce-error {
	/*
	 * Normal flow, with the disc taken out of it. Neither flex nor grid works here, because
	 * Woo emits TWO shapes and one of them puts bare text around an inline link:
	 *   <div class="woocommerce-error">…review your <a>order history</a> before…</div>
	 * In a flex or grid container each of those text nodes becomes its own anonymous item, so
	 * the sentence broke into blocks and the <a> was dealt into the 20px icon track — one
	 * character per line. flow-root also contains the floated action below.
	 */
	display: flow-root;
	position: relative;
	/* Full content width. Shrink-to-content was rejected first — the same component in the
	   same slot measured 341px, 518px and 567px across removed / added / error, and a width
	   that tracks sentence length reads as a theme that never set one. Spanning the column
	   puts both edges on the same verticals as the cards and the bands. */
	width: 100%;
	flex: 0 0 auto;
	margin: 0;
	/* left padding = 12 gutter + 20 disc + 10 gap */
	padding: 8px 14px 8px 42px;
	border: 1px solid var(--ipt-blue-dark);
	border-left-width: 3px;
	border-radius: 8px;
	background: #e8f1fb;
	color: var(--ipt-ink);
	list-style: none;
	font: 400 15px/1.45 'Source Sans 3', 'Source Sans Pro', sans-serif;
	box-shadow: none;
	/* Woo calls .focus() on this; keep it clear of the header when it scrolls to. */
	scroll-margin-top: 96px;
}

/* The other shape is <ul class="woocommerce-error"><li>…</li><li>…</li></ul> — a failed
   submit can report several fields at once. Plain blocks, so they stack. */
.woocommerce .woocommerce-error li,
.woocommerce-page .woocommerce-error li,
.woocommerce-js .woocommerce-error li,
.woocommerce .woocommerce-message li,
.woocommerce .woocommerce-info li {
	display: block;
	margin: 0 0 4px;
	padding: 0;
	list-style: none;
}
.woocommerce .woocommerce-error li:last-child,
.woocommerce-page .woocommerce-error li:last-child,
.woocommerce-js .woocommerce-error li:last-child,
.woocommerce .woocommerce-message li:last-child,
.woocommerce .woocommerce-info li:last-child { margin-bottom: 0; }

/* The state disc: 20px, filled, white glyph. `font-family: inherit` kills Woo's
   own icon-font character. */
.woocommerce .woocommerce-message::before,
.woocommerce .woocommerce-info::before,
.woocommerce .woocommerce-error::before,
.woocommerce-page .woocommerce-message::before,
.woocommerce-page .woocommerce-info::before,
.woocommerce-page .woocommerce-error::before,
.woocommerce-js .woocommerce-message::before,
.woocommerce-js .woocommerce-info::before,
.woocommerce-js .woocommerce-error::before {
	content: "";
	/* absolute so it never becomes a flex/grid item beside the sentence; `top` rather than a
	   centring transform so it sits on the FIRST line when the message wraps */
	position: absolute;
	left: 12px;
	top: 9px;
	width: 20px;
	height: 20px;
	margin: 0;
	padding: 0;
	font-family: inherit;
	background-repeat: no-repeat;
	background-position: center;
	background-size: 20px 20px;
}

/* --- the three states ---------------------------------------------------
   Fills are 1.02-1.06:1 against the body on purpose: the tint is atmosphere,
   the border and the disc carry the signal and both clear 3:1. */
.woocommerce .woocommerce-message,
.woocommerce-page .woocommerce-message,
.woocommerce-js .woocommerce-message { background: #e9f5ee; border-color: #1c7a4a; }
.woocommerce .woocommerce-message::before,
.woocommerce-page .woocommerce-message::before,
.woocommerce-js .woocommerce-message::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%231c7a4a'/%3E%3Cpath d='m7.2 12.4 3.1 3.1 6.4-6.6' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.woocommerce .woocommerce-info,
.woocommerce-page .woocommerce-info,
.woocommerce-js .woocommerce-info { background: #e8f1fb; border-color: var(--ipt-blue-dark); }
.woocommerce .woocommerce-info::before,
.woocommerce-page .woocommerce-info::before,
.woocommerce-js .woocommerce-info::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%230c5490'/%3E%3Cpath d='M12 10.6v6.2' stroke='%23fff' stroke-width='2.4' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='6.9' r='1.5' fill='%23fff'/%3E%3C/svg%3E");
}

/* #9c2f2f, not --ipt-red-fill: that hex is the buy button, and a failure must
   not read as a call to action. */
.woocommerce .woocommerce-error,
.woocommerce-page .woocommerce-error,
.woocommerce-js .woocommerce-error { background: #fbeaea; border-color: #9c2f2f; }
.woocommerce .woocommerce-error::before,
.woocommerce-page .woocommerce-error::before,
.woocommerce-js .woocommerce-error::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%239c2f2f'/%3E%3Cpath d='M12 6.2v6.6' stroke='%23fff' stroke-width='2.4' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='17.2' r='1.5' fill='%23fff'/%3E%3C/svg%3E");
}

/* --- the action ---------------------------------------------------------
   A compact control, not a page CTA. #5c85ad, not #6e93b8: that measured
   2.87:1 against the tinted fill it sits on.

   Three class names, because WooCommerce does not use one. "View cart" is
   `a.button`, but the expired-session notice writes
     Sorry, your session has expired. <a href="%s" class="wc-backward">Return to shop</a>
   (class-wc-checkout.php:1278) with no `button` at all, so it missed every rule here and
   came out at full body size in a plain link box. `wc-forward` is the same story going
   the other way. */
.woocommerce .woocommerce-message :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce .woocommerce-info :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce .woocommerce-error :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce-page .woocommerce-message :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce-page .woocommerce-info :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce-page .woocommerce-error :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce-js .woocommerce-message :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce-js .woocommerce-info :is(a.button, a.wc-backward, a.wc-forward),
.woocommerce-js .woocommerce-error :is(a.button, a.wc-backward, a.wc-forward) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/*
	 * Floated, not `margin-left: auto` — that only reached the far edge while the box was a
	 * flex row, and the box cannot be one (see the note on .woocommerce-error above). The
	 * float takes it to the right edge of the first line and the sentence wraps around it.
	 * Blockification by float is wanted here; the ≤600 rule clears it so the action can
	 * rejoin the sentence on a narrow screen.
	 */
	float: right;
	margin: 0 0 4px 14px;
	min-height: 30px;
	padding: 5px 12px;
	background: #fff;
	border: 1px solid #5c85ad;
	border-radius: 6px;
	color: var(--ipt-blue-dark);
	font: 600 13.5px/1.3 'Montserrat', sans-serif;
	text-decoration: none;
	white-space: nowrap;
}
.woocommerce .woocommerce-message :is(a.button, a.wc-backward, a.wc-forward):hover,
.woocommerce .woocommerce-info :is(a.button, a.wc-backward, a.wc-forward):hover,
.woocommerce .woocommerce-error :is(a.button, a.wc-backward, a.wc-forward):hover,
.woocommerce-js .woocommerce-message :is(a.button, a.wc-backward, a.wc-forward):hover,
.woocommerce-js .woocommerce-info :is(a.button, a.wc-backward, a.wc-forward):hover,
.woocommerce-js .woocommerce-error :is(a.button, a.wc-backward, a.wc-forward):hover {
	background: var(--ipt-surface);
	border-color: var(--ipt-blue-dark);
	color: #093f6d;
}

.woocommerce .woocommerce-message a:not(.button):not(.wc-backward):not(.wc-forward),
.woocommerce .woocommerce-info a:not(.button):not(.wc-backward):not(.wc-forward),
.woocommerce .woocommerce-error a:not(.button):not(.wc-backward):not(.wc-forward),
.woocommerce-js .woocommerce-message a:not(.button):not(.wc-backward):not(.wc-forward),
.woocommerce-js .woocommerce-info a:not(.button):not(.wc-backward):not(.wc-forward),
.woocommerce-js .woocommerce-error a:not(.button):not(.wc-backward):not(.wc-forward) {
	color: var(--ipt-blue-link);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Woo focuses the notice so screen readers announce it (tabindex="-1"), and the
   browser rings the whole box. It is not keyboard-reachable and has nothing to
   activate, so no ring on either state; the button inside keeps its own. */
.woocommerce-message:focus,
.woocommerce-info:focus,
.woocommerce-error:focus,
.woocommerce-message:focus-visible,
.woocommerce-info:focus-visible,
.woocommerce-error:focus-visible { outline: none; box-shadow: none; }

/* On the product page the band below the notice supplies its own edge, so 24px above and
   24px below the box are what the reader sees. The cart has no such band: .ipt-cart__inner
   adds its own 34px on top of the wrapper's 24, giving 24 above and 58 below. Measured, not
   guessed. When a notice is present the cart body's top padding is the notice's bottom
   padding, so it is dropped. */
.woocommerce-notices-wrapper:not(:empty) + .ipt-cart .ipt-cart__inner,
.woocommerce-notices-wrapper:not(:empty) + .ipt-cart .ipt-cart__empty { padding-top: 0; }

@media (max-width: 921px) {
	.woocommerce-notices-wrapper { max-width: 100%; padding: 0 24px; }
}
@media (max-width: 600px) {
	/* 20px, matching .ipt-pd-head / .ipt-cart-head at this width; 16 put the box 4px
	   left of the breadcrumb above it. */
	.woocommerce-notices-wrapper { padding: 0 20px; }
	.woocommerce-notices-wrapper:not(:empty) { padding-top: 20px; padding-bottom: 20px; }
	body :is(.woocommerce, .woocommerce-page, .woocommerce-js) > :is(.woocommerce-message, .woocommerce-info, .woocommerce-error),
	body .entry-content > :is(.woocommerce-message, .woocommerce-info, .woocommerce-error) {
		max-width: calc(100% - 40px);
		margin: 20px auto;
	}
	.woocommerce .woocommerce-message,
	.woocommerce .woocommerce-info,
	.woocommerce .woocommerce-error,
	.woocommerce-js .woocommerce-message,
	.woocommerce-js .woocommerce-info,
	.woocommerce-js .woocommerce-error {
		/* block, not flex: a flex item is blockified, so an <a> could never rejoin the
		   sentence. The icon comes out of the flow and the padding holds its column. */
		display: block;
		position: relative;
		width: 100%;
		max-width: 100%;
		padding: 8px 12px 8px 38px;
		font-size: 14.5px;
	}
	.woocommerce .woocommerce-message::before,
	.woocommerce .woocommerce-info::before,
	.woocommerce .woocommerce-error::before,
	.woocommerce-js .woocommerce-message::before,
	.woocommerce-js .woocommerce-info::before,
	.woocommerce-js .woocommerce-error::before {
		position: absolute;
		left: 10px;
		top: 9px;
	}
	.woocommerce .woocommerce-error li,
	.woocommerce-js .woocommerce-error li { display: block; }
	/* The action rejoins the sentence rather than claiming a row: a full-width
	   slab here reads as the page's primary CTA, and the sticky "Cart 1" chip
	   at the top of the viewport already offers the same destination. */
	/* Both error shapes: the validation error is <ul><li>, the payment and expired-session
	   errors are a <div>. Only the <ul> was listed here, so a <div> error kept the desktop
	   button at 390. The tag qualifier stays — it is what outweighs the desktop rule. */
	.woocommerce div.woocommerce-message :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce div.woocommerce-info :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce div.woocommerce-error :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce ul.woocommerce-error li :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce-js div.woocommerce-message :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce-js div.woocommerce-info :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce-js div.woocommerce-error :is(a.button, a.wc-backward, a.wc-forward),
	.woocommerce-js ul.woocommerce-error li :is(a.button, a.wc-backward, a.wc-forward) {
		display: inline;
		float: none;
		min-height: 0;
		margin: 0 0 0 2px;
		padding: 3px 4px;
		background: none;
		border: 0;
		border-radius: 0;
		color: var(--ipt-blue-link);
		font: 400 14.5px/1.45 'Source Sans 3', 'Source Sans Pro', sans-serif;
		text-decoration: underline;
		text-underline-offset: 2px;
		white-space: normal;
	}
}
/* IPT-NOTICE-END */

/* ===========================================================================
   CHECKOUT, ORDER-PAY, ORDER RECEIVED
   The last three screens of the purchase path. All three used to carry the same
   H1 — "Checkout" — and the primary action on each was #2878ff: 4.02:1 on
   checkout, and 1.37:1 on the thank-you download button, which is the most
   important control on the site.
   =========================================================================== */

.ipt-copage .site-content > .ast-container { max-width: none; padding: 0; }
.ipt-copage #primary { margin: 0; padding: 0; width: 100%; max-width: none; }
.ipt-copage .ast-container > #primary { margin-top: 0; }
.ipt-copage .entry-content > * { margin-left: 0; margin-right: 0; }

/* ---- the band, shared by all three ------------------------------------ */
.ipt-co-head,
.ipt-ty-head { background: var(--ipt-blue-dark); padding: 32px 24px 34px; }
.ipt-ty-head { padding: 40px 24px 42px; }
.ipt-co-head__inner { max-width: 1140px; margin: 0 auto; }
/* The badge used to be a first grid column, which pushed the H1 to x=213 while every card
   below it started at x=150. It sits above the text instead, so the whole page shares one
   left edge. */
.ipt-ty-head__inner {
	max-width: 1140px;
	margin: 0 auto;
}

.ipt-co-crumbs { font-size: 14px; color: rgba(255, 255, 255, 0.72); margin: 0; }
.ipt-copage .ipt-co-head .ipt-co-crumbs a { color: rgba(255, 255, 255, 0.9); text-decoration: none; }
.ipt-copage .ipt-co-head .ipt-co-crumbs a:hover { color: #fff; text-decoration: underline; }
.ipt-co-crumbs__sep { color: rgba(255, 255, 255, 0.7); margin: 0 6px; }

.ipt-co-eyebrow,
.ipt-ty-eyebrow {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.72);
	margin: 0 0 6px;
}
.ipt-copage .ipt-co-title,
.ipt-copage .ipt-ty-head h1 {
	font-family: 'Montserrat', sans-serif;
	font-size: 34px;
	font-weight: 800;
	line-height: 1.15;
	color: #fff;
	margin: 8px 0 0;
	max-width: 820px;
}
.ipt-copage .ipt-ty-head h1 { margin: 0; }
.ipt-co-sub,
.ipt-ty-sub {
	font-size: 17px;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.88);
	max-width: 620px;
	margin: 10px 0 0;
}

/* White, not green: #1c7a4a on #0c5490 measures 1.63:1 and disappears. */
.ipt-ty-badge {
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: #fff;
	color: var(--ipt-blue-dark);
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0 0 16px;
}

/* ---- checkout body ---------------------------------------------------- */
.ipt-co__inner {
	max-width: 1188px;
	margin: 0 auto;
	padding: 34px 24px 56px;
	display: grid;
	grid-template-columns: minmax(0, 1fr) 360px;
	gap: 32px;
	align-items: start;
}
/* the pay variant has no form, so the summary card IS the page and fills the column */
.ipt-co__inner--pay { grid-template-columns: minmax(0, 1fr); }
.ipt-co-paycols {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 340px;
	gap: 0 40px;
	align-items: start;
}
/* the divider is the column edge; a card this wide needs the two halves told apart */
.ipt-co-paycols__b {
	padding-left: 40px;
	border-left: 1px solid var(--ipt-line);
}
.ipt-co-sum__row--first { margin-top: 0; }

/* the order-pay dead ends: one card, actions in a row that wraps */
.ipt-copage .ipt-co-deadend {
	/* the facts read as a pair of columns, not a pair of columns 500px apart */
	max-width: 680px;
}
/* no thumbnail on these lines, so the 48px art column would squeeze the name to one word a line */
.ipt-copage .ipt-co-line--bare { grid-template-columns: minmax(0, 1fr) auto; }
/* the facts list brings its own top rule, so the last item line would draw a second one 20px above it */
.ipt-copage .ipt-co-deadend .ipt-co-review .ipt-co-line:last-child { border-bottom: 0; padding-bottom: 0; }
.ipt-copage .ipt-co-deadend__acts {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
	margin: 22px 0 0;
}
/* three classes: `.ipt-copage .ipt-co-go` sets width:100% and is declared later in this file */
.ipt-copage .ipt-co-deadend__acts .ipt-co-go--inline {
	display: inline-flex;
	width: auto;
	min-height: 44px;
	padding: 0 22px;
	font-size: 15px;
}

/* order facts on the pay page: two per row at width, one per row when the card stacks */
.ipt-co-facts {
	margin: 20px 0 0;
	padding: 18px 0 0;
	border-top: 1px solid var(--ipt-line);
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 14px 32px;
}
.ipt-copage .ipt-co-facts dt {
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin: 0 0 4px;
}
/* the note read as part of the Status cell when it sat 8px under the badge */
.ipt-copage .ipt-co-facts + .ipt-co-vat { margin-top: 20px; }
.ipt-copage .ipt-co-facts dd {
	margin: 0;
	font-size: 15px;
	line-height: 1.4;
	color: var(--ipt-ink);
	word-break: break-word;
}

.ipt-copage .checkout { display: contents; }

/*
 * A failed submit makes WooCommerce inject .woocommerce-NoticeGroup-checkout as the form's first
 * child. Because the form is display:contents that div becomes grid item ONE: it took column one,
 * pushed "Your details" into the 360px summary column and dropped the order panel to row two.
 * It spans the row instead, above both.
 */
.ipt-copage .woocommerce-NoticeGroup {
	grid-column: 1 / -1;
	order: -1;
}

.ipt-co-card {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px 26px 26px;
}
.ipt-co-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.ipt-copage .ipt-co-card__head h2 {
	font-family: 'Montserrat', sans-serif;
	font-size: 18px;
	font-weight: 700;
	color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-copage .ipt-co-login-toggle { font-size: 14.5px; color: var(--ipt-blue-link); text-decoration: none; }
.ipt-copage .ipt-co-login-toggle:hover { text-decoration: underline; }
.ipt-copage .ipt-co-lede { font-size: 14.5px; line-height: 1.6; color: var(--ipt-muted); margin: 8px 0 18px; }

/* the account line: a benefit, not a chore — there is no password to invent */
.ipt-copage .ipt-co-acct {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	padding: 14px 16px;
	margin: 20px 0 0;
	font-size: 14.5px;
	line-height: 1.55;
	color: var(--ipt-muted);
}

/* ---- the fields ------------------------------------------------------- */
.ipt-copage .ipt-co-fields h3 { display: none; } /* "Billing details" — the card is already titled */
.ipt-copage .woocommerce-billing-fields__field-wrapper { display: grid; gap: 0; }
/* `.woocommerce form .form-row { padding: 3px }` is (0,2,2) and beat the single class, so
   every label sat 3px right of the card heading above it. */
.ipt-copage.woocommerce-page form .form-row,
.ipt-copage .form-row { margin: 0 0 18px; padding: 0; width: auto; float: none; }
.ipt-copage .form-row-first,
.ipt-copage .form-row-last { width: 100%; }
.ipt-copage .ipt-co-fields { display: block; }
/* name fields two-up */
.ipt-copage #billing_first_name_field,
.ipt-copage #billing_last_name_field { display: inline-block; width: calc(50% - 9px); vertical-align: top; }
.ipt-copage #billing_first_name_field { margin-right: 18px; }

.ipt-copage .form-row label {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 13.5px;
	font-weight: 700;
	color: var(--ipt-ink);
	margin: 0 0 7px;
}
.ipt-copage .form-row label .optional { font-family: 'Source Sans 3', sans-serif; font-size: 13px; font-weight: 400; color: var(--ipt-muted); }
/* only Company is optional, so one mark beats four asterisks */
.ipt-copage .form-row label .required { display: none; }

.ipt-copage .form-row input[type="text"],
.ipt-copage .form-row input[type="email"],
.ipt-copage .form-row input[type="tel"],
.ipt-copage .form-row input[type="password"],
.ipt-copage .form-row select,
.ipt-copage .form-row .select2-selection {
	width: 100%;
	height: 44px;
	/* white, NOT --ipt-field: that token is the same hex as the page background, so a
	   --ipt-field input on a white card looks like a hole punched through it */
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
	padding: 0 13px;
	font-family: 'Source Sans 3', sans-serif;
	font-size: 15px;
	color: var(--ipt-ink);
	box-shadow: none;
}
.ipt-copage .form-row select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 38px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 7' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2356718c' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 12px 7px;
}
.ipt-copage .form-row input:focus,
.ipt-copage .form-row select:focus {
	border-color: var(--ipt-blue-dark);
	outline: 2px solid var(--ipt-blue-dark);
	outline-offset: 1px;
	box-shadow: none;
}
/*
 * Field validation colours.
 *
 * woocommerce-grid.min.css lands these at
 *   `.woocommerce-js form .form-row.woocommerce-validated input.input-text` — (0,4,2),
 * painting every validated field #69bf29 and every invalid one #d65d67. Neither is in this
 * palette, and the green turned a correctly filled form into a wall of green outlines that
 * says nothing: only a problem should be marked, a field that is simply right looks like a
 * field. The earlier one-class override here never applied — it was (0,2,1) against (0,4,2).
 * Matching their shape and adding the page class takes it to (0,5,2).
 */
.ipt-copage.woocommerce-js form .form-row.woocommerce-invalid input.input-text,
.ipt-copage.woocommerce-js form .form-row.woocommerce-invalid select,
.ipt-copage.woocommerce-js form .form-row.woocommerce-invalid .select2-container { border-color: #9c2f2f; }

.ipt-copage.woocommerce-js form .form-row.woocommerce-validated input.input-text,
.ipt-copage.woocommerce-js form .form-row.woocommerce-validated select,
.ipt-copage.woocommerce-js form .form-row.woocommerce-validated .select2-container { border-color: var(--ipt-line-strong); }

/* select2 renders its own control over the native select; match the 44px field rather
   than fight the dependency chain. */
.ipt-copage .select2-container--default .select2-selection--single {
	height: 44px;
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 7px;
}
.ipt-copage .select2-container--default .select2-selection--single .select2-selection__rendered {
	line-height: 42px;
	padding-left: 13px;
	font-family: 'Source Sans 3', sans-serif;
	font-size: 15px;
	color: var(--ipt-ink);
}
.ipt-copage .select2-container--default .select2-selection--single .select2-selection__arrow { height: 42px; right: 8px; }
.ipt-copage .select2-container--default.select2-container--open .select2-selection--single { border-color: var(--ipt-blue-dark); }
/* the native select is only a fallback once select2 has painted over it */
.ipt-copage .select2-hidden-accessible { position: absolute !important; width: 1px !important; height: 1px !important; overflow: hidden !important; clip: rect(0 0 0 0) !important; }

/* ---- summary card ----------------------------------------------------- */
.ipt-co-sum {
	background: #fff;
	border: 1px solid var(--ipt-line);
	border-radius: 10px;
	padding: 24px;
}
.ipt-copage .ipt-co-sum__k {
	font-family: 'Montserrat', sans-serif;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--ipt-muted);
	margin: 0 0 16px;
}

.ipt-co-line {
	display: grid;
	grid-template-columns: 48px minmax(0, 1fr) auto;
	gap: 14px;
	align-items: center;
	padding-bottom: 16px;
	border-bottom: 1px solid var(--ipt-line);
}
.ipt-co-line__thumb { width: 48px; height: 48px; border: 1px solid var(--ipt-line); border-radius: 8px; overflow: hidden; }
.ipt-co-line__thumb img { width: 100%; height: auto; display: block; }
.ipt-co-line__t {
	display: block;
	font-family: 'Montserrat', sans-serif;
	font-size: 15.5px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--ipt-ink);
}
.ipt-co-line__q { font-weight: 400; color: var(--ipt-muted); }
.ipt-co-line__terms { display: block; font-size: 14px; line-height: 1.5; color: var(--ipt-muted); margin-top: 4px; }
.ipt-co-line__p { font-family: 'Montserrat', sans-serif; font-size: 15.5px; font-weight: 700; color: var(--ipt-ink); white-space: nowrap; }

.ipt-co-sum__line { display: flex; justify-content: space-between; gap: 16px; font-size: 14.5px; color: var(--ipt-muted); margin-top: 12px; }
.ipt-co-sum__row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 16px; }
.ipt-co-sum__row span { font-size: 15px; color: var(--ipt-ink); }
.ipt-co-sum__row b,
.ipt-co-sum__row b * {
	font-family: 'Montserrat', sans-serif;
	font-size: 32px;
	font-weight: 800;
	line-height: 1.1;
	color: var(--ipt-blue-dark);
}
.ipt-copage .ipt-co-vat { font-size: 13.5px; line-height: 1.55; color: var(--ipt-muted); margin: 8px 0 0; }

/* Astra's inline CSS reaches this twice over:
     `.woocommerce.woocommerce-checkout form #order_review { width:40%; float:right }` — (1,2,1),
     which inside a 360px card left 124px and wrapped the product name one character per line; and
     `form #order_review:not(.elementor-widget-woocommerce-checkout-page #order_review)
        { border-width: 0 2px 2px; border-style: solid; padding: 0 2em }`
   whose :not() argument carries an id, so that selector counts TWO ids — (2,1,1) — and beat the
   one-id override that used to sit here. It drew a grey box inside the card and inset the
   contents 32px. The id is repeated below to match the count; the alternative was !important. */
.ipt-copage form #order_review#order_review,
.ipt-copage form .ipt-co-sum .woocommerce-checkout-review-order {
	float: none;
	width: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
}

/* ---- coupon ----------------------------------------------------------- */
.ipt-co-coupon { margin-top: 18px; }
.ipt-copage .ipt-co-coupon__toggle { font-size: 14.5px; color: var(--ipt-blue-link); text-decoration: none; }
.ipt-copage .ipt-co-coupon__toggle:hover { text-decoration: underline; }
.ipt-co-coupon__body { margin-top: 12px; }
.ipt-copage .ipt-co-coupon__body .form-row { margin-bottom: 10px; }
.ipt-copage .ipt-co-coupon__body input[type="text"] { background: var(--ipt-field); }
.ipt-copage .ipt-co-coupon__body button {
	min-height: 44px;
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	color: var(--ipt-blue-dark);
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	padding: 0 20px;
	cursor: pointer;
}

/* ---- payment ---------------------------------------------------------- */
.ipt-co-pay { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--ipt-line); }
.ipt-copage .payment_methods { list-style: none; margin: 0; padding: 0; }
.ipt-copage .payment_methods > li { margin: 0 0 10px; padding: 0; background: none; }
.ipt-copage .payment_methods > li > label {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 44px;
	padding: 0 14px;
	background: #fff;
	border: 1px solid var(--ipt-line-strong);
	border-radius: 8px;
	font-family: 'Montserrat', sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--ipt-ink);
	cursor: pointer;
}
.ipt-copage .payment_methods > li > input[type="radio"] { accent-color: var(--ipt-blue-dark); margin: 0 0 0 14px; }
/* a radio with one option is a control that cannot be operated */
.ipt-copage .ipt-co-pay--single > li > input[type="radio"] { display: none; }
.ipt-copage .payment_box {
	background: var(--ipt-surface);
	border: 1px solid var(--ipt-line);
	border-radius: 8px;
	padding: 14px 16px;
	margin: 10px 0 0;
	font-size: 14.5px;
	line-height: 1.6;
	color: var(--ipt-muted);
}
.ipt-copage .payment_box::before { display: none; } /* Woo's CSS arrow */

/* ---- consent ---------------------------------------------------------- */
.ipt-copage .woocommerce-privacy-policy-text p { font-size: 13.5px; line-height: 1.6; color: var(--ipt-muted); margin: 18px 0 0; }
.ipt-copage .woocommerce-terms-and-conditions-wrapper { margin-top: 14px; }
.ipt-copage .validate-required.woocommerce-validated label,
.ipt-copage .woocommerce-terms-and-conditions-checkbox-text { font-family: 'Source Sans 3', sans-serif; font-weight: 400; font-size: 14.5px; line-height: 1.5; color: var(--ipt-ink); }
.ipt-copage .form-row.validate-required > label.checkbox { display: flex; align-items: flex-start; gap: 10px; min-height: 44px; margin: 0; }
.ipt-copage input#terms { width: 24px; height: 24px; min-width: 24px; accent-color: var(--ipt-blue-dark); margin: 0; }
.ipt-copage .woocommerce-terms-and-conditions-checkbox-text .required { display: none; }

/* ---- the action ------------------------------------------------------- */
.ipt-copage .ipt-co-go,
.ipt-copage #place_order {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 54px;
	margin: 20px 0 0;
	padding: 0 24px;
	float: none;
	background: var(--ipt-red-fill);
	color: #fff;
	font-family: 'Montserrat', sans-serif;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.2;
	border: 0;
	border-radius: 7px;
	cursor: pointer;
}
.ipt-copage .ipt-co-go:hover,
.ipt-copage #place_order:hover,
.ipt-copage .ipt-co-go:focus,
.ipt-copage #place_order:focus { background: #ad2f2f; color: #fff; }
.ipt-copage .ipt-co-go:focus-visible,
.ipt-copage #place_order:focus-visible { outline: 3px solid var(--ipt-blue-dark); outline-offset: 2px; }

/* Astra still puts 20px of padding on a bare ul; one class is not enough to take it back */
.ipt-copage .ipt-co-assure { list-style: none; margin: 18px 0 0; padding: 0; display: grid; row-gap: 8px; }
.ipt-copage .ipt-co-assure li {
	position: relative;
	padding-left: 22px;
	font-size: 14px;
	line-height: 1.5;
	color: var(--ipt-muted);
	margin: 0;
}
.ipt-copage .ipt-co-assure li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.4em;
	width: 11px;
	height: 6px;
	border-left: 2px solid var(--ipt-blue);
	border-bottom: 2px solid var(--ipt-blue);
	transform: rotate(-45deg);
}
.ipt-copage .ipt-co-assure a { color: var(--ipt-blue-link); text-decoration: none; }
.ipt-copage .ipt-co-assure a:hover { text-decoration: underline; }

/* the mini price line, only when the summary is not beside the form */
.ipt-co-mini { display: none; }
/* a grid item with no `order` sits at 0 — below 921px that floated this above the card,
   because the summary and form both carry an explicit order */
.ipt-copage .ipt-co-help { order: 3; font-size: 14.5px; color: var(--ipt-muted); margin: 18px 0 0; }
.ipt-copage .ipt-co-help a { color: var(--ipt-blue-link); text-decoration: none; }

.ipt-co-login { grid-column: 1 / -1; }
.ipt-copage .ipt-co-login .woocommerce-form-login { background: #fff; border: 1px solid var(--ipt-line); border-radius: 10px; padding: 24px 26px; margin: 0; }

/* ---- order received --------------------------------------------------- */
.ipt-ty-stack { max-width: 1188px; margin: 0 auto; padding: 34px 24px 56px; }
.ipt-ty-stack > * { max-width: 840px; }
.ipt-ty-stack .ipt-acc-card + .ipt-acc-card { margin-top: 18px; }
.ipt-copage .ipt-acc-facts__list { padding: 0 26px 16px; }
.ipt-copage .ipt-acc-item { padding-left: 26px; padding-right: 26px; }
.ipt-copage .ipt-acc-totals { padding-left: 26px; padding-right: 26px; }

@media (max-width: 921px) {
	.ipt-co__inner { grid-template-columns: minmax(0, 1fr); gap: 24px; }
	.ipt-co__inner--pay { grid-template-columns: minmax(0, 1fr); }
	.ipt-co-paycols { grid-template-columns: minmax(0, 1fr); }
	.ipt-co-paycols__b {
		padding-left: 0;
		border-left: 0;
		border-top: 1px solid var(--ipt-line);
		margin-top: 22px;
		padding-top: 22px;
	}
	/* the summary confirms what was just filled in, so it follows the form */
	.ipt-co-sum { order: 2; }
	.ipt-co-card { order: 1; }
	.ipt-co-mini {
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 16px;
		grid-column: 1 / -1;
		order: 0;
		background: #fff;
		border: 1px solid var(--ipt-line);
		border-radius: 10px;
		padding: 16px 20px;
		font-size: 15px;
		color: var(--ipt-ink);
	}
	.ipt-co-mini b,
	.ipt-co-mini b * { font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: 700; color: var(--ipt-blue-dark); }
}
@media (max-width: 600px) {
	.ipt-co-facts { grid-template-columns: minmax(0, 1fr); gap: 14px; }
	.ipt-co-head,
	.ipt-ty-head { padding: 26px 20px 30px; }
	.ipt-copage .ipt-co-title,
	.ipt-copage .ipt-ty-head h1 { font-size: 27px; }
	.ipt-co-sub,
	.ipt-ty-sub { font-size: 15.5px; }
	.ipt-ty-badge { width: 36px; height: 36px; margin-bottom: 12px; }
	.ipt-co__inner,
	.ipt-ty-stack { padding: 26px 20px 44px; }
	.ipt-co-card { padding: 20px 18px; }
	.ipt-co-sum { padding: 20px 18px; }
	/* 159px will not hold "Konstantinos" */
	.ipt-copage #billing_first_name_field,
	.ipt-copage #billing_last_name_field { display: block; width: 100%; margin-right: 0; }
	/* 16px is a floor: below it iOS zooms the viewport on focus. The type selectors are
	   repeated because the desktop rule uses them and would otherwise out-specify this. */
	.ipt-copage .form-row input[type="text"],
	.ipt-copage .form-row input[type="email"],
	.ipt-copage .form-row input[type="tel"],
	.ipt-copage .form-row input[type="password"],
	.ipt-copage .form-row select,
	.ipt-copage .select2-container--default .select2-selection--single .select2-selection__rendered { font-size: 16px; }
	.ipt-co-line { grid-template-columns: 40px minmax(0, 1fr) auto; gap: 12px; }
	.ipt-co-line__thumb { width: 40px; height: 40px; }
}

/* The account cards are reused on the order-received page, which renders inside
   .entry-content — so this stylesheet's own (0,2,2) link rule repainted the button
   labels. Measured on the download button: #1a63d8 on #c93a3a = 1.09:1. */
.ipt-copage .ipt-acc-card a.ipt-acc-btn,
.ipt-copage .ipt-acc-blank a.ipt-acc-btn { color: #fff; text-decoration: none; }
.ipt-copage .ipt-acc-card a.ipt-acc-btn:hover,
.ipt-copage .ipt-acc-blank a.ipt-acc-btn:hover { color: #fff; }
.ipt-copage .ipt-acc-card a.ipt-acc-btn2 { color: var(--ipt-blue-dark); text-decoration: none; }
.ipt-copage .ipt-acc-card a.ipt-acc-btn2:hover { color: #093f6d; }

/* ==========================================================================
   Order licences
   --------------------------------------------------------------------------
   The Integrator plugin renders the licences on the single-order page. It
   emits markup and class names only; every rule that decides how any of it
   looks lives here.

   Two class families sit on the same elements deliberately:
     .wipi-*     behaviour. wipi_functions.js selects on about thirty of these
                 to copy keys, save notes, validate binding keys and drive the
                 loading states. They are hooks, never styled — renaming one
                 breaks the script.
     .ipt-lic-*  appearance. Only these carry rules.

   Built on the account area's own values: the card is .ipt-acc-card, the row
   labels are the uppercase Montserrat of .ipt-acc-fact-item__k, and a licence
   panel is the third and last step of the surface ladder
   (field #f0f5fa -> card #fff -> inset --ipt-surface). Colour states the
   licence's condition and nothing else.
   ========================================================================== */

.ipt-lic { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; }

/* ---- a type-category group, e.g. "WFU Plugin" ---------------------------- */
/* Disclosure is a checkbox and its label, so it opens with no JavaScript. The
   input is taken out of flow rather than display:none, which would drop it
   from the tab order. */
.ipt-lic-group { border: 1px solid var(--ipt-line); border-radius: 10px; overflow: hidden; }
.ipt-lic-group__toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
.ipt-lic-group__head {
	display: flex; align-items: center; gap: 10px; cursor: pointer;
	padding: 13px 16px; background: var(--ipt-surface);
	font-family: 'Montserrat', sans-serif;
	font-size: 13.5px; font-weight: 700; color: var(--ipt-blue-dark);
	margin: 0;
}
.ipt-lic-group__toggle:focus-visible + .ipt-lic-group__head { outline: 2px solid var(--ipt-blue); outline-offset: -2px; }
.ipt-lic-group__chev { display: flex; color: var(--ipt-muted); transition: transform 0.15s ease; }
.ipt-lic-group__toggle:checked + .ipt-lic-group__head .ipt-lic-group__chev { transform: rotate(90deg); }
.ipt-lic-group__count { margin-left: auto; font-family: 'Source Sans Pro', sans-serif; font-size: 12.5px; font-weight: 400; color: var(--ipt-muted); }
.ipt-lic-group__body { display: none; padding: 14px 16px 16px; flex-direction: column; gap: 14px; }
.ipt-lic-group__toggle:checked ~ .ipt-lic-group__body { display: flex; }

/* One order item's licences. The group's gap falls between these wrappers, so the wrapper
   spaces the licences inside it — several seats of the same extension were flush otherwise. */
.ipt-lic-item, .ipt-lic-item__list { display: flex; flex-direction: column; gap: 14px; }

/* ---- one licence --------------------------------------------------------- */
.ipt-lic-piece { background: var(--ipt-surface); border: 1px solid var(--ipt-line); border-radius: 8px; padding: 16px 18px; }
.ipt-lic-piece__toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
/* No bottom margin on the header. A shut licence is header-only, and 12px of dead space
   under it made every shut box tall enough that the 12px BETWEEN boxes read as nothing.
   The space belongs to the body, which only exists when the licence is open. */
.ipt-acc-ui .entry-content .ipt-lic-piece__head,
.ipt-lic-piece__head {
	display: flex; align-items: center; gap: 8px; cursor: pointer; margin: 0;
	font-family: 'Montserrat', sans-serif; font-size: 13px; font-weight: 700; color: var(--ipt-ink);
}
.ipt-lic-piece__chev { display: flex; color: var(--ipt-muted); transition: transform 0.15s ease; }
.ipt-lic-piece__toggle:checked + .ipt-lic-piece__head .ipt-lic-piece__chev { transform: rotate(90deg); }
.ipt-lic-piece__body { display: none; flex-direction: column; gap: 12px; padding-top: 14px; }
.ipt-lic-piece__toggle:checked ~ .ipt-lic-piece__body { display: flex; }
/* The only licence in a group has no header, so it needs no space above its body either. */
.ipt-lic-piece--only > .ipt-lic-piece__body { padding-top: 0; }
/* A group holding a single licence is always open and needs no header.
   The .ipt-acc-ui .entry-content prefix is carried here too: without it this rule is (0,2,0)
   against the base rule's (0,3,0) and the header stayed visible. */
.ipt-acc-ui .entry-content .ipt-lic-piece--only > .ipt-lic-piece__head,
.ipt-lic-piece--only > .ipt-lic-piece__head { display: none; }
.ipt-lic-piece--only > .ipt-lic-piece__body { display: flex; }

/* ---- what a shut licence says about itself ------------------------------- */
/* Shut, the header is the whole licence, so it carries the product name and one
   mark. Two seats of the same extension share a product name, so the ordinal
   stays and the name sits beside it — dropping the ordinal would leave two rows
   reading identically. */
.ipt-lic-piece__ord { flex: none; }
.ipt-acc-ui .entry-content .ipt-lic-piece__name,
.ipt-lic-piece__name {
	font-family: 'Source Sans Pro', sans-serif; font-size: 13px; font-weight: 400;
	color: var(--ipt-muted); margin: 0;
	/* The name is the only part that gives way. It truncates rather than wrapping:
	   a wrapped name would double the height of every shut row on a phone. */
	min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.ipt-lic-mark { display: flex; margin-left: auto; flex: none; }
.ipt-lic-mark svg { flex: none; }
.ipt-lic-mark--ok       { color: #2f7d4f; }
.ipt-lic-mark--expired  { color: var(--ipt-red-ink); }
/* Inactive is a state, not a fault — the shape says something is wrong, the
   colour does not shout about it. Same reasoning as the Inactive status pill. */
.ipt-lic-mark--inactive { color: var(--ipt-muted); }
.ipt-lic-mark--warn     { color: #8a5a00; }

/* Open, the licence states all of this in full a few rows down, so the mark
   steps aside rather than saying it twice. The name stays: it is the row's
   identity, and losing it under the cursor that just clicked would be the
   header changing as a reward for opening it. */
.ipt-lic-piece__toggle:checked + .ipt-lic-piece__head .ipt-lic-mark { display: none; }

/* The row itself carries the state while it is shut. :has() is what scopes this
   to the shut state — the tint is on the box, and the box is the toggle's
   PARENT, so no sibling selector can reach it. Where :has() is unsupported the
   rule simply does not apply and the mark carries the state alone. */
.ipt-lic-piece--expired:has(> .ipt-lic-piece__toggle:not(:checked)) {
	background: #fdeeee; border-color: #eab8b8;
}
.ipt-lic-piece--warn:has(> .ipt-lic-piece__toggle:not(:checked)) {
	background: #fff6e8; border-color: #e8c99a;
}
/* --inactive and --ok are deliberately absent: neither is a fault to flag. */

/* ---- rows ---------------------------------------------------------------- */
.ipt-lic-row { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 6px 14px; align-items: start; }
.ipt-lic-row--stack { grid-template-columns: minmax(0, 1fr); }
.ipt-acc-ui .entry-content .ipt-lic-label,
.ipt-lic-label {
	font-family: 'Montserrat', sans-serif;
	font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ipt-muted); padding-top: 3px; margin: 0;
}
.ipt-acc-ui .entry-content .ipt-lic-value,
.ipt-lic-value { font-size: 14.5px; color: var(--ipt-ink); min-width: 0; margin: 0; }
.ipt-lic-value--muted { color: var(--ipt-muted); }
.ipt-lic-value--mono { font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace; font-size: 13px; word-break: break-all; }

/* ---- the key ------------------------------------------------------------- */
/* 32 monospace characters. min-width:0 on the flex child is what stops it
   widening the card instead of shrinking. */
.ipt-lic-keyrow { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
.ipt-acc-ui .entry-content input.ipt-lic-key,
.ipt-lic-key {
	flex: 1 1 220px; min-width: 0;
	font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
	font-size: 13px; letter-spacing: 0.02em; color: var(--ipt-ink);
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 7px;
	padding: 8px 11px; box-shadow: none; text-overflow: ellipsis;
}
.ipt-lic-key--masked { color: var(--ipt-muted); letter-spacing: 0.16em; }

/* ---- status -------------------------------------------------------------- */
.ipt-lic-statusline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ipt-acc-ui .entry-content .ipt-lic-status,
.ipt-lic-status {
	display: inline-block; font-family: 'Montserrat', sans-serif;
	font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
	border-radius: 4px; padding: 2px 8px; white-space: nowrap; margin: 0;
}
.ipt-lic-status--active   { color: #2f7d4f;            background: #eef6f0; border: 1px solid #bcd9c4; }
/* Inactive is not a fault, so it carries no hue — only Expired and the warnings do. */
.ipt-lic-status--inactive { color: var(--ipt-muted);   background: #fff;    border: 1px solid var(--ipt-line-strong); }
.ipt-lic-status--expired  { color: var(--ipt-red-ink); background: #fdeeee; border: 1px solid #eab8b8; }
.ipt-acc-ui .entry-content .ipt-lic-remark,
.ipt-lic-remark { font-size: 13.5px; color: var(--ipt-muted); margin: 0; }

/* ---- warnings ------------------------------------------------------------ */
/* The old markup was a bare dashicon carrying its meaning in a title attribute,
   which a touch user and a screen reader both never see. The sentence is in the
   element now and the icon only decorates it. */
.ipt-lic-warn {
	display: inline-flex; align-items: center; gap: 6px;
	font-size: 13px; line-height: 1.4; color: #8a5a00;
	background: #fff6e8; border: 1px solid #e8c99a;
	border-radius: 6px; padding: 3px 9px;
}
.ipt-lic-warn svg { flex: none; }

/* ---- buttons ------------------------------------------------------------- */
.ipt-acc-ui .entry-content button.ipt-lic-btn,
.ipt-lic-btn {
	display: inline-flex; align-items: center; gap: 7px;
	background: #fff; color: var(--ipt-blue-link);
	border: 1px solid var(--ipt-line-strong); border-radius: 7px;
	padding: 8px 15px;
	font-family: 'Source Sans Pro', sans-serif; font-size: 13.5px; font-weight: 600;
	line-height: 1.2; text-decoration: none; cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.ipt-acc-ui .entry-content button.ipt-lic-btn:hover, .ipt-acc-ui .entry-content button.ipt-lic-btn:focus,
.ipt-lic-btn:hover, .ipt-lic-btn:focus { background: var(--ipt-surface); color: var(--ipt-blue-dark); border-color: var(--ipt-blue-dark); }
.ipt-acc-ui .entry-content button.ipt-lic-btn--primary,
.ipt-lic-btn--primary {
	background: var(--ipt-red-fill); color: #fff; border-color: var(--ipt-red-fill);
	font-family: 'Montserrat', sans-serif; font-weight: 700;
}
.ipt-acc-ui .entry-content button.ipt-lic-btn--primary:hover, .ipt-acc-ui .entry-content button.ipt-lic-btn--primary:focus,
.ipt-lic-btn--primary:hover, .ipt-lic-btn--primary:focus { background: var(--ipt-red-fill-hover); border-color: var(--ipt-red-fill-hover); color: #fff; }
/* The prefix is carried here for the same reason as on the base rule: without it the padding
   below loses to it, and a 34px button with 15px of side padding squeezed the icon to 2px. */
.ipt-acc-ui .entry-content button.ipt-lic-btn--icon,
.ipt-lic-btn--icon { padding: 0; width: 34px; height: 34px; justify-content: center; flex: none; color: var(--ipt-muted); }
.ipt-acc-ui .entry-content button.ipt-lic-btn--icon:hover, .ipt-acc-ui .entry-content button.ipt-lic-btn--icon:focus,
.ipt-lic-btn--icon:hover, .ipt-lic-btn--icon:focus { color: var(--ipt-blue-dark); }
/* And the icon itself refuses to be squashed, whatever the button around it does. */
.ipt-lic-btn svg, .ipt-lic-warn svg, .ipt-lic-adv__btn svg, .ipt-lic-group__chev svg, .ipt-lic-piece__chev svg { flex: none; }
/* `disabled` is the plugin's own state class, toggled by its script, not the attribute. */
.ipt-acc-ui .entry-content button.ipt-lic-btn.disabled,
.ipt-lic-btn.disabled, .ipt-lic-btn[disabled] {
	color: var(--ipt-muted); border-color: var(--ipt-line); background: var(--ipt-surface);
	cursor: not-allowed; pointer-events: none;
}

/* ---- fields -------------------------------------------------------------- */
.ipt-acc-ui .entry-content input.ipt-lic-input,
.ipt-lic-input {
	width: 100%; box-shadow: none;
	font-family: 'Source Sans Pro', sans-serif; font-size: 14.5px; color: var(--ipt-ink);
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 7px; padding: 8px 11px;
}
.ipt-lic-input--mono { font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace; font-size: 13px; }
.ipt-lic-input--invalid, .ipt-lic-input.wipi-invalid { border-color: #eab8b8; background: #fdeeee; }
.ipt-acc-ui .entry-content textarea.ipt-lic-notes,
.ipt-lic-notes {
	width: 100%; min-height: 68px; resize: vertical; box-shadow: none;
	font-family: 'Source Sans Pro', sans-serif; font-size: 14.5px; line-height: 1.5; color: var(--ipt-ink);
	background: #fff; border: 1px solid var(--ipt-line); border-radius: 8px; padding: 10px 12px;
}
.ipt-acc-ui .entry-content textarea.ipt-lic-code,
.ipt-lic-code {
	width: 100%; min-height: 76px; resize: vertical; box-shadow: none;
	font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
	font-size: 12.5px; line-height: 1.5; color: var(--ipt-ink); word-break: break-all;
	background: var(--ipt-surface); border: 1px solid var(--ipt-line); border-radius: 7px; padding: 10px 12px;
}
.ipt-lic-key:focus, .ipt-lic-input:focus, .ipt-lic-notes:focus, .ipt-lic-code:focus {
	outline: 2px solid var(--ipt-blue); outline-offset: 1px;
}
.ipt-lic-fieldhead { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 7px; }
.ipt-lic-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ipt-lic-sep { height: 1px; background: var(--ipt-line); margin: 3px 0; }
.ipt-acc-ui .entry-content .ipt-lic-error,
.ipt-lic-error {
	font-size: 13.5px; line-height: 1.45; color: var(--ipt-red-ink);
	background: #fdeeee; border: 1px solid #eab8b8; border-radius: 6px; padding: 8px 11px; margin: 0;
}

/* ---- advanced ------------------------------------------------------------ */
.ipt-lic-adv { border-top: 1px solid var(--ipt-line); margin-top: 4px; padding-top: 12px; }
.ipt-lic-adv__toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
.ipt-acc-ui .entry-content .ipt-lic-adv__btn,
.ipt-lic-adv__btn {
	display: inline-flex; align-items: center; gap: 7px; cursor: pointer; margin: 0;
	font-size: 13.5px; font-weight: 600; color: var(--ipt-blue-link);
}
.ipt-lic-adv__toggle:focus-visible + .ipt-lic-adv__btn { outline: 2px solid var(--ipt-blue); outline-offset: 2px; }
.ipt-lic-adv__btn svg { transition: transform 0.15s ease; }
.ipt-lic-adv__toggle:checked + .ipt-lic-adv__btn svg { transform: rotate(90deg); }
.ipt-lic-adv__panel { display: none; margin-top: 12px; background: #fff; border: 1px solid var(--ipt-line); border-radius: 8px; }
.ipt-lic-adv__toggle:checked ~ .ipt-lic-adv__panel { display: block; }

/* ---- tabs inside advanced ------------------------------------------------ */
/* Radio inputs, one group name per licence, so the tabs switch without
   JavaScript. Each panel is shown by the radio that precedes it. */
.ipt-lic-tab__radio { position: absolute; width: 1px; height: 1px; opacity: 0; }
.ipt-lic-tabs__head { display: flex; gap: 2px; border-bottom: 1px solid var(--ipt-line); padding: 0 14px; flex-wrap: wrap; }
.ipt-acc-ui .entry-content .ipt-lic-tab,
.ipt-lic-tab {
	display: block; padding: 11px 14px 9px; cursor: pointer; margin: 0 0 -1px;
	font-family: 'Montserrat', sans-serif; font-size: 12.5px; font-weight: 700;
	color: var(--ipt-muted); border-bottom: 2px solid transparent;
}
.ipt-lic-tabs__panel { display: none; padding: 16px 16px 18px; flex-direction: column; gap: 13px; }

/* Two tabs at most, and which is first depends on the licence type, so each
   carries an explicit modifier rather than relying on nth-of-type — the head
   is a div too, which would throw the count off. */
.ipt-lic-tab__radio--main:checked  ~ .ipt-lic-tabs__head .ipt-lic-tab--main,
.ipt-lic-tab__radio--props:checked ~ .ipt-lic-tabs__head .ipt-lic-tab--props {
	color: var(--ipt-blue-dark); border-bottom-color: var(--ipt-blue-dark);
}
.ipt-lic-tab__radio--main:checked  ~ .ipt-lic-tabs__panel--main,
.ipt-lic-tab__radio--props:checked ~ .ipt-lic-tabs__panel--props { display: flex; }
.ipt-lic-tab__radio:focus-visible + .ipt-lic-tabs__head { outline: 2px solid var(--ipt-blue); outline-offset: 2px; }

/* ---- responsive ---------------------------------------------------------- */
@media (max-width: 600px) {
	.ipt-lic-row { grid-template-columns: minmax(0, 1fr); }
	.ipt-lic-label { padding-top: 0; }
	.ipt-lic-piece { padding: 14px; }
	.ipt-lic-group__body { padding: 12px; }
	.ipt-lic-btn { padding: 9px 14px; }
	/* A 32-character key needs about 312px at 13px, which is more than a 390px phone
	   leaves once the card padding is off. Ellipsis hid the end of it; a point smaller
	   and tighter tracking fit the whole key instead. */
	.ipt-lic-key { font-size: 12px; letter-spacing: 0; padding: 8px 9px; }
}

/* The plugin ships a stylesheet of its own for this screen; it is dequeued in
   inc-account.php. These are the few utility classes its script still toggles
   at runtime, so they have to keep working. */
.ipt-lic .wipi-hidden { display: none !important; }
.ipt-lic .wipi-loading { opacity: 0.55; pointer-events: none; }

/* ==========================================================================
   Order licences — progress and results
   --------------------------------------------------------------------------
   Instant actions (copy, restore) confirm themselves on the control and say
   nothing else. Everything that talks to a server reports into one banner at
   the top of its licence, so the controls never move and a screen reader has a
   single region to watch.

   These rules restore behaviour that the plugin's own stylesheet used to carry
   and that was lost when it was dequeued: the spinner on a working button, and
   the conditional icons on the binding key row. The classes below are the ones
   `wipi_functions.js` already toggles and cannot be renamed.
   ========================================================================== */

/* ---- working: text buttons ----------------------------------------------- */
/* The label is made transparent rather than removed, so the button keeps its
   exact width and nothing on the row reflows while the request is in flight.
   .wipi-loading is the plugin's own class; .is-working is ours, for the paths
   the plugin never covered. */
.ipt-acc-ui .entry-content button.ipt-lic-btn.wipi-loading,
.ipt-acc-ui .entry-content button.ipt-lic-btn.is-working,
.ipt-lic-btn.wipi-loading, .ipt-lic-btn.is-working {
	color: transparent;
	position: relative;
	pointer-events: none;
}
.ipt-lic-spin { display: none; }
.ipt-lic-btn.wipi-loading .ipt-lic-spin,
.ipt-lic-btn.is-working .ipt-lic-spin {
	display: block; position: absolute; inset: 0; margin: auto;
	width: 18px; height: 18px; color: var(--ipt-blue-link);
}
.ipt-lic-btn--primary.wipi-loading .ipt-lic-spin,
.ipt-lic-btn--primary.is-working .ipt-lic-spin { color: #fff; }
.ipt-lic-spin circle { opacity: 0.25; }
.ipt-lic-spin path { transform-origin: 10px 10px; animation: ipt-lic-turn 0.75s linear infinite; }

/* ---- working: icon buttons ----------------------------------------------- */
/* An icon button shows the SAME drawn spinner as a text button: its icon is
   hidden and the spinner takes its place. Turning the icon itself was wrong —
   Save carries a tick, and a rotating tick means nothing.

   The plugin's script puts wipi-updating and wipi-deleting on the HIDDEN STATUS
   INPUT, not on the button that was pressed, so the button has to be reached as
   that input's sibling. Written on the button itself these rules parse, match
   nothing, and the row spins for no one. */
.wipi-bindinglicense-status.wipi-updating ~ .ipt-lic-bind .ipt-lic-btn--save,
.wipi-bindinglicense-status.wipi-deleting ~ .ipt-lic-bind .ipt-lic-btn--unbind,
.ipt-lic-btn--icon.is-working { pointer-events: none; }

.wipi-bindinglicense-status.wipi-updating ~ .ipt-lic-bind .ipt-lic-btn--save .ipt-lic-icon,
.wipi-bindinglicense-status.wipi-deleting ~ .ipt-lic-bind .ipt-lic-btn--unbind .ipt-lic-icon,
.ipt-lic-btn--icon.is-working .ipt-lic-icon { display: none; }

.wipi-bindinglicense-status.wipi-updating ~ .ipt-lic-bind .ipt-lic-btn--save .ipt-lic-spin,
.wipi-bindinglicense-status.wipi-deleting ~ .ipt-lic-bind .ipt-lic-btn--unbind .ipt-lic-spin,
.ipt-lic-btn--icon.is-working .ipt-lic-spin {
	display: block; position: static; width: 17px; height: 17px; color: var(--ipt-blue-link);
}

/* Unbind is hidden while the key is modified, but an unbind of a SAVED key must
   stay on screen for as long as it is running. */
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-deleting ~ .ipt-lic-bind button.ipt-lic-btn--unbind,
.wipi-bindinglicense-status.wipi-deleting ~ .ipt-lic-bind .ipt-lic-btn--unbind { display: inline-flex; }

@keyframes ipt-lic-turn { to { transform: rotate(360deg); } }
/* A stopped spinner reads as a hang, so it slows rather than stopping. */
@media (prefers-reduced-motion: reduce) {
	.ipt-lic-spin path { animation-duration: 2.4s; }
}

/* ---- instant actions confirm on the control ------------------------------ */
/* Copy and Restore finish before a message could be read, so the button itself
   becomes the answer for a moment. Nothing is added to the layout. */
.ipt-acc-ui .entry-content button.ipt-lic-btn.is-done,
.ipt-lic-btn.is-done { color: #2f7d4f; background: #eef6f0; border-color: #bcd9c4; }
.ipt-acc-ui .entry-content button.ipt-lic-btn--primary.is-done,
.ipt-lic-btn--primary.is-done { color: #fff; background: #2f7d4f; border-color: #2f7d4f; }
/* The icon and the tick are wrapped in spans so one can replace the other. Those
   spans must be flex boxes: left inline, the span forms a text line, the SVG sits
   on its baseline, and the descender space below pushes the icon about 2px above
   the centre of the button — visible on every icon button at once. line-height: 0
   stops the span reserving that space at all. */
.ipt-lic-btn .ipt-lic-icon,
.ipt-lic-btn .ipt-lic-tick { display: flex; line-height: 0; }
.ipt-lic-btn .ipt-lic-tick { display: none; }
.ipt-lic-btn.is-done .ipt-lic-icon { display: none; }
.ipt-lic-btn.is-done .ipt-lic-tick { display: flex; }

/* ---- the banner, one per licence ----------------------------------------- */
.ipt-lic-said { display: none; }
.ipt-lic-said.is-on { display: block; margin-bottom: 12px; }
.ipt-lic-banner {
	display: flex; align-items: flex-start; gap: 9px;
	font-size: 13.5px; line-height: 1.45;
	border-radius: 7px; padding: 9px 12px;
}
.ipt-lic-banner svg { flex: none; margin-top: 1px; }
.ipt-lic-banner--ok  { color: #2f7d4f;            background: #eef6f0; border: 1px solid #bcd9c4; }
.ipt-lic-banner--bad { color: var(--ipt-red-ink); background: #fdeeee; border: 1px solid #eab8b8; }
.ipt-acc-ui .entry-content button.ipt-lic-banner__x,
.ipt-lic-banner__x {
	margin-left: auto; background: none; border: 0; padding: 0;
	line-height: 0; color: inherit; opacity: 0.65; cursor: pointer;
}
.ipt-lic-banner__x:hover, .ipt-lic-banner__x:focus { opacity: 1; background: none; }
/* Only a failure offers a dismiss — a success clears itself. */
.ipt-lic-banner--ok .ipt-lic-banner__x { display: none; }

/* ---- the binding key row's states ---------------------------------------- */
/* A hidden input carries the state, and the row reads it as a preceding
   sibling. That is the plugin's own arrangement and its script already drives
   every class below; the input must stay immediately before .ipt-lic-bind.

   Every rule here is written through `.ipt-acc-ui .entry-content` and an element
   name, because the base control rules above are, and a shorter selector loses
   to them however far down the file it sits. The state selectors add their
   classes on top of that same floor, so they in turn outrank the resting state.
   Shortening any of these to `.ipt-lic-bind .ipt-lic-btn--save` silently stops
   it working — the rule still parses, matches, and loses. */
.ipt-lic-bind { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
.ipt-acc-ui .entry-content .ipt-lic-bind input.ipt-lic-input,
.ipt-lic-bind .ipt-lic-input { flex: 1 1 220px; min-width: 0; }

.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-modified:not(.wipi-invalid) ~ .ipt-lic-bind input.ipt-lic-input,
.wipi-bindinglicense-status.wipi-modified:not(.wipi-invalid) ~ .ipt-lic-bind .ipt-lic-input {
	border-color: var(--ipt-blue); background: #f7fbff;
}
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-invalid ~ .ipt-lic-bind input.ipt-lic-input,
.wipi-bindinglicense-status.wipi-invalid ~ .ipt-lic-bind .ipt-lic-input {
	border-color: #e8c99a; background: #fff6e8;
}

/* Restore appears only once the key differs from the one that was saved. */
.ipt-acc-ui .entry-content .ipt-lic-bind button.ipt-lic-btn--restore,
.ipt-lic-bind .ipt-lic-btn--restore { display: none; }
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-modified ~ .ipt-lic-bind button.ipt-lic-btn--restore,
.wipi-bindinglicense-status.wipi-modified ~ .ipt-lic-bind .ipt-lic-btn--restore { display: inline-flex; }

/* Unbind acts on the SAVED key, so it steps aside while the field is being
   edited, and greys out when there is nothing bound to remove. */
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-modified ~ .ipt-lic-bind button.ipt-lic-btn--unbind,
.wipi-bindinglicense-status.wipi-modified ~ .ipt-lic-bind .ipt-lic-btn--unbind { display: none; }
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-empty ~ .ipt-lic-bind button.ipt-lic-btn--unbind,
.wipi-bindinglicense-status.wipi-empty ~ .ipt-lic-bind .ipt-lic-btn--unbind {
	color: var(--ipt-muted); border-color: var(--ipt-line); background: var(--ipt-surface); pointer-events: none;
}

/* Save is the opposite: only while there is a change, and only when it could succeed. */
.ipt-acc-ui .entry-content .ipt-lic-bind button.ipt-lic-btn--save,
.ipt-lic-bind .ipt-lic-btn--save { display: none; }
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-modified ~ .ipt-lic-bind button.ipt-lic-btn--save,
.wipi-bindinglicense-status.wipi-modified ~ .ipt-lic-bind .ipt-lic-btn--save { display: inline-flex; }
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-empty ~ .ipt-lic-bind button.ipt-lic-btn--save,
.ipt-acc-ui .entry-content .wipi-bindinglicense-status.wipi-invalid ~ .ipt-lic-bind button.ipt-lic-btn--save,
.wipi-bindinglicense-status.wipi-empty ~ .ipt-lic-bind .ipt-lic-btn--save,
.wipi-bindinglicense-status.wipi-invalid ~ .ipt-lic-bind .ipt-lic-btn--save {
	color: var(--ipt-muted); border-color: var(--ipt-line); background: var(--ipt-surface); pointer-events: none;
}
