@charset "UTF-8";
/**
 * Text Block - Main Styles
 * Using modern SASS module system
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Token Index
 * Forwards all design tokens
 *
 * Usage in other files:
 * @use '../shared/tokens' as tokens;
 *
 * color: tokens.$color-base-black;
 */
/**
 * Color Tokens
 * Pure CSS variables - no mixins, just values
 * Can be safely imported anywhere
 */
/**
 * Spacing Tokens
 * Pure CSS variables - no mixins, just values
 * Can be safely imported anywhere
 */
/**
 * Typography Tokens
 * Pure CSS variables - no mixins, just values
 * Can be safely imported anywhere
 */
/**
 * Breakpoint Tokens
 * Pure values - no mixins, just variables
 * Can be safely imported anywhere
 */
/**
 * Transition & Animation Tokens
 * Pure CSS variables - no mixins, just values
 * Can be safely imported anywhere
 */
/**
 * Mixins Index
 * Forwards all mixins for use in components
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 *
 * .container { @include mix.container(); }
 * .heading { @include mix.heading-lg(); }
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Container Mixins
 * Reusable container patterns
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 * .my-class { @include mix.container(); }
 */
/**
 * Responsive Mixins
 * Media query helpers using modern SASS
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 * @include mix.media-md { ... }
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Typography Mixins
 * Reusable text styles
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 * h1 { @include mix.heading-lg(); }
 */
/**
 * Background Mixins
 * Consistent background and text color combinations
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 * .block { @include mix.block-backgrounds('block-name'); }
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Height System Mixins
 * Reusable height constraints for images and media blocks
 */
/**
 * Apply height variants for images
 * Works with both cover and contain object-fit modes
 * - Cover mode: Fixed height (crops to fill)
 * - Contain mode: Max height (scales down proportionally)
 *
 * @param {String} $selector - The image selector to apply heights to
 * @param {String} $block-class - The block class for data attributes
 */
/**
 * Apply object-fit modes for images
 *
 * @param {String} $selector - The image selector
 * @param {String} $block-class - The block class for data attributes
 */
/**
 * Apply height variants for block containers (not images)
 * For hero/banner blocks that need full container height control
 *
 * @param {String} $block-class - The block class for data attributes
 */
/**
 * Card-specific height system with aspect-ratio on mobile
 * Hybrid approach: aspect-ratio on mobile, vh-driven on desktop
 *
 * Mobile: Content-aware (aspect ratio) with max-height constraint
 * Desktop: Viewport-driven (vh) with min-height fallback (existing behavior)
 *
 * This solves mobile scroll issues while preserving desktop impact.
 *
 * @param {String} $selector - The image selector to apply heights to
 * @param {String} $block-class - The block class for data attributes
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Hero Positioning Mixin (AB-42, Chunk 0.5b)
 * ONE positioning model for all hero layouts. Replaces the three per-layout
 * `align-items` systems (construction review F1) with a single band-relative
 * placement that is header-aware (F4) and content-fit-aware (F3).
 *
 * The model: the "positioning region" is a flex COLUMN with a top safe-zone
 * inset. Content is placed within the band (safe-zone top → region bottom) via
 * `justify-content: safe <valign>`; halign via `align-items`. `safe` means the
 * placement degrades to start (top) when content exceeds the band, so content
 * NEVER overflows upward under a fixed nav. Proven in the harness
 * (blocks/inner-hero/__harness__/probe-safe.mjs): clearance >= 0 for every
 * valign × content-length at an 88px underlap nav.
 *
 * data-* contract (emitted by render.php + edit.js, identical):
 *   data-valign         : start | center | end          (base, all widths)
 *   data-valign-mobile   : "" | start | center | end     ("" = inherit base)
 *   data-halign          : start | center | end          (base)
 *   data-halign-mobile   : "" | start | center | end     ("" = inherit)
 *   data-underlap        : true | false                  (render-computed)
 *   data-content-fit     : flow | clip                   (flow = default)
 *
 * The safe-zone value: JS publishes --header-height (the real nav height); we
 * provide a per-breakpoint CSS fallback so the reserve is correct BEFORE JS runs
 * (architecture §4 option c — no first-paint jump dependent on JS). Only applied
 * when data-underlap="true"; standard pages reserve nav space on <main> already.
 *
 * IMPORTANT: call this at the TOP LEVEL (not nested inside a selector) and pass
 * fully-qualified selector STRINGS — the mixin builds its own rules. `&` does
 * not compose across a root/region split, so we never rely on it here.
 */
/**
 * Apply the positioning model.
 *
 * @param {String} $root   - the block-root selector the data-* attrs live on,
 *                           e.g. '.inner-hero[data-layout="full-image"]'.
 * @param {String} $region - suffix appended to $root to reach the flex-column
 *                           positioning region. '' when the region IS the root
 *                           (full-image / text-only); ' .child' when it's a
 *                           descendant (split's content side). Include the
 *                           leading space for a descendant.
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Alignment Mixins
 * Reusable alignment patterns for images and media blocks
 */
/**
 * Apply image alignment within containers
 *
 * @param {String} $figure-selector - The figure/wrapper selector
 * @param {String} $block-class - The block class for data attributes
 * @param {Boolean} $include-container - Whether to include container alignment
 */
/**
 * Apply caption alignment based on image alignment
 *
 * @param {String} $caption-selector - The caption selector
 * @param {String} $block-class - The block class for data attributes
 */
/**
 * Apply vertical alignment for grid containers
 * Used for multi-image layouts (double, triple)
 *
 * @param {String} $container-selector - The grid container selector
 * @param {String} $block-class - The block class for data attributes
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Grid Split Ratio Mixins
 * Reusable grid column layouts for multi-column blocks
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 *
 * .my-block {
 *   @include mix.grid-split-two('.my-block-inner');
 * }
 */
/**
 * Two-column split ratio layouts
 * Supports: 50-50, 60-40, 40-60, 70-30, 30-70
 *
 * @param {String} $inner-selector - The grid container selector (e.g., '.inner', '.grid')
 * @param {String} $block-class - Optional block class for scoping
 */
/**
 * Two-column split ratios for edge-to-edge layouts
 * Uses fr units instead of column spans (simpler for edge-to-edge)
 *
 * @param {String} $inner-selector - The grid container selector
 * @param {String} $block-class - Optional block class for scoping
 */
/**
 * Three-column split ratio layouts
 * Supports: 33-33-33, 25-25-50, 50-25-25
 *
 * @param {String} $inner-selector - The grid container selector
 * @param {String} $block-class - Optional block class for scoping
 */
/**
 * Three-column split ratios for edge-to-edge layouts
 *
 * @param {String} $inner-selector - The grid container selector
 * @param {String} $block-class - Optional block class for scoping
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Flexbox Split Layout Mixins
 * Reusable flexbox layouts for side-by-side blocks
 *
 * Handles common flexbox split pattern:
 * - Mobile: column layout (stacked)
 * - Desktop: row layout (side-by-side)
 * - Prevents overflow bugs from width: 100% + flex-basis conflicts
 *
 * Usage:
 * @use '../shared/mixins' as mix;
 *
 * .my-block {
 *   @include mix.flex-split-container();
 * }
 * .my-block-child {
 *   @include mix.flex-split-child();
 * }
 */
/**
 * Flexbox split container
 * Use on parent element that contains split children
 *
 * @param {String} $gap-mobile - Gap between items on mobile (default: 0)
 * @param {String} $gap-desktop - Gap between items on desktop (default: 0)
 */
