/* BD Cat Quickview — frontend styles. Namespaced under bd-sqv- to avoid
   colliding with the active theme/page-builder's own CSS. Override from a
   child theme (enqueue after this stylesheet) rather than editing this file
   directly if you only need visual tweaks; edit the templates in
   templates/ (or a theme override) for structural changes. */

.bd-sqv-wrap {
	position: relative;
	display: inline-block;
}

/* The menu-less carrier (0.50.0, bd_cat_quickview_get_preview_carrier_html()) only
   hands frontend.js a product id. `display: none` here, not only through the
   `hidden` attribute: the rule above would otherwise override it, and a
   sanitizer may strip the attribute. */
.bd-sqv-wrap.bd-sqv-wrap--carrier {
	display: none;
}

/* The trigger is bd-core-shared's icon button — `bd-btn bd-btn--icon` on the
   markup — so its shape, border, colours, hover and focus ring all come from
   components.css; nothing here draws any of them. A card
   sets the diameter: 44px in the catalogue grid, 34px in a carousel, as
   measured off the mockups. This is the standalone size, for a trigger placed
   in a shop loop where no card sets one. */
.bd-sqv-trigger {
	--bd-btn-icon-size: 40px;
}

/* Admin-configured icon (Settings tab) replacing the default "…" glyph.
   !important on sizing: this trigger renders once per product inside the
   shop loop, where WooCommerce's own core stylesheet applies a much more
   specific rule to every <img> in that context —
   `.woocommerce ul.products li.product img { width: 100%; height: auto; ... }`
   (3 classes + 3 type selectors) — which otherwise wins over this plugin's
   single-class selector regardless of source order, blowing the icon up to
   the product thumbnail's full width. Confirmed live on a Divi Ajax
   Filter "Loop Archive" grid, where the WooCommerce loop markup wraps each
   item in exactly that `li.product` structure. */
.bd-sqv-trigger-icon {
	display: block;
	width: 18px !important;
	height: 18px !important;
	object-fit: contain;
}

/* `position: fixed`, not `absolute` — this menu is relocated to be a direct
   child of <body> the first time it's opened (frontend.js's
   relocateMenuToBody()), the same fix already applied to the sidebar in
   0.5.0 for the same underlying reason: a `.bd-sqv-wrap` inside the shop
   loop can sit under an ancestor (a Divi Row/Section using transform, or a
   product-card wrapper using `overflow: hidden`) that either clips an
   absolutely-positioned dropdown or traps a fixed-positioned one inside its
   own containing block/stacking context. Once relocated, `top`/`left` are
   computed and set inline by frontend.js from the trigger's
   `getBoundingClientRect()` (viewport coordinates, flipped to stay inside
   the viewport) — the static `top`/`right` this rule used to carry are
   gone because they only made sense relative to `.bd-sqv-wrap`. z-index
   sits above `.bd-sqv-overlay` below.

   `display: none` belongs in THIS rule and not only in the `[hidden]` rule
   below (0.28.1). The closed state must not depend on any attribute being
   present in the delivered markup: the loop layout this trigger renders
   inside is echoed through a sanitizer before it reaches the browser, and a
   sanitizer can only ever REMOVE markup — so a bare `hidden` may or may not
   survive, while the ABSENCE of `.is-open` always does. When it didn't
   survive, every product's dropdown painted expanded on page load and the
   first scroll of the page collapsed all of them at once. Same shape as
   `.bd-sqv-overlay`/`.is-visible` two rules below. */
