/*
 * Marketing pages: the site root, pricing, managed bookkeeping and the eleven
 * competitor comparison pages. Loaded by layouts/default after theme.css and
 * site.css, and replaces the Stack theme those pages used to run on.
 *
 * Absorbs the old custom.css, whose pricing rules are folded in below and
 * retokenised — it hard-coded the brand blue in a dozen places.
 *
 * Sections: navbar · hero · sections · feature cards · chips · steps · CTA
 *           · pricing · tables · footer · motion
 */

/* ── Navbar ─────────────────────────────────────────────────────────────────
   Sticky and translucent; JS adds .is-scrolled once the page has moved, which
   is the only thing that separates the two states. */

.site-navbar {
    position: sticky;
    top: 0;
    z-index: 1030;
    background-color: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    transition: box-shadow var(--spheyas-transition), background-color var(--spheyas-transition);
}

.site-navbar.is-scrolled {
    background-color: rgba(255, 255, 255, 0.97);
    box-shadow: var(--spheyas-shadow-sm);
}

.site-navbar .navbar-brand img {
    width: 180px;
    height: 40px;
}

.site-navbar .nav-link {
    color: var(--spheyas-ink);
    font-size: var(--spheyas-text-sm);
    font-weight: 600;
    transition: color var(--spheyas-transition-fast);
}

.site-navbar .nav-link:hover,
.site-navbar .nav-link:focus {
    color: var(--spheyas-blue-dark);
}

/* The toggler's default Bootstrap icon is a background image tinted by a CSS
   variable; ours has to match the ink colour rather than Bootstrap's black */
.site-navbar .navbar-toggler {
    border-color: var(--spheyas-border-strong);
}

.site-navbar .navbar-toggler:focus {
    box-shadow: none;
}

@media (max-width: 991.98px) {
    /* Stacked menu needs breathing room and a surface of its own */
    .site-navbar .navbar-collapse {
        margin-top: var(--spheyas-space-3);
        padding: var(--spheyas-space-3) 0;
        border-top: 1px solid var(--spheyas-border);
    }

    .site-navbar .navbar-nav {
        gap: var(--spheyas-space-1);
    }

    .site-navbar .navbar-actions {
        display: flex;
        gap: var(--spheyas-space-2);
        margin-top: var(--spheyas-space-3);
    }
}

/* ── Hero ───────────────────────────────────────────────────────────────────
   Tinted band with a soft radial wash. The wash is a gradient rather than an
   image so it costs nothing to load and scales to any viewport. */

.hero {
    position: relative;
    padding: var(--spheyas-section-y) 0;
    background-color: var(--spheyas-blue-tint-soft);
    background-image:
        radial-gradient(ellipse 80% 60% at 50% -10%, rgba(74, 144, 226, 0.18), transparent 70%),
        radial-gradient(ellipse 60% 50% at 90% 10%, rgba(74, 144, 226, 0.10), transparent 70%);
}

.hero__inner {
    max-width: 46rem;
    margin: 0 auto;
    text-align: center;
}

.hero__title {
    margin-bottom: var(--spheyas-space-4);
    font-size: var(--spheyas-text-4xl);
}

/* Gradient headline accent. -webkit- prefixes are still required for the
   background-clip:text trick outside Firefox. */
.text-gradient {
    background: linear-gradient(100deg, var(--spheyas-blue-dark), var(--spheyas-blue));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.hero__lead {
    margin-bottom: var(--spheyas-space-5);
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-lg);
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spheyas-space-3);
    justify-content: center;
}

.hero__note {
    margin-top: var(--spheyas-space-4);
    margin-bottom: 0;
    color: var(--spheyas-ink-faint);
    font-size: var(--spheyas-text-sm);
}

/* Dark hero, used by managed bookkeeping where the page is a single pitch */
.hero--dark {
    background-color: var(--spheyas-blue-darker);
    background-image:
        radial-gradient(ellipse 80% 60% at 50% -10%, rgba(255, 255, 255, 0.18), transparent 70%),
        radial-gradient(ellipse 60% 50% at 85% 20%, rgba(255, 255, 255, 0.10), transparent 70%);
    color: #fff;
}