/**
 * Flexbox split child
 * Use on child elements within a flex split container
 * Prevents overflow by only applying width: 100% on mobile
 *
 * IMPORTANT: This prevents the common bug where width: 100% + flex-basis
 * causes horizontal overflow in flexbox row layouts
 */
/**
 * Flexbox split ratios
 * Use on children to control their width in desktop split layout
 *
 * @param {String} $ratio - Split ratio (50-50, 40-60, 60-40)
 * @param {String} $position - Which child this is (left, right, first, second)
 */
/**
 * Flexbox split with data attribute support
 * Generates split ratios based on data-split attribute
 * Use this on the container when you want data-attribute control
 *
 * @param {String} $child-selector - The child element selector
 * @param {String} $block-class - Optional block class for scoping
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Overlay System Mixins
 * Reusable overlay patterns for darkening/lightening images and media
 */
/**
 * Apply image overlay with opacity levels
 * Creates a dark overlay element that sits on top of images
 *
 * @param {String} $overlay-class - The overlay element class name (e.g., 'inner-hero-overlay')
 * @param {String} $block-class - The block class for data attributes (null uses &)
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Carousel Mixins
 * Reusable patterns for Swiper.js carousel implementations
 *
 * Provides consistent edge padding and overflow control for carousels
 * to ensure first and last slides have proper spacing from viewport edges.
 */
/**
 * Carousel Edge Padding
 * Adds responsive padding to carousel wrapper to match inter-slide spacing.
 * This ensures first and last slides don't touch viewport edges.
 *
 * Usage:
 * .my-block[data-style="slider"] {
 *     @include carousel-edge-padding();
 * }
 */
/**
 * Carousel Edge Padding with Custom Values
 * Allows overriding the default spacing values if needed.
 *
 * @param {string} $mobile-sm - Spacing for mobile 320px (default: $spacing-4)
 * @param {string} $mobile-lg - Spacing for mobile 480px (default: $spacing-5)
 * @param {string} $tablet - Spacing for tablet 768px (default: $spacing-6)
 * @param {string} $desktop - Spacing for desktop 1024px (default: $spacing-8)
 *
 * Usage:
 * .my-special-carousel {
 *     @include carousel-edge-padding-custom($spacing-3, $spacing-4, $spacing-5, $spacing-6);
 * }
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Artwork Card Component
 * Ported from ARTBID design system: artist-archive-block
 * Source: /Users/user/Dev/nextjs/artbid-system/src/assets/css/main.css (lines 10120-10195)
 */
/* ============================================
   GRID
   Responsive: 1 → 2 → 3 → 4 columns
   ============================================ */
/* ============================================
   IN-CONTEXT HOVER SWAP (MEDIA-2 ruling): the room shot (rendered only when
   the card opts in with show_context_hover AND the work has one) is a
   full-bleed cover that fades in OVER the letterboxed artwork. No room shot,
   no motion. Current Auction's slider and Artist Artworks share it.
   ============================================ */
/* ============================================
   CARD WRAPPER (LINK)
   Design System: @apply block; @apply focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-black; border-radius: var(--radius-brand);
   ============================================ */
.artwork-card {
  display: block;
  text-decoration: none;
  color: inherit;
  border-radius: 0;
  box-sizing: border-box;
}
.artwork-card:focus-visible {
  outline: var(--spacing-scale-0) 0.5 solid var(--color-base-black);
  outline-offset: var(--spacing-scale-0) 0.5;
}

/* ============================================
   INNER WRAPPER
   Design System: @apply block;
   ============================================ */
.artwork-card-inner {
  display: block;
  box-sizing: border-box;
}

/* ============================================
   IMAGE WRAPPER - Tan Matte Background
   Design System:
     background-color: var(--color-tan);
     @apply relative w-full;
     aspect-ratio: 3/4;
     @apply p-4 md:p-6;
     @apply overflow-hidden;
     @apply flex items-center justify-center;
     border-radius: var(--radius-brand);
     @apply mb-4;
   ============================================ */
.artwork-card-image-wrapper {
  background-color: var(--color-warm-300);
  position: relative;
  width: 100%;
  aspect-ratio: 3/4;
  padding: var(--spacing-scale-4);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0;
  margin-bottom: var(--spacing-scale-2);
  box-sizing: border-box;
}
@media (min-width: 768px) {
  .artwork-card-image-wrapper {
    padding: var(--spacing-scale-6);
  }
}

/* ============================================
   IMAGE
   Design System: @apply w-full h-full object-contain;
   WordPress: object-fit: contain maintains natural aspect ratio
   ============================================ */
.artwork-card-image {
  position: absolute;
  inset: 0;
  margin: auto;
  max-width: calc(100% - var(--spacing-scale-4) * 2);
  max-height: calc(100% - var(--spacing-scale-4) * 2);
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}
@media (min-width: 768px) {
  .artwork-card-image {
    max-width: calc(100% - var(--spacing-scale-6) * 2);
    max-height: calc(100% - var(--spacing-scale-6) * 2);
  }
}

/* ============================================
   IMAGE PLACEHOLDER
   ============================================ */
.artwork-card-image-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-gray-100);
  color: var(--color-gray-400);
}
.artwork-card-image-placeholder svg {
  width: var(--spacing-scale-12);
  height: var(--spacing-scale-12);
}

/* ============================================
   INFO CONTAINER (Flex container for details + badge)
   Design System: @apply flex items-start justify-between gap-4;
   ============================================ */
.artwork-card-info {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--spacing-scale-4);
}

/* ============================================
   DETAILS (Text content area)
   Design System: @apply flex-1;
   ============================================ */
.artwork-card-details {
  flex: 1;
}

/* ============================================
   TITLE
   Design System:
     @apply text-base font-medium mb-1;
     font-style: italic;
   ============================================ */
.artwork-card-title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-normal);
  margin-bottom: var(--spacing-scale-1);
  font-style: italic;
  line-height: 1.4;
  color: var(--color-gray-900);
}

/* ============================================
   YEAR (Inline with title)
   ============================================ */
.artwork-card-year {
  font-weight: var(--font-weight-normal);
  font-style: normal;
}

/* ============================================
   ARTIST (for auction context)
   ============================================ */
.artwork-card-artist {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-normal);
  color: var(--color-gray-700);
  margin-bottom: var(--spacing-scale-1);
  line-height: 1.4;
}

/* ============================================
   META (Year, Medium)
   Design System: @apply text-sm text-gray-600 mb-1;
   ============================================ */
.artwork-card-meta {
  font-size: var(--font-size-sm);
  color: var(--color-gray-600);
  margin-bottom: var(--spacing-scale-1);
  line-height: 1.5;
}

/* ============================================
   DIMENSIONS
   Design System: @apply text-sm text-gray-500;
   ============================================ */
.artwork-card-dimensions {
  font-size: var(--font-size-sm);
  color: var(--color-gray-500);
  margin: 0;
  line-height: 1.5;
}

/* ============================================
   BADGE (Sold badge on the right)
   Artist artworks context: Just bold text "Sold"
   Other contexts: Background box (preserved for backwards compatibility)
   ============================================ */
.artwork-card-badge {
  display: inline-block;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-gray-900);
  flex-shrink: 0;
  align-self: flex-start;
}
.artwork-card-badge.artwork-card-badge--box {
  padding: var(--spacing-scale-1) var(--spacing-scale-3);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-normal);
  background-color: var(--color-gray-100);
  color: var(--color-gray-700);
  border-radius: 0;
}

