/* ==========================================================================
   Utilities
   ========================================================================== */

.text-center { text-align: center; }
.text-left   { text-align: left; }

.mt-0 { margin-top: 0; }
.mt-4 { margin-top: var(--sp-4); }
.mt-6 { margin-top: var(--sp-6); }
.mb-0 { margin-bottom: 0; }
.mb-4 { margin-bottom: var(--sp-4); }
.mb-6 { margin-bottom: var(--sp-6); }

.stack   { display: flex; flex-direction: column; gap: var(--sp-4); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }
.center  { display: flex; align-items: center; justify-content: center; }

.muted  { color: var(--slate-500); }
.accent { color: var(--primary-color); }

.no-scroll { overflow: hidden; }

/* Scroll-to-top button */
.to-top {
    position: fixed;
    right: 25px;
    left: auto;            /* declared so the phone rule can move it to the left */
    bottom: 95px;
    width: 44px; height: 44px;
    border-radius: 50%;
    background: var(--white);
    color: var(--primary-color);
    border: 1px solid var(--border-light);
    box-shadow: var(--shadow-md);
    display: flex; align-items: center; justify-content: center;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out), visibility var(--dur-2);
    z-index: var(--z-sidebar);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }

/* Phone geometry. This has to live HERE, after .to-top's own base rule above,
   because a media query adds no specificity — the same block written in
   04-nav.css lost to the unmediaed `right: 25px` and left the button sitting on
   top of the assistant bubble.

   Back-to-top moves to the LEFT edge on phones while the assistant stays right.
   The previous approach stacked all three floating buttons on the right with
   hand-computed clearances, which is exactly what drifted out of sync.
   Opposite corners cannot collide, need no arithmetic, and survive the
   assistant window being open. Clearance derives from the tokens in
   00-tokens.css so it cannot fall behind the sticky CTA bar. */
@media (max-width: 900px) {
    .to-top {
        left: var(--sp-4);
        right: auto;
        bottom: calc(var(--cta-bar-h) + var(--safe-b) + var(--fab-gap));
        width: var(--fab-size);
        height: var(--fab-size);
    }
}

@media (max-width: 400px) {
    .to-top { left: var(--sp-3); }
}

/* Honeypot — see partials/honeypot.php.

   Deliberately NOT display:none and NOT type="hidden": a good many bots skip
   both, and the point is that they DO fill it. This moves it out of the
   viewport while leaving it a visible, fillable text input to anything parsing
   the DOM. aria-hidden + tabindex="-1" in the markup keep it away from screen
   readers and keyboard users, so no real visitor can reach it either way. */
.hp-field {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   Print — legal pages and long-form articles are the two things anyone
   plausibly prints. Strip chrome and floating UI, force legible black-on-white
   type, and show link destinations since a printout can't be clicked.
   -------------------------------------------------------------------------- */
@media print {
    #mainHeader,
    .site-footer,
    .social-sidebar,
    .to-top,
    .bot-trigger,
    .bot-window,
    .modal,
    #toastStack,
    .scroll-progress,
    [data-modal-open],
    .skip-link {
        display: none !important;
    }

    * {
        background: transparent !important;
        box-shadow: none !important;
        text-shadow: none !important;
        color: #000 !important;
    }

    body { font-size: 12pt; line-height: 1.5; }

    a { color: #000 !important; text-decoration: underline; }
    a[href^="http"]::after,
    a[href^="https"]::after {
        content: ' (' attr(href) ')';
        font-size: 0.85em;
        font-weight: 400;
    }
    /* Relative/anchor/mailto/tel links don't carry a meaningful printed URL. */
    a[href^="#"]::after,
    a[href^="mailto:"]::after,
    a[href^="tel:"]::after,
    .prose a::after {
        content: '';
    }

    .hero, .section-cta-banner, .cta-banner-wrapper { padding: 0 0 var(--sp-6); }
    img { max-width: 100% !important; }
}

/* Placeholder marker — makes unfilled demo content obvious so it can never
   ship to a client unnoticed. */
.is-placeholder {
    position: relative;
    outline: 1px dashed var(--warning);
    outline-offset: 2px;
}
.is-placeholder::before {
    content: 'PLACEHOLDER';
    position: absolute;
    top: 0; right: 0;
    background: var(--warning);
    color: #fff;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.5px;
    padding: 2px 6px;
    border-radius: 0 0 0 4px;
    z-index: 5;
    pointer-events: none;
}