.hero--dark .hero__title {
    color: #fff;
}

.hero--dark .hero__lead,
.hero--dark .hero__note {
    color: rgba(255, 255, 255, 0.85);
}

/* ── Sections ───────────────────────────────────────────────────────────── */

.section {
    padding: var(--spheyas-section-y) 0;
}

.section--tint {
    background-color: var(--spheyas-surface-sunken);
}

.section__head {
    max-width: 44rem;
    margin: 0 auto var(--spheyas-space-6);
    text-align: center;
}

.section__title {
    margin-bottom: var(--spheyas-space-3);
    font-size: var(--spheyas-text-2xl);
}

.section__lead {
    margin-bottom: 0;
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-lg);
}

.section__note {
    margin-top: var(--spheyas-space-3);
    margin-bottom: 0;
    color: var(--spheyas-ink-faint);
    font-size: var(--spheyas-text-sm);
}

/* Eyebrow label above a title */
.eyebrow {
    display: inline-block;
    margin-bottom: var(--spheyas-space-3);
    padding: 0.35em 0.9em;
    border-radius: var(--spheyas-radius-pill);
    background-color: var(--spheyas-blue-tint);
    color: var(--spheyas-blue-darker);
    font-size: var(--spheyas-text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.hero--dark .eyebrow {
    background-color: rgba(255, 255, 255, 0.16);
    color: #fff;
}

/* ── Feature cards ──────────────────────────────────────────────────────── */

.feature-card {
    height: 100%;
    padding: var(--spheyas-space-5);
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius-lg);
    background-color: var(--spheyas-surface);
    box-shadow: var(--spheyas-shadow-sm);
    transition: transform var(--spheyas-transition), box-shadow var(--spheyas-transition), border-color var(--spheyas-transition);
}

.feature-card:hover {
    transform: translateY(-3px);
    border-color: var(--spheyas-blue);
    box-shadow: var(--spheyas-shadow);
}

.feature-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: var(--spheyas-space-4);
    border-radius: var(--spheyas-radius);
    background-color: var(--spheyas-blue-tint);
    color: var(--spheyas-blue-dark);
    font-size: var(--spheyas-text-lg);
}

.feature-card__title {
    margin-bottom: var(--spheyas-space-2);
    font-size: var(--spheyas-text-lg);
}

.feature-card__body {
    margin-bottom: 0;
    color: var(--spheyas-ink-muted);
}

/* A checklist inside a card — used by the bookkeeping teaser and the
   "when they are the better choice" list */
.check-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.check-list li {
    position: relative;
    padding-left: 1.75rem;
}

.check-list li + li {
    margin-top: var(--spheyas-space-2);
}

.check-list li::before {
    content: '\f00c'; /* Font Awesome check */
    position: absolute;
    top: 0.15em;
    left: 0;
    color: var(--spheyas-blue);
    font-family: 'Font Awesome 5 Free'; /* the vendored build is 5.15 */
    font-size: 0.85em;
    font-weight: 900;
}

/* ── Capability chips ───────────────────────────────────────────────────── */

.chip-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spheyas-space-3);
    justify-content: center;
}

.chip {
    padding: var(--spheyas-space-3) var(--spheyas-space-4);
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius-pill);
    background-color: var(--spheyas-surface);
    color: var(--spheyas-ink);
    font-size: var(--spheyas-text-sm);
    font-weight: 600;
}

.chip i {
    margin-right: var(--spheyas-space-2);
    color: var(--spheyas-blue);
}

/* The comparison block's chips are links, not labels */
a.chip {
    text-decoration: none;
    transition: border-color var(--spheyas-transition-fast), color var(--spheyas-transition-fast), box-shadow var(--spheyas-transition-fast);
}

a.chip:hover,
a.chip:focus-visible {
    border-color: var(--spheyas-blue);
    color: var(--spheyas-blue-dark);
    box-shadow: var(--spheyas-shadow-sm);
}

/* ── Steps ──────────────────────────────────────────────────────────────── */