/* ============================================
   PRICE
   ============================================ */
.artwork-card-price {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  color: var(--color-gray-900);
  margin-top: var(--spacing-scale-2);
}

/* ============================================
   OVERLAY (for masonry view)
   Default: hidden everywhere except in masonry view
   ============================================ */
.artwork-card-overlay {
  display: none;
}

/* ============================================
   AUCTION CONTEXT VARIANT
   ============================================ */
[data-context=artist] .artwork-card-artist {
  display: none;
}

[data-context=auction] .artwork-card-title {
  font-style: normal;
}

[data-context=auction] .artwork-card-badge {
  display: none;
}

[data-context=auction] .artwork-card-meta,
[data-context=auction] .artwork-card-dimensions {
  display: none;
}

/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Post Card Component (Journal Card)
 * Converted from: assets/css/journal-archive.css
 * Used by: Latest Posts block, Archive templates, Blog pages
 *
 * Structure:
 * .post-card (or .journal-card) - Article wrapper
 *   .post-card-image - Featured image (4:3 aspect ratio)
 *   .post-card-content - Content wrapper
 *     .post-card-meta - Date + Category
 *       .post-card-date
 *       .post-card-category
 *     .post-card-title - H3 title with display font
 *     .post-card-excerpt - Excerpt text
 *     .post-card-cta - "Read more" link
 */
/* ============================================
   GRID MIXIN
   Responsive: 1 → 2 → 3 columns
   ============================================ */
/* ============================================
   CARD WRAPPER
   ============================================ */
.post-card,
.journal-card {
  display: block;
  overflow: hidden;
  cursor: pointer;
  opacity: 1;
  transition: opacity 0.2s ease-in-out, transform 0.2s ease-out;
}
.post-card a,
.journal-card a {
  position: relative;
  z-index: 1;
}
.post-card:focus-within,
.journal-card:focus-within {
  outline: 2px solid var(--color-base-black);
  outline-offset: var(--spacing-scale-1);
  border-radius: 0;
}
.post-card[style*="display: none"],
.journal-card[style*="display: none"] {
  display: none !important;
}

/* ============================================
   CARD IMAGE
   4:3 aspect ratio with gray background
   ============================================ */
.post-card-image,
.journal-card-image,
.post-card .wp-block-post-featured-image,
.journal-card .wp-block-post-featured-image {
  width: 100%;
  margin-bottom: 0;
  display: block;
  background-color: var(--color-gray-100);
  overflow: hidden;
  position: relative;
  aspect-ratio: 1/1;
  border-radius: 0;
}
.post-card-image img,
.journal-card-image img,
.post-card .wp-block-post-featured-image img,
.journal-card .wp-block-post-featured-image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  max-width: none;
}

/* ============================================
   CARD CONTENT
   Gap between elements: 0.75rem
   ============================================ */
.post-card-content,
.journal-card-content {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-scale-3);
  padding-top: var(--spacing-scale-2);
}

/* ============================================
   META: Date & Category
   ============================================ */
.post-card-meta,
.journal-card-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-scale-4);
  font-size: var(--font-size-xs);
  margin: 0;
}

.post-card-date,
.journal-card-date,
.post-card .wp-block-post-date,
.journal-card .wp-block-post-date {
  color: var(--color-gray-600);
  font-size: var(--font-size-xs);
}

.post-card-category,
.journal-card-category,
.post-card .wp-block-post-terms,
.journal-card .wp-block-post-terms {
  color: var(--color-gray-600);
  text-transform: uppercase;
  letter-spacing: var(--font-letterSpacing-wider);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-normal);
}
.post-card-category a,
.journal-card-category a,
.post-card .wp-block-post-terms a,
.journal-card .wp-block-post-terms a {
  color: inherit;
  text-decoration: none;
}

.post-card .wp-block-post-terms__separator,
.journal-card .wp-block-post-terms__separator {
  display: none;
}

/* ============================================
   TITLE
   Display font, responsive sizing
   ============================================ */
.post-card-title,
.journal-card-title,
.post-card .wp-block-post-title,
.journal-card .wp-block-post-title,
.post-card h3,
.journal-card h3,
.post-card .wp-block-post-title a,
.journal-card .wp-block-post-title a {
  font-family: var(--font-family-display);
  font-size: var(--font-size-xl);
  line-height: var(--font-lineHeight-tight);
  margin: 0;
  color: var(--color-base-black);
  font-weight: var(--font-weight-normal);
}
@media (min-width: 768px) {
  .post-card-title,
  .journal-card-title,
  .post-card .wp-block-post-title,
  .journal-card .wp-block-post-title,
  .post-card h3,
  .journal-card h3,
  .post-card .wp-block-post-title a,
  .journal-card .wp-block-post-title a {
    font-size: var(--font-size-2xl);
  }
}

.post-card-title a,
.journal-card-title a,
.post-card .wp-block-post-title a,
.journal-card .wp-block-post-title a {
  color: inherit;
  text-decoration: none;
  font-family: inherit;
}
.post-card-title a:hover,
.journal-card-title a:hover,
.post-card .wp-block-post-title a:hover,
.journal-card .wp-block-post-title a:hover {
  color: var(--color-gray-700);
}

/* ============================================
   EXCERPT
   Clamped to 3 lines
   ============================================ */
.post-card-excerpt,
.journal-card-excerpt,
.post-card .wp-block-post-excerpt,
.journal-card .wp-block-post-excerpt {
  font-size: var(--font-size-sm);
  line-height: var(--font-lineHeight-relaxed);
  color: var(--color-gray-600);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (min-width: 768px) {
  .post-card-excerpt,
  .journal-card-excerpt,
  .post-card .wp-block-post-excerpt,
  .journal-card .wp-block-post-excerpt {
    font-size: var(--font-size-base);
  }
}

.post-card .wp-block-post-excerpt__more-link,
.journal-card .wp-block-post-excerpt__more-link {
  display: none;
}

/* ============================================
   READ MORE CTA
   Underlined link that removes underline on hover
   ============================================ */
.post-card-cta-wrapper,
.journal-card-cta-wrapper {
  margin: 0;
}

.post-card-cta,
.journal-card-cta,
.post-card .wp-block-read-more,
.journal-card .wp-block-read-more {
  display: inline-block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-normal);
  color: var(--color-base-black);
  text-decoration: underline;
  transition: text-decoration 0.2s ease-in-out;
}
.post-card-cta:hover,
.journal-card-cta:hover,
.post-card .wp-block-read-more:hover,
.journal-card .wp-block-read-more:hover {
  text-decoration: none;
}

.post-card:hover .post-card-cta,
.journal-card:hover .journal-card-cta,
.post-card:hover .wp-block-read-more,
.journal-card:hover .wp-block-read-more {
  text-decoration: none;
}

/* ============================================
   SCREEN READER TEXT
   For accessible card links
   ============================================ */