.bd-sqv-menu {
	position: fixed;
	z-index: 999999;
	display: none;
	min-width: 200px;
	background: var(--bd-white, #FFFFFF);
	border: 1px solid rgba(0, 0, 0, 0.15);
	border-radius: var(--bd-radius, 4px);
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
	padding: 4px;
}

/* Kept, and still mirrored by frontend.js on every open and close, so the
   markup stays correct with CSS disabled and for anything reading the
   attribute rather than the class. It is no longer what MAKES the menu
   closed — only a second opinion agreeing with the rule above, and a
   stronger one (0-2-0) against a theme rule that sets `display` on this
   element. */
.bd-sqv-menu[hidden] {
	display: none;
}

/* The only thing that opens the menu. Added by frontend.js's toggleMenu()
   before positionMenu() measures the element — a `display: none` element
   reports a 0x0 getBoundingClientRect(), which would silently defeat the
   flip-into-the-viewport arithmetic instead of failing loudly.

   Same specificity as the `[hidden]` rule above (both 0-2-0), so source
   order decides: this MUST stay after it. Moved before it, a menu whose
   `hidden` attribute did survive to the browser could never be opened at
   all. Pinned by tests/Unit/Frontend/MenuOpenStateTest.php. */
.bd-sqv-menu.is-open {
	display: block;
}

/* Dark backdrop shown behind an open trigger menu or the open preview sidebar
   (0.42.0), to spotlight it against the rest of the page — created and
   toggled entirely by frontend.js's syncOverlay() (no shortcode/template
   renders this; a single shared node is enough since only one `.bd-sqv-menu`
   is ever open at a time, see closeAllMenus(), and the sidebar is a single
   node too). Sits just under the menu's and the sidebar's own z-index so
   both remain clickable; a click on the backdrop itself dismisses them. */
.bd-sqv-overlay {
	display: none;
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.6);
	z-index: 999998;
}

.bd-sqv-overlay.is-visible {
	display: block;
}

.bd-sqv-menu-item {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	background: none;
	border: 0;
	text-align: left;
	padding: 8px 12px;
	font-size: var(--bd-fs-sm, 13px);
	cursor: pointer;
	text-decoration: none;
	color: inherit;
	border-radius: var(--bd-radius, 4px);
}

.bd-sqv-menu-item:hover,
.bd-sqv-menu-item:focus {
	background: rgba(0, 0, 0, 0.06);
}

/* Never hidden — a control whose condition isn't met (not logged in, book
   not in the visitor's plan, no free copy) renders like this instead. Since
   0.33.0 it is a real <button> that opens bd-core-shared's modal to say why, so
   it reads unavailable but is genuinely operable: no pointer-events:none,
   and the cursor stays `pointer` rather than `not-allowed`, which would
   promise nothing happens on click. */
.bd-sqv-menu-item.is-disabled {
	opacity: 0.55;
}

/* The sidebar's unavailable read button takes bd-core-shared's muted .bd-btn
   look; only the cursor is put back, for the reason given above. */
.bd-sqv-preview-action-btn.is-disabled {
	cursor: pointer;
}

.bd-sqv-menu-item.is-disabled:hover {
	background: none;
}

/* bd-b2b-loans' "Cancel loan" button, when it is placed in this menu.
   That plugin owns the control — its markup, its confirmation dialog and its
   request — and this rule owns only how it sits in furniture this plugin
   draws, which is the same division the watchlist button settled into in
   0.56.0 after three stylesheets had each claimed a copy of it.

   Only this menu's own look belongs here — the padding, the type size, the
   row's corner radius. Undoing the button itself, its box and its centring, is
   bd-b2b-loans' job and is done by the `--menu-item` modifier over there:
   that sheet is enqueued from the render call, so it lands after this one and
   anything this file tried to override would tie on specificity and lose on
   source order. The selector stays scoped to `.bd-sqv-menu` so the button keeps
   its own appearance on the surfaces that are not this menu. */
.bd-sqv-menu .bd-btn-cancel-loan--menu-item {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 8px 12px;
	font-size: var(--bd-fs-sm, 13px);
	line-height: inherit;
	border-radius: var(--bd-radius, 4px);
	cursor: pointer;
}

/* The plain row highlight, the same one every other item gets. The danger
   colour this button carries elsewhere is not merely overridden here — it is
   declined at the source, by bd-b2b-loans excluding the `--menu-item`
   variant from its own hover rule. Overriding it from this file was tried and
   does not work: the two selectors tie on specificity and that sheet loads
   last, which is why the item used to turn solid red under the pointer inside
   a dropdown of otherwise neutral rows. */
.bd-sqv-menu .bd-btn-cancel-loan--menu-item:hover,
.bd-sqv-menu .bd-btn-cancel-loan--menu-item:focus {
	background: rgba(0, 0, 0, 0.06);
	color: inherit;
}