.step__number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    margin-bottom: var(--spheyas-space-3);
    border-radius: var(--spheyas-radius-pill);
    background-color: var(--spheyas-blue);
    color: #fff;
    font-family: var(--spheyas-font-heading);
    font-size: var(--spheyas-text-lg);
    font-weight: 700;
}

.step__title {
    margin-bottom: var(--spheyas-space-2);
    font-size: var(--spheyas-text-lg);
}

.step__body {
    margin-bottom: 0;
    color: var(--spheyas-ink-muted);
}

/* ── Split section (text beside a card) ─────────────────────────────────── */

.split__title {
    margin-bottom: var(--spheyas-space-3);
    font-size: var(--spheyas-text-2xl);
}

.split__lead {
    margin-bottom: var(--spheyas-space-4);
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-lg);
}

/* ── Closing call to action ─────────────────────────────────────────────── */

/* site.css grows the last band of a page so a short one still reaches the footer.
   That is right for a neutral content region and wrong for this — a stretched dark
   band swallows the viewport. Written as a child selector to match the specificity
   of the rule it overrides; a bare .cta-band loses to .site-main > :last-child. */
.site-main > .cta-band {
    flex: 0 0 auto;
}

.cta-band {
    padding: var(--spheyas-section-y) 0;
    background-color: var(--spheyas-blue-darker);
    background-image: linear-gradient(120deg, var(--spheyas-blue-darker), var(--spheyas-blue-dark));
    color: #fff;
    text-align: center;
}

.cta-band__title {
    margin-bottom: var(--spheyas-space-3);
    color: #fff;
    font-size: var(--spheyas-text-2xl);
}

.cta-band__lead {
    max-width: 40rem;
    margin: 0 auto var(--spheyas-space-5);
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--spheyas-text-lg);
}

/* White button for any dark surface — the CTA band and the dark hero both use
   it, so it is deliberately not scoped to either. Bootstrap's .btn-light is
   grey-tinted and disappears against a blue field. */
.btn-inverse {
    background-color: #fff;
    border-color: #fff;
    color: var(--spheyas-blue-darker);
    font-weight: 600;
}

.btn-inverse:hover,
.btn-inverse:focus {
    background-color: var(--spheyas-blue-tint);
    border-color: var(--spheyas-blue-tint);
    color: var(--spheyas-blue-darker);
}

/* ── Pricing ────────────────────────────────────────────────────────────────
   From the old custom.css, retokenised. */

/* Billing toggle — segmented control. The container owns the border so the
   segments can never show a seam, and the buttons deliberately avoid .btn,
   whose padding breaks the control. */
.billing-toggle {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--spheyas-blue);
    border-radius: var(--spheyas-radius-sm);
    overflow: hidden;
}

.billing-toggle-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    margin: 0;
    padding: 0.6em 1.4em;
    border: 0;
    background-color: var(--spheyas-surface);
    color: var(--spheyas-blue-dark);
    font-size: var(--spheyas-text-sm);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--spheyas-transition-fast), color var(--spheyas-transition-fast);
}

.billing-toggle-btn + .billing-toggle-btn {
    border-left: 1px solid var(--spheyas-blue);
}

.billing-toggle-btn:hover {
    background-color: var(--spheyas-blue-tint-soft);
}

.billing-toggle-btn.active,
.billing-toggle-btn.active:hover {
    background-color: var(--spheyas-blue);
    color: #fff;
}

.billing-toggle-saving {
    padding: 0.2em 0.6em;
    border-radius: var(--spheyas-radius-pill);
    background-color: var(--spheyas-blue-tint);
    color: var(--spheyas-blue-darker);
    font-size: var(--spheyas-text-xs);
    font-weight: 600;
}

.billing-toggle-btn.active .billing-toggle-saving {
    background-color: rgba(255, 255, 255, 0.22);
    color: #fff;
}

/* Tier cards — equal heights, with the call to action pinned to the bottom so
   the three buttons line up however long the feature lists are. */
.pricing-card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: var(--spheyas-space-5);
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius-lg);
    background-color: var(--spheyas-surface);
    box-shadow: var(--spheyas-shadow-sm);
    text-align: center;
}