.post-card-link,
.journal-card-link {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

/* ============================================
   JOURNAL CARD — Yael's page notes (2026-10-05; artbid-v2
   design-token-index.md §6 J3 · J7 · J8). This SAME block closes
   blocks/_shared/components/_post-card.scss (the Latest Posts block) and the
   card copy inlined in assets/css/journal-archive.css (G19) — keep the two
   identical until the card has one source.
   ============================================ */
/* J3: the type on the LEFT, the date on the RIGHT (the markup keeps the date
   first; `order` moves the type ahead in the space-between row). */
.post-card-category,
.journal-card-category,
.post-card .wp-block-post-terms,
.journal-card .wp-block-post-terms {
  order: -1;
}

/* J7: the title = --font-size-xl at every width (24 desktop, 20 phone), two
   lines at most. */
/* `.post-card h3` / `.journal-card h3` are listed too: the base rule above
   names them, and a class + a tag outranks the class alone — the block's card
   title stayed on the old 2xl step from 768 up (30.5 at 1440 beside the
   journal's 24) until 2026-10-13. */
.post-card-title,
.journal-card-title,
.post-card h3,
.journal-card h3,
.post-card .wp-block-post-title,
.journal-card .wp-block-post-title {
  font-size: var(--font-size-xl);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.post-card .wp-block-post-title a,
.journal-card .wp-block-post-title a {
  font-size: inherit;
  display: inline; /* an inline-block link is one atomic box — the clamp can't cut inside it */
}

/* J7: the excerpt = --font-size-sm at every width, five lines at most. */
.post-card-excerpt,
.journal-card-excerpt,
.post-card .wp-block-post-excerpt,
.journal-card .wp-block-post-excerpt {
  font-size: var(--font-size-sm);
  -webkit-line-clamp: 5;
  line-clamp: 5;
}

/* The card owns its own gaps (the content's flex gap). Inside page content the
   prose rhythm (`.wp-block-post-content h3 + *`) added a paragraph gap under
   the title: 28 where /journal/ has 12. */
.post-card .post-card-content > *,
.journal-card .journal-card-content > * {
  margin-top: 0;
  margin-bottom: 0;
}

/* J8: "Read more" = the main nav's line, exactly (header-footer.css
   .header-nav-link::after): no line at rest; hovering or focusing THE LINK
   draws a 1px currentColor line in from the left, --transition-duration-300
   ease-out; no animation under prefers-reduced-motion. Hovering ANYWHERE on
   the card draws it too — the card is one clickable unit (Chuck 2026-10-05). */
.post-card-cta,
.journal-card-cta,
.post-card .wp-block-read-more,
.journal-card .wp-block-read-more {
  position: relative;
  text-decoration: none;
  /* the line lives INSIDE the link's box (as the nav's does): the card clips
     its overflow and the link is its last element, so a line drawn below the
     box was cut off (Chuck's walk, 2026-10-05). */
  padding-bottom: calc(var(--spacing-scale-0_5) + var(--border-width-1));
  /* shrink to the words: the card content is a flex column that stretches its
     children, so the link (and the line inside it) ran the card's full width
     (Chuck 2026-10-06). */
  align-self: flex-start;
}

.post-card-cta::after,
.journal-card-cta::after,
.post-card .wp-block-read-more::after,
.journal-card .wp-block-read-more::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--border-width-1);
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--transition-duration-300) var(--transition-timing-ease-out);
}

.post-card:hover .post-card-cta::after,
.journal-card:hover .journal-card-cta::after,
.post-card:hover .wp-block-read-more::after,
.journal-card:hover .wp-block-read-more::after,
.post-card-cta:hover::after,
.journal-card-cta:hover::after,
.post-card .wp-block-read-more:hover::after,
.journal-card .wp-block-read-more:hover::after,
.post-card-cta:focus-visible::after,
.journal-card-cta:focus-visible::after,
.post-card .wp-block-read-more:focus-visible::after,
.journal-card .wp-block-read-more:focus-visible::after {
  transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
  .post-card-cta::after,
  .journal-card-cta::after,
  .post-card .wp-block-read-more::after,
  .journal-card .wp-block-read-more::after {
    transition: none;
  }
}
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Carousel Component - Shared Swiper.js Carousel Styles
 *
 * Used by: Current Auction slider, Artist slider (future)
 * Based on artbid-system carousel patterns
 *
 * Features:
 * - Variable-width slides on desktop (based on image aspect ratio)
 * - Snap scrolling on mobile for better UX
 * - Universal navigation (dots + arrows)
 * - Light/dark theme support
 */
/* ============================================
   CAROUSEL UNIVERSAL NAVIGATION
   Reusable pagination dots and arrow buttons
   ============================================ */
/* Pagination dots container */
.carousel-pagination {
  display: flex;
  gap: var(--spacing-scale-2);
}

/* Individual pagination bullet (inactive - outline only) */
.carousel-pagination-bullet {
  width: var(--spacing-scale-2);
  height: var(--spacing-scale-2);
  border-radius: 50%;
  transition: all 0.2s;
  cursor: pointer;
  background: transparent;
}

/* Active pagination bullet (filled circle, same size) */
.carousel-pagination-bullet-active {
  /* No size change - stays circular */
}

/* Light theme bullets (for dark backgrounds) */
.carousel-pagination--light .carousel-pagination-bullet {
  border: 1px solid rgba(255, 255, 255, 0.6);
}
.carousel-pagination--light .carousel-pagination-bullet:hover {
  border-color: rgba(255, 255, 255, 0.8);
}

.carousel-pagination--light .carousel-pagination-bullet-active {
  background: var(--color-base-white);
  border-color: var(--color-base-white);
}

/* Dark theme bullets (for light backgrounds) — 1px solid black ring
   (2026-07-18 ruling, matches the app's related-lots dots) */
.carousel-pagination--dark .carousel-pagination-bullet {
  border: 1px solid var(--color-base-black);
}

.carousel-pagination--dark .carousel-pagination-bullet-active {
  background: var(--color-base-black);
  border-color: var(--color-base-black);
}

/* Navigation arrows — bare mitered chevrons, lightbox parity
   (Chuck's ruling 2026-07-18: no circles or boxes anywhere; the glyph
   is the lightbox cut scaled to nav size, 23:41 ratio). The 40px hit
   target stays. Inline <svg> chevrons at every render site are retired
   by CSS (display:none) — direction rides the aria-label
   ("Previous…" / "Next…") every site already carries. Theme variants
   (--dark/--light) now set glyph color only. Mirror of nextjs-system
   main.css @spec-section: carousel-arrows — keep the two in step. */
.carousel-arrow {
  width: var(--spacing-scale-10);
  height: var(--spacing-scale-10);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.2s;
}
.carousel-arrow:focus-visible {
  outline: 2px solid var(--color-base-black);
  outline-offset: 2px;
}
.carousel-arrow:hover:not(:disabled) {
  opacity: 1;
}
.carousel-arrow:disabled {
  opacity: 0.25;
  cursor: not-allowed;
}
.carousel-arrow svg {
  display: none;
}
.carousel-arrow {
  /* Default glyph = next (right); Previous overrides below */
}
.carousel-arrow::before {
  content: "";
  display: block;
  width: 14px;
  height: 25px;
  background-color: currentColor;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='46' height='82' viewBox='0 0 46 82' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0L45.1025 39H32L0 12V0Z' fill='black'/%3E%3Cpath d='M0 82L45.1025 43H32L0 70V82Z' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg width='46' height='82' viewBox='0 0 46 82' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0L45.1025 39H32L0 12V0Z' fill='black'/%3E%3Cpath d='M0 82L45.1025 43H32L0 70V82Z' fill='black'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}