/* Hold the row's own padding on hover/focus: bd-core-shared's
   `.bd-btn:not(.bd-btn--icon):hover` swaps it with !important, which shifted
   the row under the pointer. Kept here so an older bd-shared still renders
   right. The icon keeps its own colours too, never the inverted white of the
   red standalone button, which would vanish on this light row. */
.bd-sqv-menu .bd-btn-cancel-loan--menu-item:hover,
.bd-sqv-menu .bd-btn-cancel-loan--menu-item:focus {
	padding: 8px 12px !important;
}

.bd-sqv-menu .bd-btn-cancel-loan--menu-item:hover .bd-sqv-menu-item-icon,
.bd-sqv-menu .bd-btn-cancel-loan--menu-item:focus .bd-sqv-menu-item-icon {
	filter: none !important;
	opacity: 1;
	visibility: visible;
}

/* One static icon per fixed menu item (Scheda Libro / Indice Libro / Leggi
   EPUB / Leggi PDF / Annulla prestito) — admin-uploaded (Settings tab) or the
   plugin's own bundled placeholder. The last of those rides inside markup
   bd-b2b-loans renders, which is why the icon travels to it as an argument
   rather than being drawn there. !important on sizing for the same reason as
   .bd-sqv-trigger-icon above — this menu is nested inside the same
   per-product shop-loop item, subject to the same WooCommerce core
   `.woocommerce ul.products li.product img` override. */
.bd-sqv-menu-item-icon {
	flex: 0 0 auto;
	width: 16px !important;
	height: 16px !important;
	object-fit: contain;
}

/* Every icon this plugin draws beside a label (BD_Cat_Quickview_Frontend::
   get_icon_mask_html(), 0.58.1): a span filled with the text colour and cut
   to the icon's shape by a mask, so it follows that colour through rest,
   hover, focus and the disabled look — white on the navy hover of bd-core-shared's
   ghost button, where an <img> stayed dark. Only the image's alpha is used: a
   bundled line SVG or an uploaded icon on a transparent background. The URL
   arrives in the inline `--bd-sqv-icon` property. The "Cancel loan" row gets
   both `icon_url` (a mask drawn by bd-reservations 0.85.0+) and `icon_html`
   (an <img>, for older releases, still sized by .bd-sqv-menu-item-icon). */