.pricing-card ul {
    flex-grow: 1;
    text-align: left;
}

.pricing-card > .btn {
    margin-top: auto;
    align-self: center;
}

.pricing-plan-name {
    display: block;
    margin-bottom: var(--spheyas-space-2);
    font-family: var(--spheyas-font-heading);
    font-size: var(--spheyas-text-xl);
    font-weight: 700;
}

/* Amount and its /mo suffix on one line */
.pricing-price {
    margin-bottom: var(--spheyas-space-1);
}

.pricing-amount {
    font-family: var(--spheyas-font-heading);
    font-size: var(--spheyas-text-3xl);
    font-weight: 700;
    line-height: 1;
}

.pricing-period,
.pricing-annual,
.pricing-note {
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-sm);
}

.pricing-card .check-list {
    margin: var(--spheyas-space-4) 0;
}

.pricing-card .check-list li {
    font-size: var(--spheyas-text-sm);
}

/* The free plan carries the offer, so its name and price are set one step larger
   than the paid cards. Scoped to this card rather than changed on .pricing-amount,
   which the paid cards share — and "$0" is short enough to take the extra size
   without wrapping, which "$29" at the same step would not be guaranteed to. */
.pricing-card-free .pricing-plan-name {
    font-size: var(--spheyas-text-2xl);
}

.pricing-card-free .pricing-amount {
    font-size: var(--spheyas-text-4xl);
}

/* Straddles the paid cards' bottom edge, mirroring .pricing-badge at the top. Taken
   out of flow on purpose: in flow it would sit below the button and push the three
   buttons out of line, since only two of the three cards carry it. The solid
   background is what masks the border it sits on, including the highlight card's
   thicker one. */
.pricing-guarantee {
    position: absolute;
    bottom: -0.85rem;
    left: 50%;
    z-index: 1;
    transform: translateX(-50%);
    margin: 0;
    padding: 0.4em 1em;
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius-pill);
    background-color: var(--spheyas-surface);
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-xs);
    font-weight: 600;
    white-space: nowrap;
}

.pricing-guarantee .fa-shield-alt {
    color: var(--spheyas-green);
}

/* Highlighted card, lifted rather than merely outlined */
.pricing-card-highlight {
    border-color: var(--spheyas-blue);
    border-width: 2px;
    box-shadow: var(--spheyas-shadow);
}