.carousel-arrow[aria-label^=Prev]::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='46' height='82' viewBox='0 0 46 82' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M45.1025 0L0 39H13.1025L45.1025 12V0Z' fill='black'/%3E%3Cpath d='M45.1025 82L0 43H13.1025L45.1025 70V82Z' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg width='46' height='82' viewBox='0 0 46 82' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M45.1025 0L0 39H13.1025L45.1025 12V0Z' fill='black'/%3E%3Cpath d='M45.1025 82L0 43H13.1025L45.1025 70V82Z' fill='black'/%3E%3C/svg%3E");
}

/* Light theme arrows (for dark backgrounds) — glyph color only */
.carousel-arrow--light {
  color: var(--color-base-white);
}

/* Dark theme arrows (for light backgrounds) — glyph color only */
.carousel-arrow--dark {
  color: var(--color-base-black);
}

/* ============================================
   ARTWORK CAROUSEL
   For current auction slider and artist slider
   ============================================ */
.artwork-carousel-heading {
  font-family: var(--font-family-display);
  font-size: var(--font-size-3xl);
  margin-bottom: 0;
}
.artwork-carousel-heading--left {
  text-align: left;
}
.artwork-carousel-heading--center {
  text-align: center;
}
.artwork-carousel-heading--right {
  text-align: right;
}
.artwork-carousel-heading--2xl {
  font-size: var(--font-size-2xl);
}
.artwork-carousel-heading--3xl {
  font-size: var(--font-size-3xl);
}
.artwork-carousel-heading--4xl {
  font-size: var(--font-size-4xl);
}
.artwork-carousel-heading--5xl {
  font-size: var(--font-size-5xl);
}
.artwork-carousel-heading--6xl {
  font-size: var(--font-size-6xl);
}
.artwork-carousel-heading--7xl {
  font-size: var(--font-size-7xl);
}
.artwork-carousel-heading--sm {
  font-size: var(--font-size-3xl);
}
.artwork-carousel-heading--md {
  font-size: var(--font-size-4xl);
}
.artwork-carousel-heading--lg {
  font-size: var(--font-size-5xl);
}
.artwork-carousel-heading--xl {
  font-size: var(--font-size-6xl);
}

/* Subheading under the heading (Yael 2026-09-14, punchlist #13): body-size,
   quieter colour, follows the heading's alignment. */
.artwork-carousel-subheading {
  margin: var(--spacing-scale-2) 0 0;
  font-size: var(--font-size-base);
  color: var(--color-gray-700);
}
.artwork-carousel-subheading--left {
  text-align: left;
}
.artwork-carousel-subheading--center {
  text-align: center;
}
.artwork-carousel-subheading--right {
  text-align: right;
}

.artwork-carousel-wrapper {
  position: relative;
  margin-top: var(--spacing-scale-6);
  margin-bottom: clamp(1.5rem, 1.2rem + 1vw, 2.5rem);
}

.artwork-carousel-swiper {
  overflow: visible;
}

.artwork-carousel-slide {
  height: auto;
  /* Width controlled by Swiper configuration and card content */
}

/* Navigation wrapper: CTA button + dots/arrows */
.artwork-carousel-nav-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  margin-top: var(--spacing-scale-4);
}

/* CTA Button - centered on page */
.artwork-carousel-cta {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

/* Navigation container — dots bottom-LEFT, arrows right (Chuck
   2026-07-18: parity with the app's related-lots carousel nav) */
.artwork-carousel-nav {
  display: flex;
  align-items: center;
  gap: var(--spacing-scale-4);
  width: 100%;
}

/* Pagination dots — left edge; arrows push to the right */
.artwork-carousel-pagination,
[class*=artwork-carousel-pagination-] {
  position: static !important;
  width: auto !important;
  flex: 1;
  display: flex !important;
  justify-content: flex-start;
}

/* Arrow buttons - no additional styles needed, inherit from .carousel-arrow--dark */
.artwork-carousel-prev,
.artwork-carousel-next {
  /* Inherits from .carousel-arrow--dark */
}

/* ============================================
   NAV POSITION MODEL (shared, 2026-08-17)
   Show/hide + position for DOTS (left/center/right) and ARROWS (left/right).
   Used by current-auction + artist-slider — both @use this partial.

   WHY GRID: the rules above give .artwork-carousel-pagination
   `position:static !important; flex:1; justify-content:flex-start`. A flex
   auto-margin "centre" only centres within the space LEFT BY the arrows (reads
   off-centre), and a `position:absolute` centre is beaten by `position:static
   !important`. Making .artwork-carousel-nav a GRID sidesteps all of it: a grid
   item ignores `flex:1`, wants `position:static`, and the middle `auto` column
   of `1fr auto 1fr` is TRUE-centred between two equal tracks regardless of the
   arrows' width. Grid placement (grid-column/justify-self) uses properties the
   !important rules never touch, so we need no !important of our own.

   Activated only when .artwork-carousel-nav carries the position data-attrs
   (both carousel blocks emit them); other carousels are unaffected.
   ============================================ */
.artwork-carousel-nav[data-dots-position] {
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* left | centre | right */
  align-items: center;
  gap: var(--spacing-scale-4);
  width: 100%;
  /* DOTS → cell by position. flex:1 is inert on a grid item; the dots stay an
     internal flex row (shared rule), we only place the group. */
}
.artwork-carousel-nav[data-dots-position][data-dots-position=left] .artwork-carousel-pagination {
  grid-column: 1;
  justify-self: start;
}
.artwork-carousel-nav[data-dots-position][data-dots-position=center] .artwork-carousel-pagination {
  grid-column: 2;
  justify-self: center;
}
.artwork-carousel-nav[data-dots-position][data-dots-position=right] .artwork-carousel-pagination {
  grid-column: 3;
  justify-self: end;
}
.artwork-carousel-nav[data-dots-position] {
  /* ARROWS → left or right cell only (no centre). */
}
.artwork-carousel-nav[data-dots-position] .artwork-carousel-nav-arrows {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-scale-2);
}
.artwork-carousel-nav[data-dots-position][data-arrows-position=left] .artwork-carousel-nav-arrows {
  grid-column: 1;
  justify-self: start;
}
.artwork-carousel-nav[data-dots-position][data-arrows-position=right] .artwork-carousel-nav-arrows {
  grid-column: 3;
  justify-self: end;
}

/* ARROWS AT THE SIDES (Chuck 2026-10-29, Artist Slider card) — over the
   far-left and far-right images, at the picture's middle. carousel-init.js
   measures that middle into --sides-top on the nav wrapper (the nav keeps its
   place in the markup, so the dots still centre in the row). Over a photo the
   arrows are the bare white symbol with a soft shadow, as the video bar. From
   md up; phones keep the row (the phone rule below). */
@media (min-width: 768px) {
  .artwork-carousel-nav-wrapper:has(.artwork-carousel-nav[data-arrows-position=sides]) {
    position: relative;
  }
  .artwork-carousel-nav[data-arrows-position=sides] .artwork-carousel-nav-arrows {
    position: absolute;
    left: 0;
    right: 0;
    top: var(--sides-top, 0);
    z-index: 2;
    display: flex;
    justify-content: space-between;
    padding: 0 var(--spacing-scale-2);
    transform: translateY(-50%);
    pointer-events: none;
  }
  .artwork-carousel-nav[data-arrows-position=sides] .artwork-carousel-nav-arrows .carousel-arrow {
    pointer-events: auto;
    color: var(--color-base-white);
    filter: drop-shadow(0 0 var(--spacing-scale-1) color-mix(in srgb, var(--color-base-black) 50%, transparent));
  }
  .artwork-carousel-nav-wrapper:not([style*="--sides-top"]) .artwork-carousel-nav[data-arrows-position=sides] .artwork-carousel-nav-arrows {
    visibility: hidden;
  }
}
/* SHARED ZONE — dots and arrows shown AND at the same position. One justified
   flex row, dots then arrows (source order = the "dots always left of arrows"
   tie-breaker), gap between, never overlapping. Overrides the grid above. */