.bd-sqv-icon {
	display: inline-block;
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	vertical-align: middle;
	background-color: currentColor;
	-webkit-mask-image: var(--bd-sqv-icon);
	mask-image: var(--bd-sqv-icon);
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

/* Windows high-contrast: a forced background would paint the whole box.
   Opting the span out keeps `currentColor`, which is the forced text colour
   of the control around it. */
@media (forced-colors: active) {
	.bd-sqv-icon {
		forced-color-adjust: none;
		background-color: currentColor;
	}
}

/* Sidebar — a genuine right-hand panel (0.5.0), fixed to the viewport at
   full height, wherever [bd_cat_quickview_sidebar] is placed in the
   markup (position is irrelevant now — it's taken out of flow). Hidden by
   default and shown only once real content has loaded (see the visibility
   rule below); the close button, a click on the shared `.bd-sqv-overlay`
   backdrop above, or Escape hides the whole panel, not just its content —
   see frontend.js's setSidebarCollapsed().

   This reverses 0.3.0's "static in-flow block, not an overlay" decision.
   That change was prompted by a real bug where the theme's own default
   widget sidebar was bleeding through and the off-canvas/relocation
   machinery made it harder to diagnose — the actual cause (this plugin's
   template being named `sidebar.php`, colliding with a WordPress-reserved
   template filename) is unrelated and was fixed at the root in 0.3.4
   (renamed to `preview-sidebar.php`). With that fixed, a fixed overlay
   panel is safe to use again and matches how the admin actually wants this
   presented — a proper sidebar, not a small popup. */

.bd-sqv-sidebar {
	display: none;
	position: fixed;
	top: 0;
	right: 0;
	/* ~50% of the viewport on desktop (0.8.0 redesign), never narrower than
	   360px nor wider than 720px so it stays readable on very small/large
	   screens; collapses to full-width below the WP admin-bar mobile
	   breakpoint (782px) — see the media query below. */
	width: 50vw;
	min-width: 360px;
	max-width: 720px;
	height: 100vh;
	background: var(--bd-white, #FFFFFF);
	border-left: 1px solid rgba(0, 0, 0, 0.12);
	box-shadow: -4px 0 20px rgba(0, 0, 0, 0.12);
	/* High enough to clear typical page-builder headers/menus (Divi's own
	   admin bar sits at 99999). frontend.js also relocates this element to
	   be a direct child of <body> on load — a z-index alone can't help if
	   [bd_cat_quickview_sidebar] was placed inside an ancestor that traps
	   `position: fixed` in its own stacking context (transform/filter/
	   opacity, common on Divi Row/Section wrappers). */
	z-index: 999999;
}

@media (max-width: 782px) {
	.bd-sqv-sidebar {
		width: 100vw;
		min-width: 0;
		max-width: 100vw;
	}
}

/* Shown once real content has replaced the initial placeholder, and not
   closed. Keyed on the *absence* of the placeholder rather than the
   *presence* of `.bd-sqv-preview`, so the panel doesn't flicker closed
   while a subsequent "Anteprima" click is loading (frontend.js clears the
   content — removing `.bd-sqv-preview` — before the new one arrives; the
   placeholder itself never comes back once removed). */
.bd-sqv-sidebar:not(.is-collapsed):not(:has(.bd-sqv-sidebar-placeholder)) {
	display: flex;
	flex-direction: column;
}

/* Header simplified to just the close X (0.8.0) — no title/border, floats
   in the top-right corner over the content below. */
.bd-sqv-sidebar-header {
	display: flex;
	justify-content: flex-end;
	padding: 16px 20px 0;
	flex-shrink: 0;
}

/* The button is the 44x44 hit area (WCAG 2.5.5) and draws nothing; the 28px
   ring the mockup shows is its inner glyph span. The negative margin keeps the
   ring where the 28px button used to sit in the header's corner. */
.bd-sqv-sidebar-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin: -8px -8px 0 0;
	padding: 0;
	background: none;
	border: 0;
	color: inherit;
	cursor: pointer;
}

.bd-sqv-sidebar-toggle span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border: 1px solid rgba(0, 0, 0, 0.15);
	border-radius: var(--bd-radius-circle, 50%);
	line-height: 1;
	font-size: var(--bd-fs-lg, 17px);
}

.bd-sqv-sidebar-content {
	padding: 8px 32px 32px;
	flex: 1;
	overflow-y: auto;
}