.pricing-badge {
    position: absolute;
    top: -0.85rem;
    left: 50%;
    z-index: 1;
    transform: translateX(-50%);
    padding: 0.4em 1em;
    border-radius: var(--spheyas-radius-pill);
    background-color: var(--spheyas-blue);
    color: #fff;
    font-size: var(--spheyas-text-xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

/* Competitor comparison — only the price you don't pay is written in red */
/* Branch pricing, set as a head-to-head rather than a sentence. Sizes come off the
   same scale as the plan cards so it reads as part of the pricing section and not as
   an advertisement dropped into it. */
.pricing-versus {
    max-width: 44rem;
    margin: 0 auto;
    text-align: center;
}

.pricing-versus-question {
    margin-bottom: var(--spheyas-space-4);
    color: var(--spheyas-ink);
    font-family: var(--spheyas-font-heading);
    font-size: var(--spheyas-text-xl);
    font-weight: 700;
}

.pricing-versus-side {
    padding: 0 var(--spheyas-space-3);
}

/* The divider belongs to the right-hand column so it lands exactly on the gutter,
   and it stops at the column's own height rather than running the full block */
.pricing-versus-side-ours {
    border-left: 1px solid var(--spheyas-border);
}

.pricing-versus-label {
    display: block;
    margin-bottom: var(--spheyas-space-2);
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.pricing-versus-amount {
    margin-bottom: var(--spheyas-space-1);
    font-family: var(--spheyas-font-heading);
    font-size: var(--spheyas-text-3xl);
    font-weight: 700;
    line-height: 1;
}

/* Rides on the amount's baseline at body size, the way /mo does on the plan cards */
.pricing-versus-period {
    font-family: var(--spheyas-font-body);
    font-size: var(--spheyas-text-sm);
    font-weight: 600;
}

.pricing-versus-note {
    margin-bottom: 0;
    font-size: var(--spheyas-text-sm);
}

/* Softened from --spheyas-red / --spheyas-green, which are status colours: at this
   size a full-strength pair shouts, and the block sits directly under the guarantee
   band. Kept local rather than lightening the tokens, which carry meaning elsewhere.
   The amounts get the lighter tint; the notes below them get a deeper one, because
   the same tint that is comfortable at 3xl fails contrast at --spheyas-text-sm.

   Ours is also the bigger number: the competitor's figure is the setup, not the
   point, and at matching sizes it competes for the eye. */
.pricing-versus-amount.pricing-versus-them {
    color: #b5695f;
    font-size: var(--spheyas-text-2xl);
}

.pricing-versus-amount.pricing-versus-ours {
    color: #56a482;
}

.pricing-versus-note.pricing-versus-them {
    color: #97564d;
}

.pricing-versus-note.pricing-versus-ours {
    color: #3d7f62;
}

/* Notes to the plans */
.pricing-notes {
    max-width: 44rem;
    margin: var(--spheyas-space-6) auto 0;
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-sm);
}

.pricing-notes li {
    margin-bottom: var(--spheyas-space-4);
}

.pricing-notes strong {
    color: var(--spheyas-ink);
}

/* ── Comparison tables ──────────────────────────────────────────────────────
   Shared by the pricing schedule and the eleven competitor pages. */

.pricing-table-wrapper {
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius-lg);
    background-color: var(--spheyas-surface);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.pricing-table {
    min-width: 600px;
    width: 100%;
    margin: 0;
    border-collapse: collapse;
}

.pricing-table th,
.pricing-table td {
    padding: var(--spheyas-space-3) var(--spheyas-space-4);
    vertical-align: middle;
}

.pricing-corner-cell {
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-xs);
    font-weight: 500;
    letter-spacing: 0.04em;
    text-align: left;
    text-transform: uppercase;
    vertical-align: bottom;
}

.pricing-table thead th {
    border-bottom: 2px solid var(--spheyas-border);
    background-color: var(--spheyas-surface-sunken);
    font-family: var(--spheyas-font-heading);
}

.pricing-table tbody tr + tr {
    border-top: 1px solid var(--spheyas-border);
}

.pricing-table tbody td:first-child {
    font-weight: 500;
}

/* Our column, tinted. Translucent so a row's own background reads through. */
.pricing-col-highlighted {
    background-color: rgba(74, 144, 226, 0.06);
}

.pricing-table .fa-check {
    color: var(--spheyas-green);
}

/* ── Footer ─────────────────────────────────────────────────────────────── */

.marketing-footer {
    padding: var(--spheyas-space-7) 0 var(--spheyas-space-5);
    border-top: 1px solid var(--spheyas-border);
    background-color: var(--spheyas-surface-sunken);
    color: var(--spheyas-ink-muted);
    font-size: var(--spheyas-text-sm);
}

.marketing-footer__title {
    margin-bottom: var(--spheyas-space-3);
    color: var(--spheyas-ink);
    font-size: var(--spheyas-text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.marketing-footer ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.marketing-footer li + li {
    margin-top: var(--spheyas-space-2);
}

.marketing-footer a {
    color: var(--spheyas-ink-muted);
    text-decoration: none;
    transition: color var(--spheyas-transition-fast);
}

.marketing-footer a:hover,
.marketing-footer a:focus {
    color: var(--spheyas-blue-dark);
    text-decoration: underline;
}

.marketing-footer__base {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--spheyas-space-3);
    margin-top: var(--spheyas-space-6);
    padding-top: var(--spheyas-space-4);
    border-top: 1px solid var(--spheyas-border);
}

.marketing-footer__legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spheyas-space-2) var(--spheyas-space-4);
}

/* ── Product screenshots ────────────────────────────────────────────────────
   The source images already carry their own browser chrome and a pale mat, so
   they need a rounded edge and a shadow rather than a frame of our own. */