.artwork-carousel-nav.is-shared-zone {
  display: flex;
  align-items: center;
  gap: var(--spacing-scale-3);
}
.artwork-carousel-nav.is-shared-zone .artwork-carousel-pagination {
  flex: 0 0 auto !important;
}
.artwork-carousel-nav.is-shared-zone[data-dots-position=left] {
  justify-content: flex-start;
}
.artwork-carousel-nav.is-shared-zone[data-dots-position=right] {
  justify-content: flex-end;
}

/* PHONE (<768px, tablets ≥768px unaffected): the nav row can't hold dots +
   arrows + a button on one line, so we FORCE a single sensible layout and stop
   honouring the desktop position choices:
     • nav row is always dots-left / arrows-right (override the grid placement),
     • the button drops to its OWN full-width line BELOW the row.
   `full-width` is scoped to phone only — at tablet+ the button keeps its natural
   content width and the designer's chosen position (the --button-* rules above).
   $breakpoint-md is 768px, so `max-width:767px` is exactly the phone edge. */
@media (max-width: 767px) {
  .artwork-carousel-nav[data-dots-position] {
    gap: var(--spacing-scale-2);
    grid-template-columns: 1fr auto;
  }
  .artwork-carousel-nav[data-dots-position] .artwork-carousel-pagination {
    grid-column: 1 !important;
    justify-self: start !important;
  }
  .artwork-carousel-nav[data-dots-position] .artwork-carousel-nav-arrows {
    grid-column: 2 !important;
    justify-self: end !important;
  }
  .artwork-carousel-nav.is-shared-zone {
    justify-content: flex-start;
  }
  .artwork-carousel-nav-wrapper--with-button {
    flex-direction: column;
    align-items: stretch;
    gap: var(--spacing-scale-3);
  }
  .artwork-carousel-nav-wrapper--with-button .artwork-carousel-nav {
    order: 0;
  }
  .artwork-carousel-nav-wrapper--with-button .artwork-carousel-cta-button,
  .artwork-carousel-nav-wrapper--with-button .artist-slider-button {
    position: static !important;
    left: auto !important;
    transform: none !important;
    order: 1;
    width: 100%;
  }
  .artwork-carousel-nav-wrapper--with-button .artwork-carousel-cta-button .btn,
  .artwork-carousel-nav-wrapper--with-button .artist-slider-button .btn {
    width: 100%;
  }
  .artwork-carousel-nav-wrapper--button-center .artwork-carousel-nav {
    margin-left: 0;
  }
}
/* ============================================
   NAV CTA BUTTON (shared, 2026-08-17)
   An optional button that lives in the nav-wrapper beside the dots/arrows row.
   Ported from artist-slider so current-auction can share it. The wrapper gets
   `--with-button` + `--button-{align}`; the button itself is
   `.artwork-carousel-cta-button` (artist-slider's legacy `.artist-slider-button`
   is aliased below until it migrates). Button visual = the shared `.btn` classes.
   ============================================ */
.artwork-carousel-nav-wrapper--with-button {
  display: flex;
  align-items: center;
  position: relative;
}

.artwork-carousel-cta-button,
.artist-slider-button { /* legacy alias — remove once artist-slider migrates */
  display: inline-flex;
}
.artwork-carousel-cta-button .btn,
.artist-slider-button .btn {
  width: auto;
  white-space: nowrap;
}

/* Left: button left, nav row pushed right. */
.artwork-carousel-nav-wrapper--button-left {
  justify-content: space-between;
}

/* Centre: button absolutely centred, nav row stays right. */
.artwork-carousel-nav-wrapper--button-center .artwork-carousel-cta-button,
.artwork-carousel-nav-wrapper--button-center .artist-slider-button {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
.artwork-carousel-nav-wrapper--button-center .artwork-carousel-nav {
  margin-left: auto;
}

/* ============================================
   THE CAROUSEL SHELL (2026-10-06; inc/helpers/carousel-helpers.php,
   artbid-v2 design-token-index.md §6.1 J2)
   "N cells in view". The GAP is a token, set here and nowhere else — the
   script measures it through the probe (no px in JS). Cells per view ride
   on the root as custom properties from the emitter.
   Before Swiper starts (and always in the editor, where it never starts) the
   track lays out the cells with the same geometry; Swiper's own inline
   widths/margins take over once it adds .swiper-initialized.
   The nav reuses the shared dots/arrows/nav-position rules above.
   ============================================ */
.artbid-carousel {
  --artbid-carousel-gap: var(--spacing-scale-4);
  --artbid-carousel-cells: var(--artbid-carousel-cells-phone, 2);
  position: relative;
  min-width: 0;
}
@media (min-width: 768px) {
  .artbid-carousel {
    --artbid-carousel-cells: var(--artbid-carousel-cells-desktop, 3);
  }
}

.artbid-carousel-gap-probe {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--artbid-carousel-gap);
  height: 0;
  visibility: hidden;
  pointer-events: none;
}

.artbid-carousel-track {
  overflow: hidden;
}

.artbid-carousel-track:not(.swiper-initialized) > .swiper-wrapper {
  display: flex;
  gap: var(--artbid-carousel-gap);
}

.artbid-carousel-track:not(.swiper-initialized) .artbid-carousel-slide {
  flex: 0 0 calc((100% - (var(--artbid-carousel-cells) - 1) * var(--artbid-carousel-gap)) / var(--artbid-carousel-cells));
  min-width: 0;
}

.artbid-carousel-slide {
  height: auto;
}

/* Fewer cells than fit in view: nothing to scroll — no dots, no arrows. */
.artbid-carousel.is-locked .artbid-carousel-nav-wrapper {
  display: none;
}

/* Before the script decides, keep the nav's space but hide its controls
   (no flash of arrows on a carousel that turns out to be locked). */
.artbid-carousel:not(.is-ready) .artbid-carousel-nav-wrapper {
  visibility: hidden;
}

/* The shell's 'single' and 'marquee' modes (2026-10-19, the Image Slider).
   'single' lays out like one cell; 'marquee' lets every slide keep its own
   width and moves the wrapper linearly. The pause button (anything that moves
   by itself) is the bare symbol beside the dots, black on the page. */
.artbid-carousel[data-mode=single] {
  --artbid-carousel-cells: 1;
  --artbid-carousel-slide-duration: var(--transition-duration-500);
}
@media (min-width: 768px) {
  .artbid-carousel[data-mode=single] {
    --artbid-carousel-slide-duration: var(--transition-duration-700);
  }
}
.artbid-carousel[data-mode=single] .swiper-wrapper {
  transition-timing-function: var(--transition-timing-ease-in-out);
}
@media (prefers-reduced-motion: reduce) {
  .artbid-carousel[data-mode=single] {
    --artbid-carousel-slide-duration: 0ms;
  }
}

