/* /public/css/base/utilities.css */

/*
  Visually hide an element, but leave it available for screen readers.
  Useful for accessibility.
*/
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
  }
  
  /* Text alignment utilities */
  .text-left { text-align: left; }
  .text-center { text-align: center; }
  .text-right { text-align: right; }
  
  /* Display utilities */
  .d-block { display: block; }
  .d-flex { display: flex; }
  .d-none { display: none; }

  /*
    Safe-area utilities for mobile-app feel.

    iOS notch + home-indicator clearance. Use these on full-bleed fixed
    elements (mobile headers, bottom tab bars, sheet-style modals) so
    nothing renders under the notch or behind the home indicator.

    Per design-system-spec.md §4 (mobile composition).
  */
  .safe-area-pad-top    { padding-top:    env(safe-area-inset-top,    0px); }
  .safe-area-pad-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); }
  .safe-area-pad-left   { padding-left:   env(safe-area-inset-left,   0px); }
  .safe-area-pad-right  { padding-right:  env(safe-area-inset-right,  0px); }

  /* Convenience: add safe-area padding on all four edges of a full-bleed
     container. Most common use is on a fixed bottom bar or a sheet
     modal. */
  .safe-area-pad-all {
    padding-top:    env(safe-area-inset-top,    0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    padding-left:   env(safe-area-inset-left,   0px);
    padding-right:  env(safe-area-inset-right,  0px);
  }

/* ============================================================
 * Global click loader (2026-05-21)
 *
 * The .cp-click-loading class is applied by the global handler in
 * base_members.twig to any anchor that the user just clicked AND that
 * is about to navigate (modal-opening anchors skipped via
 * requestAnimationFrame + defaultPrevented gating). Fills the visual
 * gap between click and unload so slow-network users (Indian 3G/4G,
 * in-app webviews, etc.) don't rage-click.
 *
 * Affordance:
 *   1. The anchor dims to opacity 0.65 — clearly says "busy."
 *   2. cursor switches to `wait`.
 *   3. pointer-events: none blocks a second click landing during the
 *      navigation window.
 *   4. Any trailing directional icon (arrow, chevron) is hidden — a
 *      rotating arrow reads as "broken" not "loading."
 *   5. A CSS-only spinner glyph (rotating bordered circle) is appended
 *      via ::after, inheriting the link's text color. Paints
 *      immediately on add-class — no Font Awesome dependency, no
 *      bundle parse needed.
 *
 * 30-second safety timeout (JS-side) removes the class if the page
 * never navigates. So even on edge cases (back-button mid-click, late
 * preventDefault, errored navigation), the anchor doesn't stay dim
 * forever.
 * ============================================================ */

.cp-click-loading {
    pointer-events: none;
    cursor: wait;
    opacity: 0.65;
    position: relative;
}

/* Hide any trailing directional icon while loading. A rotating arrow
 * implies "go" not "wait" — the real spinner appended via ::after
 * below replaces it. Visibility (not display) keeps the icon's slot
 * reserved so layout doesn't reflow when the spinner replaces it. */
.cp-click-loading .audit-hero__cta-arrow,
.cp-click-loading .feature-card__cta-arrow,
.cp-click-loading .urgent-banner__chev,
.cp-click-loading .velvet-rope__cta-arrow,
.cp-click-loading .dashboard-videos__see-all > i.fas,
.cp-click-loading > i.fas.fa-arrow-right,
.cp-click-loading > i.fas.fa-chevron-right,
.cp-click-loading > i.fas.fa-angle-right {
    visibility: hidden;
}

/* Inline spinner appended to the clicked anchor. Uses currentColor so
 * it inherits the link's text color automatically — works on indigo
 * CTAs, dark text-on-light links, white-on-dark hero CTAs, anywhere. */
.cp-click-loading::after {
    content: '';
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-left: 8px;
    vertical-align: -2px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: cp-click-loading-spin 650ms linear infinite;
}

@keyframes cp-click-loading-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .cp-click-loading::after {
        animation: none;
        border-right-color: currentColor;
        opacity: 0.5;
    }
}