.bd-sqv-sidebar-placeholder {
	color: var(--bd-text-muted, #5A6989);
	margin: 0;
}

.bd-sqv-sidebar-loading {
	text-align: center;
	padding: 24px 0;
	color: var(--bd-text-muted, #5A6989);
}

.bd-sqv-sidebar-loading[hidden] {
	display: none;
}

.bd-sqv-sidebar-error {
	text-align: center;
	padding: 24px 12px;
	color: var(--bd-danger, #B3261E);
}

.bd-sqv-preview-title {
	margin: 0 0 4px;
	text-align: center;
	font-weight: 700;
}

.bd-sqv-preview-subtitle {
	margin: 0 0 4px;
	color: var(--bd-text-muted, #5A6989);
	font-style: italic;
	text-align: center;
}

/* Below the title/subtitle (0.9.1) — same 16px gap whether or not a
   subtitle is present, since the subtitle's own bottom margin is small. */
.bd-sqv-preview-image {
	display: block;
	max-width: 240px;
	max-height: 340px;
	width: auto;
	height: auto;
	margin: 12px auto 20px;
}

/* The containing block of bd-core-shared's .bd-ribbon: shrink-wrapped to the
   cover so the ribbon sits on the jacket's corner, centred as the image was.
   The image's own margin moves here; a theme override without the wrapper
   keeps the rule above. */
.bd-sqv-preview-cover {
	position: relative;
	width: fit-content;
	max-width: 100%;
	margin: 12px auto 20px;
}

.bd-sqv-preview-cover .bd-sqv-preview-image {
	margin: 0;
}

/* "Leggi EPUB"/"Leggi PDF" and, mutually exclusive with those,
   the reservation-status notice + "Richiedilo alla Biblioteca"/"Avvisami
   quando disponibile" — see Grafica/3_SCHEDA-LIBRO-OVERLAY_SETTEMBRE26.jpg and
   Grafica/4_SCHEDA-LIBRO-PRESTATO-OVERLAY_SETTEMBRE26.jpg for the visual this
   follows. Radii come from bd-core-shared's tokens: --bd-radius (4px) on every
   rectangle, --bd-radius-circle on the square close control, never a pill. */
.bd-sqv-preview-read-actions,
.bd-sqv-preview-secondary-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-bottom: 20px;
}

/* Every control here is a bd-core-shared `.bd-btn` (0.56.0), `--primary` for each
   available read format and the journal link, `--ghost` otherwise (0.59.0):
   size, padding, font, border, radius, hover and the Divi ::after defence all come
   from components.css, and nothing in this sheet resizes a .bd-btn. This rule
   only places the control in its flex row. */
.bd-sqv-preview-action-btn {
	flex: 0 1 auto;
}

/* Divi decorates every <button> with an arrow in ::after and widens its
   padding on hover. components.css mounts the same defence for .bd-btn. */
.bd-sqv-menu-item::after {
	display: none !important;
}

/* The format icon of «Leggi ePUB»/«Leggi PDF», the one icon the mockup puts
   on these buttons; the other controls carry text only. Since 0.58.1 it is a
   `.bd-sqv-icon` (16px, text-coloured, see above); this rule only sizes an
   <img> a theme override builds itself (an override still passing the icon
   through a wp_kses() img allow-list prints nothing: see the 0.58.1 entry). */
.bd-sqv-preview-action-btn img {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
}

/* Wired to real bd-b2b-loans capacity data since 0.7.0 — see
   BD_Cat_Quickview_Frontend::get_reservation_status(). */
.bd-sqv-preview-reservation-status {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 12px;
	padding: 8px 14px;
	border: 1px solid rgba(0, 0, 0, 0.15);
	border-radius: var(--bd-radius, 4px);
	font-size: var(--bd-fs-sm, 13px);
	color: var(--bd-text, #022A61);
}

/* A theme override's <img>; the plugin's own icon is a `.bd-sqv-icon`. */
.bd-sqv-preview-reservation-status img {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
}

.bd-sqv-preview-missing-plan-notice {
	margin: 0 0 12px;
	padding: 8px 14px;
	border: 1px solid rgba(0, 0, 0, 0.15);
	border-radius: var(--bd-radius, 4px);
	font-size: var(--bd-fs-sm, 13px);
	color: var(--bd-text, #022A61);
	text-align: center;
}

/* "Richiedilo alla Biblioteca" (bd-b2b-requests' .bd-br-request-btn) and
   "Avvisami quando disponibile" (bd-b2b-loans' .bd-btn-watchlist) are
   reused, self-sufficient markup owned by their respective plugins, both
   already `.bd-btn .bd-btn--ghost`. Since 0.56.0 this sheet no longer reskins
   them: they render at the standard .bd-btn size, colour, disabled state and
   hover exactly as everywhere else on the site, with no decorative icon. Only
   their place in this row is decided here. */
.bd-sqv-preview-secondary-actions .bd-br-request-btn,
.bd-sqv-preview-secondary-actions .bd-btn-watchlist {
	flex: 0 1 auto;
	margin: 0;
}

/* Since bd-book-requests 0.36.0 the capacity button shares its wrapper with
   the "?" help control, so the flex item in this row is the wrapper rather
   than the button. The button styling above still targets the button itself;
   this only stops the wrapper's own vertical margin pushing the pair out of
   line with the watchlist button beside it. */
.bd-sqv-preview-secondary-actions .bd-br-request-wrap {
	margin: 0;
}

/* Colour only: the "?" control's size and its 24px target are bd-b2b-requests'
   own, and this sheet no longer shrinks it (0.56.0). */
.bd-sqv-preview-secondary-actions .bd-br-help-btn {
	background: var(--bd-white, #FFFFFF);
	border-color: var(--bd-blue, #001E60);
	color: var(--bd-blue, #001E60);
	opacity: 1;
}

.bd-sqv-preview-secondary-actions .bd-br-help-btn:hover,
.bd-sqv-preview-secondary-actions .bd-br-help-btn:focus {
	background: rgba(26, 61, 124, 0.06);
}

/* Manager self-service purchase — bd-b2b-requests' "Add to team plan" /
   "Add a licence" button, plus its notice. Additive rather than mutually
   exclusive with the blocks above: a manager can land in any of the three
   and still need this one, so it gets a top rule to separate it from
   whichever preceded it rather than sharing their spacing. */
.bd-sqv-preview-manager-actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	margin-bottom: 20px;
	padding-top: 16px;
	border-top: 1px solid rgba(0, 0, 0, 0.08);
}

/* bd-b2b-requests' own wrapper. Its JS appends the confirmation notice and
   the cart link inside it after a successful click, so it has to stack them
   rather than sit as a bare flex item. */
.bd-sqv-preview-manager-actions .bd-br-manager-purchase-wrap {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
}

.bd-sqv-preview-manager-notice {
	margin: 0;
	font-size: var(--bd-fs-sm, 13px);
	color: var(--bd-text-muted, #5A6989);
	text-align: center;
}

/* bd-b2b-requests' purchase button is already `.bd-btn .bd-btn--primary`,
   filled because it is a purchase rather than one more way to ask. Since
   0.56.0 it renders at the standard .bd-btn size with no reskin here; only
   the margin its own sheet may give it is reset inside this column. */
.bd-sqv-preview-manager-actions .bd-br-manager-purchase-btn {
	margin: 0;
}

.bd-sqv-preview-manager-actions .bd-br-manager-purchase-notice {
	margin: 0;
	font-size: 12px;
	color: var(--bd-success-ink, #007E3F);
	text-align: center;
}

.bd-sqv-preview-manager-actions .bd-br-manager-purchase-cart-link {
	font-size: var(--bd-fs-sm, 13px);
	font-weight: 600;
	color: var(--bd-blue, #001E60);
}

.bd-sqv-preview-description h3 {
	margin: 0 0 8px;
}

.bd-sqv-preview-description {
	margin-bottom: 20px;
}

/* Justified, as in the reference mockup. Scoped to our own container, and
   necessarily written against the bare `p`: this text comes out of
   wpautop(), so those paragraphs carry no class we could put here — the
   container class is what keeps the rule off Divi's own paragraphs.
   hyphens is not decoration: justifying Italian prose in a ~470px column
   without it opens rivers of white space between the words. */
.bd-sqv-preview-description p {
	text-align: justify;
	hyphens: auto;
}

/* Optional clamp (0.39.0), off unless an admin sets a line count on the
   Settings tab. The clamp is on this inner element and not on the container
   above, so the "Description" heading and the toggle button stay outside the
   box being clamped — otherwise the heading would eat one of the N lines and
   the button would be hidden along with the text it reveals.

   `display: -webkit-box` is what makes -webkit-line-clamp work at all, and it
   is unprefixed-in-name-only: every current engine implements this exact
   spelling, Firefox included. The paragraphs inside still stack, because the
   box orients vertically.

   .is-clamped is put on server-side, not by JS, so the text is never painted
   at full height and then collapsed — that flash would happen on every single
   open, the panel's markup being re-injected each time.

   The cut is stated TWICE, as in bd-core-shared's card-title clamp and for its
   reason: -webkit-line-clamp is a deprecated prefixed property that a minifier
   or a "Minify and Combine CSS" pass is free to drop, and where it goes the
   text runs free with nothing on the page to say so. overflow + max-height do
   the cut on their own; where the clamp survives the two agree and only the
   ellipsis is its contribution. Unlike that precedent there is no min-height
   here: a row of cards needs every title box to be exactly N lines so the
   cards line up, but there is one description and nothing to line it up with,
   so forcing N lines would only pad a short one. */
.bd-sqv-preview-description-body.is-clamped {
	--bd-sqv-desc-lines: 6;
	--bd-sqv-desc-line-height: 1.6;

	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--bd-sqv-desc-lines);
	line-clamp: var(--bd-sqv-desc-lines);
	overflow: hidden;
	line-height: var(--bd-sqv-desc-line-height);
	max-height: calc(var(--bd-sqv-desc-lines) * var(--bd-sqv-desc-line-height) * 1em);
}

/* Load-bearing, not tidying. max-height above counts LINES, and Divi 5 ships a
   global `p { padding-bottom: 1em }` — the same declaration the meta-row block
   further down already had to fight — which would put uncounted height between
   the paragraphs and cut the text a line or more early. It goes wrong only on
   the real site, never in isolation, which is exactly the kind of thing worth
   writing down. */
.bd-sqv-preview-description-body.is-clamped p {
	margin: 0;
	padding-bottom: 0;
}

/* Rendered with `hidden` and revealed by frontend.js only where the text
   really does overflow — a "Read more" that opens nothing is worse than no
   button at all, and nothing server-side can know how many lines a given
   description takes in a given viewport. */
.bd-sqv-preview-description-toggle {
	display: inline-block;
	margin-top: 6px;
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	font-size: var(--bd-fs-sm, 13px);
	font-weight: 600;
	color: var(--bd-blue, #001E60);
	text-decoration: underline;
	cursor: pointer;
}

.bd-sqv-preview-description-toggle[hidden] {
	display: none;
}

/* Autori, ISBN carta/PDF/EPUB, DOI, Anno/Mese di pubblicazione, Edizione,
   Pagine — one "Label: value" line per field, only the ones with an actual
   value are rendered. */
.bd-sqv-preview-meta {
	margin: 0 0 20px;
}

/* Targeted by our own class rather than by `p`, so nothing here can reach a
   paragraph Divi styles. The pitch is the mockup's: ~30px per row on a 16px
   body, which is 1.5 of leading plus a 6px gap and NOT a single loose
   line-height — the authors row wraps to three lines, and those must stay
   tighter than the space between one field and the next.
   padding-bottom is the load-bearing declaration: Divi 5 ships a global
   `p { padding-bottom: 1em }` that the old `margin: 0 0 8px` did nothing
   about, which is the whole reason this block read at nearly double the
   mockup's spacing. */
.bd-sqv-preview-meta-row {
	margin: 0 0 6px;
	padding-bottom: 0;
	line-height: 1.5;
}

.bd-sqv-preview-meta-row:last-child {
	margin-bottom: 0;
}

.bd-sqv-preview-category {
	margin: 0 0 16px;
}

/* The row the panel closes with: an outbound link to buy the paperback at the
   publisher. Separated by a rule rather than by space alone, because it is the
   one control here that leaves the site — everything above it stays inside the
   library. Centred like the action block at the top, since it renders the same
   button; the rule above it is what keeps the two from reading as one group.

   Note the button itself needs no styling of its own: it is
   `.bd-btn .bd-btn--ghost`, never primary, text only.
   .bd-sqv-preview-paper-btn rides alongside purely so a site can target this
   one control. */
.bd-sqv-preview-paper-link {
	display: flex;
	justify-content: center;
	margin: 4px 0 16px;
	padding-top: 16px;
	border-top: 1px solid var(--bd-grey-200, #E5E5E5);
}

/* ── Standalone [bd_book_*] action shortcodes ─────────────────────────────
   The seven action shortcodes reuse the sidebar's own container classes so
   they inherit its button styling for free — including the rules above that
   reskin bd-b2b-requests' and bd-b2b-loans' own buttons, which are
   scoped to .bd-sqv-preview-secondary-actions. This extra class rides
   alongside so a site can target "this control placed on its own in a Divi
   layout" without also restyling the sidebar. The sidebar never carries it.
   Left-aligned rather than centered: on a product page these sit in a
   normal content column, not in a narrow centered panel. */
.bd-sqv-standalone-action {
	justify-content: flex-start;
}

/* [bd_cat_quickview_book_actions] is one row on a product template (0.58.0): the read
   buttons, then the links its `secondary` attribute appends (index, paper),
   left-aligned, wrapping on a narrow column with the same 8px gap in both
   directions. Every available read button (or the journal link) is
   `.bd-btn--primary` (0.59.0); the rest are ghost. */
.bd-sqv-preview-read-actions.bd-sqv-standalone-action {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-start;
	gap: 8px;
}

/* [bd_cat_quickview_book_actions] (0.47.1): the button rows of the composite block carry
   the class too. The sidebar's 20px under each row is panel spacing; on a
   template the layout decides it, keeping an 8px gap before whatever the
   block renders next (the manager block, a second row). */
.bd-sqv-preview-read-actions.bd-sqv-standalone-action,
.bd-sqv-preview-secondary-actions.bd-sqv-standalone-action {
	margin-bottom: 0;
}

.bd-sqv-preview-read-actions.bd-sqv-standalone-action + *,
.bd-sqv-preview-secondary-actions.bd-sqv-standalone-action + * {
	margin-top: 8px;
}

/* The manager block inside [bd_cat_quickview_book_actions] follows the left-aligned rows;
   its top rule still separates it from them. The sidebar never carries it. */
.bd-sqv-preview-manager-actions.bd-sqv-standalone-action,
.bd-sqv-preview-manager-actions.bd-sqv-standalone-action .bd-br-manager-purchase-wrap {
	align-items: flex-start;
}

.bd-sqv-preview-manager-actions.bd-sqv-standalone-action {
	margin-bottom: 0;
}

.bd-sqv-preview-manager-actions.bd-sqv-standalone-action .bd-sqv-preview-manager-notice {
	text-align: left;
}

/* [bd_cat_quickview_book_paper_link] (0.46.0): the sidebar's closing row placed on its own.
   The rule and the spacing that separate it from the panel above belong to
   the sidebar; on a template the layout around it decides. */
.bd-sqv-preview-paper-link.bd-sqv-standalone-action {
	margin: 0;
	padding-top: 0;
	border-top: 0;
}

/* [bd_cat_quickview_book_details] (0.46.0): the book's metadata card on a product template.
   A two-column grid of label/value rows, each row a <div> inside the <dl>,
   separated by a hairline. Tokens only, so it follows the suite's palette. */
.bd-sqv-book-details {
	margin: 0 0 var(--bd-space-md);
	padding: var(--bd-space-sm) var(--bd-space-md);
	border: 1px solid var(--bd-border);
	border-radius: var(--bd-radius, 4px);
	background: var(--bd-surface);
	font-family: var(--bd-font-sans);
	font-size: var(--bd-fs-sm);
	line-height: var(--bd-lh);
	color: var(--bd-text);
}

.bd-sqv-book-details__row {
	display: grid;
	grid-template-columns: minmax(8rem, 40%) 1fr;
	gap: var(--bd-space-md);
	padding: var(--bd-space-xs) 0;
	border-bottom: 1px solid var(--bd-border-subtle);
}

.bd-sqv-book-details__row:last-child {
	border-bottom: 0;
}

.bd-sqv-book-details__label {
	margin: 0;
	font-weight: var(--bd-fw-medium);
	color: var(--bd-text-muted);
}

.bd-sqv-book-details__value {
	margin: 0;
	padding: 0;
	overflow-wrap: anywhere;
}

.bd-sqv-book-details__value a {
	color: var(--bd-link);
}

/* Only ever visible while the bd_cat_quickview_actions_debug option is on — a build
   aid for laying out a Divi template, never the live storefront. Styled to
   look obviously like scaffolding so it cannot be mistaken for content. */
.bd-sqv-actions-debug {
	margin: 0 0 8px;
	padding: 6px 10px;
	border: 1px dashed rgba(0, 0, 0, 0.35);
	border-radius: var(--bd-radius, 4px);
	background: rgba(0, 0, 0, 0.03);
	font-size: 12px;
	color: var(--bd-text-muted, #5A6989);
}

.bd-sqv-actions-debug code {
	background: none;
	padding: 0;
	font-size: 12px;
}

/* A card carrying a "..." trigger, or since 0.50.0 a menu-less carrier, opens
   its panel from the cover and the title (0.45.0, frontend.js openFromCard()). Anchors already show a pointer;
   this covers the unlinked cover and title, which would otherwise look inert. */
.bd-book-card:has(.bd-sqv-wrap) .bd-book-card__cover,
.bd-book-card:has(.bd-sqv-wrap) .bd-book-card__title {
	cursor: pointer;
}