.artbid-carousel[data-mode=marquee] .artbid-carousel-slide,
.artbid-carousel[data-mode=marquee] .artbid-carousel-track:not(.swiper-initialized) .artbid-carousel-slide {
  flex: 0 0 auto;
  width: auto;
}
.artbid-carousel[data-mode=marquee].is-strip {
  position: relative;
}
.artbid-carousel[data-mode=marquee].is-strip .swiper-wrapper {
  display: flex;
  gap: 0;
  width: max-content;
  animation: artbid-strip var(--strip-duration, 60s) linear infinite;
}
.artbid-carousel[data-mode=marquee].is-strip .artbid-carousel-slide {
  margin-right: var(--strip-gap, 0);
}
.artbid-carousel[data-mode=marquee].is-strip.is-paused .swiper-wrapper, .artbid-carousel[data-mode=marquee].is-strip:hover .swiper-wrapper, .artbid-carousel[data-mode=marquee].is-strip:focus-within .swiper-wrapper {
  animation-play-state: paused;
}
.artbid-carousel[data-mode=marquee] .artbid-carousel-pause {
  position: absolute;
  left: var(--spacing-scale-4);
  top: calc(var(--strip-pause-bottom, 100%) - var(--spacing-scale-4));
  z-index: 1;
  transform: translateY(-100%);
  color: var(--color-base-white);
  filter: drop-shadow(0 0 var(--spacing-scale-1) rgba(0, 0, 0, 0.5));
  transition: opacity var(--transition-duration-300) var(--transition-timing-ease-out);
}
.artbid-carousel[data-mode=marquee] .artbid-carousel-pause:focus-visible {
  outline-color: var(--color-base-white);
}
@media (hover: hover) and (pointer: fine) {
  .artbid-carousel[data-mode=marquee]:not(.is-paused) .artbid-carousel-pause {
    opacity: 0;
  }
  .artbid-carousel[data-mode=marquee]:hover .artbid-carousel-pause,
  .artbid-carousel[data-mode=marquee] .artbid-carousel-pause:focus-visible {
    opacity: 1;
  }
}
.artbid-carousel[data-mode=marquee]:not(.is-strip) .artbid-carousel-pause, .artbid-carousel[data-mode=marquee].is-locked .artbid-carousel-pause {
  display: none;
}

@keyframes artbid-strip {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(var(--strip-shift, -50%));
  }
}
@media (prefers-reduced-motion: reduce) {
  .artbid-carousel[data-mode=marquee] .artbid-carousel-pause {
    transition: none;
  }
}
.artbid-carousel-nav-start {
  display: flex;
  align-items: center;
  gap: var(--spacing-scale-2);
}

.artbid-carousel-pause {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--spacing-scale-8);
  height: var(--spacing-scale-8);
  padding: 0;
  color: var(--color-base-black);
  background: none;
  border: 0;
  cursor: pointer;
}
@media (pointer: coarse) {
  .artbid-carousel-pause {
    width: var(--button-height-md);
    height: var(--button-height-md);
  }
}
.artbid-carousel-pause svg {
  width: var(--spacing-scale-4);
  height: var(--spacing-scale-4);
}
.artbid-carousel-pause:focus-visible {
  outline: var(--border-width-2) solid var(--color-base-black);
  outline-offset: var(--border-width-2);
}
.artbid-carousel-pause .artbid-carousel-play-icon {
  display: none;
}

.artbid-carousel.is-paused .artbid-carousel-pause .artbid-carousel-pause-icon {
  display: none;
}
.artbid-carousel.is-paused .artbid-carousel-pause .artbid-carousel-play-icon {
  display: block;
}

/**
 * THE AMBIENT VIDEO TOGGLE — one source (2026-10-19, Lane 29). The pause /
 * play button on every silent looping video: Content Video (Ambient), an
 * Image Card and the Image & Text media cell. Markup:
 * artbid_ambient_toggle_html() (inc/helpers/ambient-video.php); script:
 * assets/js/content-video.js (adds .is-playing to the root).
 *
 * THE BARE GLYPH (Yael, card 66; Chuck 2026-10-16): no circle, just the
 * symbol, as the carousel arrows (no circles or boxes anywhere, 07-18). The
 * hit area stays (32, 44 on touch); a soft shadow keeps a white glyph readable
 * on light footage (no glyph-shadow token yet — design-token-index §2.2 gap).
 * Hidden while it plays until hover / focus (a mouse); paused, focused or on a
 * touch screen it stays in view, so play is always findable.
 *
 * @param $root  The element that carries .is-playing.
 * @param $z     Its stacking order inside the media box.
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * Image Block Editor Styles
 * Shared editor preview styles for all image blocks
 *
 * Usage:
 * @use '../_shared' as *;
 * @include image-block-editor-base();
 */
/**
 * Base editor styles for image blocks with object-fit modes
 * Apply to any block that uses data-object-fit and data-height attributes
 *
 * @param {String} $block-class - The block class (e.g., 'content-full-image')
 * @param {String} $figure-class - The figure class (e.g., 'content-full-image-figure')
 */
/**
 * Editor grid layouts for multi-image blocks
 *
 * @param {String} $block-class - The block class
 * @param {String} $inner-class - The inner grid container class
 */
/**
 * Shared "Remove image" button for the editor (over-image variant).
 *
 * Replaces the old inline red-text-on-transparent <Button isDestructive> that
 * was hard to see over photos. Renders as a dark, semi-transparent pill with a
 * white ✕ at rest (legible on ANY image); on hover/focus it turns red and
 * reveals a "Remove" label — unobtrusive at rest, unmistakably destructive on
 * intent. EDITOR-ONLY (this file is imported by each block's editor.scss).
 *
 * Markup contract (edit.js):
 *   <Button className="artbid-remove-image" onClick={…} isDestructive>
 *     <span class="artbid-remove-image__label">Remove</span>
 *   </Button>
 * The button must sit inside a `position: relative` parent (the image
 * container/figure it overlays) — every call site already provides one.
 */
/**
 * Media upload placeholder styling
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
/**
 * The contact form's fields (AB-171): label sm above, a white box on a
 * gray-300 hairline, gray-400 on hover, a 2px black ring on focus; errors,
 * status, the spam check, the privacy line, the honeypot, the thank-you.
 * One look for every form that posts to the contact route: the Contact Form
 * block and the Ask a Question pop-up (2026-11-09). Include it inside the
 * form's scope (the content flow resets outrank a bare class).
 */
/**
 * Shared Styles Index
 * Main entry point for all shared styles
 *
 * Usage in block styles:
 * @use '../_shared' as shared;
 *
 * .my-block {
 *   @include shared.block-container();
 * }
 */
.container {
  width: 100%;
  max-width: var(--layout-container-wide);
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--spacing-container-inline);
  padding-right: var(--spacing-container-inline);
  box-sizing: border-box;
}

[data-container=narrow] .container {
  max-width: var(--layout-container-standard);
}

[data-container=prose] .container {
  max-width: var(--layout-container-prose);
}

[data-container=ultra] .container {
  max-width: var(--layout-container-ultra);
}

/* ==========================================
   BASE CONTAINER
   ========================================== */
