/**
 * Custom Blocks — frontend styles.
 * Per-block styling is handled by the Gutenberg editor (stored in post_content).
 * These rules are the framework defaults only.
 */

.cl-custom-block { display: block; }

/* ===========================================================
 * Lazy-load placeholder (render_mode = 'after_page_load')
 * ===========================================================
 * Paired with renderAjaxPlaceholder() in customBlocksControllerFR.php
 * and the IntersectionObserver loader in custom_blocks_fr.js. Follows
 * Google's Core Web Vitals + Material Design guidance:
 *
 *   - content-visibility: auto + contain-intrinsic-size
 *       Google's #1 CSS primitive for CLS on unknown-height content
 *       (web.dev/content-visibility/). Browser skips full rendering of
 *       off-screen elements and reserves ~200px until the real content
 *       lands → zero layout shift on swap.
 *
 *   - Shimmer skeleton (three rectangular "lines")
 *       Material Design "placeholder UI" pattern (preferred over
 *       spinners). Signals "content is coming" AND reserves visual
 *       space in one move.
 *
 *   - prefers-reduced-motion
 *       Disables the shimmer for users who opt out of motion.
 */
.cl-custom-block-lazy {
    content-visibility: auto;
    contain-intrinsic-size: auto 200px;
    min-height: 120px;
    position: relative;
    overflow: hidden;
    border-radius: 6px;
    background: #f5f6f7;
    margin: 12px 0;
}

/* Failure state — keep element in the DOM (vs silent removal) so
 * aria-busy="false" transition is announced to screen readers, but the
 * visual weight is minimized. */
.cl-custom-block-lazy.is-failed {
    background: transparent;
    min-height: 0;
    margin: 0;
}
.cl-custom-block-lazy.is-failed .cl-custom-block-lazy-skeleton {
    display: none;
}

.cl-custom-block-lazy-skeleton {
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.cl-cb-skel-line {
    height: 12px;
    border-radius: 4px;
    background: linear-gradient(
        90deg,
        #e1e3e5 0%,
        #eceef0 50%,
        #e1e3e5 100%
    );
    background-size: 200% 100%;
    animation: cl-cb-shimmer 1.5s ease-in-out infinite;
}
.cl-cb-skel-line--title {
    height: 16px;
    width: 40%;
    margin-bottom: 4px;
}
.cl-cb-skel-line--short {
    width: 60%;
}

@keyframes cl-cb-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .cl-cb-skel-line { animation: none; }
}

/* Header — rendered whenever display_type is collapse / modal_* (i.e. whenever
   the wrapper is present). The legacy header_is_active toggle was removed. */
.cl-cb-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
}
.cl-cb-header-left {
    display: flex;
    align-items: center;
    gap: 8px;
}
.cl-cb-header-right {
    display: flex;
    align-items: center;
    gap: 4px;
}
.cl-cb-header-title { font-weight: 600; }
.cl-cb-header-icon,
.cl-cb-toggle-open,
.cl-cb-toggle-close { display: inline-flex; align-items: center; justify-content: center; }

/* Collapse behavior — managed by .cl_toggle_block / .cl_toggle_body from
   public.js. Uses the shared .cl-cb-is-collapsible hook so both
   "open by default" (display_type=collapse) and "closed by default"
   (display_type=collapse_closed) variants match. */
.cl-cb-is-collapsible[is_open="no"] > .cl-cb-body { display: none; }

/* Toggle-icon visibility swap via [is_open]. */
.cl-cb-is-collapsible[is_open="yes"] .cl-cb-toggle-open,
.cl-cb-is-collapsible[is_open="no"]  .cl-cb-toggle-close { display: none; }

/* Modal variants (center / left / right) — the header is a one-way
   "click to open the popup" trigger, not a toggle: the popup has its
   own × button to close. Hide the close-toggle icon so the header
   just shows the open-icon as an affordance.

   Specificity matters here: public.css has
   `.cl_toggle_block[is_open="yes"] .cl-icon-close { display: block; animation: shakeMe }`
   at (0,3,0) that forcibly shows the close icon when the modal opens
   (because public.js flips is_open="yes" on the root). We target both
   class-names the icon span carries (.cl-cb-toggle-close
   AND .cl-icon-close) and qualify with .cl-custom-block to land at
   (0,4,0) — an unambiguous win over the global rule. */
.cl-custom-block.cl-cb-display-modal_center .cl-cb-toggle-close.cl-icon-close,
.cl-custom-block.cl-cb-display-modal_left   .cl-cb-toggle-close.cl-icon-close,
.cl-custom-block.cl-cb-display-modal_right  .cl-cb-toggle-close.cl-icon-close { display: none; }

/* "none" display type = raw content, no wrapper chrome. */
.cl-cb-no-wrapper > .cl-cb-header { display: none; }

.cl_modal_body .cl-cb-body {
    padding: 0px;
}
.cl-cb-display-collapse .cl-cb-body {
    padding: 10px 0px 0px 0px;
}