.screenshot {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--spheyas-radius-lg);
    box-shadow: var(--spheyas-shadow-lg);
}

/* A shot inside a feature card. The image itself is a purpose-made crop of the
   report body — cropping in CSS instead would show whatever happens to fall in
   the box at that card width, which at a third of a row was browser chrome and
   date filters rather than the report. Bordered rather than shadowed, since the
   crop has no window frame of its own to sit in. */
.feature-card__shot {
    margin-top: var(--spheyas-space-4);
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius);
    box-shadow: none;
}

/* The hero shot, pulled up so it overlaps the band below and reads as one
   composition rather than a picture sitting in a box */
.hero__shot {
    max-width: 60rem;
    margin: var(--spheyas-space-7) auto calc(var(--spheyas-section-y) * -1 - var(--spheyas-space-6));
    position: relative;
    z-index: 1;
}

/* The band after a hero that carries a shot has to make room for the overlap */
.section--after-shot {
    padding-top: calc(var(--spheyas-section-y) + var(--spheyas-space-8));
}

@media (max-width: 767.98px) {
    /* The overlap costs more than it gives on a phone, where the shot is small
       and the fold is close */
    .hero__shot {
        margin-bottom: 0;
    }

    .section--after-shot {
        padding-top: var(--spheyas-section-y);
    }

    /* The two columns stay side by side on a phone — stacking them would destroy the
       comparison, which only works when both numbers are in one glance — so the type
       comes down instead to buy each column room. */
    .pricing-versus-amount {
        font-size: var(--spheyas-text-2xl);
    }

    .pricing-versus-amount.pricing-versus-them {
        font-size: var(--spheyas-text-xl);
    }

    .pricing-versus-note {
        font-size: var(--spheyas-text-xs);
    }

    .pricing-versus-side {
        padding: 0 var(--spheyas-space-2);
    }
}

/* ── Motion ─────────────────────────────────────────────────────────────────
   js/reveal.js adds .is-revealed as each element crosses into view. The
   starting state is only applied when motion is welcome, so a reduced-motion
   visitor — or anyone with JS off — sees the finished state and never a blank
   page. */

@media (prefers-reduced-motion: no-preference) {
    /* Scoped to .js-reveal, which js/reveal.js puts on <html> as it loads: if the
       script 404s, errors or is blocked, the class never lands and every section
       stays visible. Hiding content behind a script that might not run is how a
       page ends up blank for a crawler. */
    .js-reveal .reveal {
        opacity: 0;
        transform: translateY(14px);
        transition: opacity 500ms ease, transform 500ms cubic-bezier(0.2, 0.7, 0.3, 1);
    }

    .js-reveal .reveal.is-revealed {
        opacity: 1;
        transform: none;
    }

    /* Staggered children, for a row of cards */
    .js-reveal .reveal-stagger > *:nth-child(2) {
        transition-delay: 80ms;
    }

    .js-reveal .reveal-stagger > *:nth-child(3) {
        transition-delay: 160ms;
    }

    .js-reveal .reveal-stagger > *:nth-child(4) {
        transition-delay: 240ms;
    }
}

/* ── FAQ (contractor trade pages) ────────────────────────────────────────────
   Same <details> pattern as the blog's content-faq, sized for the marketing
   layout. The summary carries the question, the answer opens in place. */
.faq-list {
    max-width: var(--spheyas-measure, 46rem);
    margin: 0 auto;
}

.faq-list details {
    border: 1px solid var(--spheyas-border);
    border-radius: var(--spheyas-radius);
    background: var(--spheyas-surface, #ffffff);
}

.faq-list details + details {
    margin-top: var(--spheyas-space-3);
}

.faq-list summary {
    cursor: pointer;
    padding: var(--spheyas-space-3) var(--spheyas-space-4);
    font-weight: 600;
    list-style: none;
}

.faq-list summary::-webkit-details-marker {
    display: none;
}

.faq-list .faq-answer {
    margin: 0;
    padding: 0 var(--spheyas-space-4) var(--spheyas-space-3);
    color: var(--spheyas-ink-muted);
}