.content-text-block {
  position: relative;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding-top: var(--spacing-block-md);
  padding-bottom: var(--spacing-block-md);
}
.content-text-block[data-spacing=none] {
  padding-top: 0;
  padding-bottom: 0;
}
.content-text-block[data-spacing=xs] {
  padding-top: var(--spacing-block-xs);
  padding-bottom: var(--spacing-block-xs);
}
.content-text-block[data-spacing=sm] {
  padding-top: var(--spacing-block-sm);
  padding-bottom: var(--spacing-block-sm);
}
.content-text-block[data-spacing=md] {
  padding-top: var(--spacing-block-md);
  padding-bottom: var(--spacing-block-md);
}
.content-text-block[data-spacing=lg] {
  padding-top: var(--spacing-block-lg);
  padding-bottom: var(--spacing-block-lg);
}
.content-text-block[data-spacing=xl] {
  padding-top: var(--spacing-block-xl);
  padding-bottom: var(--spacing-block-xl);
}
.content-text-block[data-spacing-top=none] {
  padding-top: 0;
}
.content-text-block[data-spacing-top=xs] {
  padding-top: var(--spacing-block-xs);
}
.content-text-block[data-spacing-top=sm] {
  padding-top: var(--spacing-block-sm);
}
.content-text-block[data-spacing-top=md] {
  padding-top: var(--spacing-block-md);
}
.content-text-block[data-spacing-top=lg] {
  padding-top: var(--spacing-block-lg);
}
.content-text-block[data-spacing-top=xl] {
  padding-top: var(--spacing-block-xl);
}
.content-text-block[data-spacing-bottom=none] {
  padding-bottom: 0;
}
.content-text-block[data-spacing-bottom=xs] {
  padding-bottom: var(--spacing-block-xs);
}
.content-text-block[data-spacing-bottom=sm] {
  padding-bottom: var(--spacing-block-sm);
}
.content-text-block[data-spacing-bottom=md] {
  padding-bottom: var(--spacing-block-md);
}
.content-text-block[data-spacing-bottom=lg] {
  padding-bottom: var(--spacing-block-lg);
}
.content-text-block[data-spacing-bottom=xl] {
  padding-bottom: var(--spacing-block-xl);
}
.content-text-block .container {
  width: 100%;
  max-width: var(--layout-container-wide);
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--spacing-container-inline);
  padding-right: var(--spacing-container-inline);
  box-sizing: border-box;
}
.content-text-block[data-container=narrow] .container {
  max-width: var(--layout-container-standard);
}
.content-text-block[data-container=prose] .container {
  max-width: var(--layout-container-prose);
}
.content-text-block[data-container=ultra] .container {
  max-width: var(--layout-container-ultra);
}
.content-text-block .container {
  max-width: var(--layout-container-wide);
}

/* ==========================================
   INNER CONTAINER
   ========================================== */
.content-text-block-inner {
  margin-left: auto;
  margin-right: auto;
  box-sizing: border-box;
  overflow-x: clip;
}
.content-text-block-inner[data-width=xx-narrow] {
  max-width: var(--layout-container-prose-xx-narrow);
}
.content-text-block-inner[data-width=x-narrow] {
  max-width: var(--layout-container-prose-x-narrow);
}
.content-text-block-inner[data-width=narrow] {
  max-width: var(--layout-container-prose);
}
.content-text-block-inner[data-width=medium] {
  max-width: var(--layout-container-prose-medium);
}
.content-text-block-inner[data-width=wide] {
  max-width: var(--layout-container-prose-wide);
}
.content-text-block-inner[data-width=full] {
  max-width: var(--layout-container-wide);
}

/* ==========================================
   POSITIONING & ALIGNMENT
   ========================================== */
.content-text-block[data-block-position=center] .content-text-block-inner {
  margin-left: auto;
  margin-right: auto;
}
.content-text-block[data-block-position=left] .content-text-block-inner {
  margin-left: 0;
  margin-right: auto;
}
.content-text-block[data-block-position=right] .content-text-block-inner {
  margin-left: auto;
  margin-right: 0;
}

.content-text-block-inner[data-text-align=left] {
  text-align: left;
}
.content-text-block-inner[data-text-align=center] {
  text-align: center;
}
.content-text-block-inner[data-text-align=right] {
  text-align: right;
}
.content-text-block-inner:is([data-text-align=justify], [data-text-align=justify-center], [data-text-align=justify-right]) {
  text-align: justify;
  text-align-last: left;
  hyphens: auto;
  -webkit-hyphens: auto;
}
.content-text-block-inner:is([data-text-align=justify], [data-text-align=justify-center], [data-text-align=justify-right]) :is(.has-text-align-left, .has-text-align-center, .has-text-align-right) {
  text-align-last: auto;
}
.content-text-block-inner:is([data-text-align=justify], [data-text-align=justify-center], [data-text-align=justify-right]) :is(h1, h2, h3, h4, h5, h6) {
  text-align: left;
  text-align-last: auto;
  hyphens: manual;
  -webkit-hyphens: manual;
}
.content-text-block-inner[data-text-align=justify-center] {
  text-align-last: center;
}
.content-text-block-inner[data-text-align=justify-right] {
  text-align-last: right;
}

/* ==========================================
   TYPOGRAPHY (Text Block package, 2026-10-02 — design-token-index.md §5.4.1)
   ========================================== */
/* Headings are sized BY LEVEL ON THE BLOCK'S OWN LADDER, not the theme's tag
 * ladder (theme.json h1=5xl … h6=lg): H1/H2 `--font-size-3xl` · H3
 * `--font-size-2xl` · H4–H6 `--font-size-xl` (R4 + ruling H, Chuck 10-02).
 * The seeded `.content-text-block-heading` follows its LEVEL like any other
 * heading. An Aa Size override is an inline `font-size` (render_block filter,
 * editor-restrictions.php) and outranks all of this. */
.content-text-block :is(h1, h2, h3, h4, h5, h6),
.content-text-block .content-text-block-heading {
  font-family: var(--font-family-display);
  font-weight: var(--font-weight-normal);
  line-height: var(--line-height-heading);
  margin-top: 0;
  font-size: var(--font-size-3xl);
  margin-bottom: var(--spacing-scale-6);
}

.content-text-block :is(h3, h3.content-text-block-heading) {
  font-size: var(--font-size-2xl);
}

.content-text-block :is(h4, h5, h6, h4.content-text-block-heading, h5.content-text-block-heading, h6.content-text-block-heading) {
  font-size: var(--font-size-xl);
}

/* Running text = the site's running text (R1, Chuck 10-02: `--font-size-base`
 * for every paragraph and list). The block no longer styles the seeded
 * `.content-text-block-content` paragraph differently from one the editor adds:
 * the old `body-lg` rule on that class (lg + relaxed) made the first paragraph
 * a different size from every other (T1). Colour = the site's (black, R2; the
 * old gray-600 never won). The class stays in saved content, unstyled. */
/* ==========================================
   BACKGROUND COLORS
   ========================================== */
.content-text-block[data-bg=white] {
  background-color: var(--color-base-white);
}
.content-text-block[data-bg=white] .content-text-block-inner :not(.btn):not(.wp-block-button__link) {
  color: var(--color-base-black);
}
.content-text-block[data-bg=gray] {
  background-color: var(--color-gray-100);
}
.content-text-block[data-bg=gray] .content-text-block-inner :not(.btn):not(.wp-block-button__link) {
  color: var(--color-base-black);
}
.content-text-block[data-bg=tan] {
  background-color: var(--color-warm-300);
}
.content-text-block[data-bg=tan] .content-text-block-inner :not(.btn):not(.wp-block-button__link) {
  color: var(--color-base-black);
}

/* Button overrides removed 2026-08-29 (AB-57): they styled `.wp-block-button__link`
   (a CORE button class), but text-block never allowed core/button — and as of
   this review artbid/button is no longer allowed inside prose either (buttons
   belong in their own block, e.g. Button Section). So the rules were dead. */
