/* =============================================================================
   The public site's design system  (Phase 701)
   -----------------------------------------------------------------------------
   ONE STYLESHEET FOR THE WHOLE MARKETING SITE. The guest layout it replaces
   loaded twenty stylesheets and fourteen scripts — including DevExtreme, a grid
   library no marketing page has ever used — before a visitor saw a word. Every
   one of those was a request, a parse and a render-blocking wait on the first
   impression the product gets to make.

   IT BUILDS ON THE SHARED TOKENS rather than beside them: --ds-brand-* and
   --ds-neutral-* come from design-system/tokens.css, so the public site and the
   signed-in product are recognisably one piece of software. What is defined here
   are the things only a marketing page needs — display type, sections, hero
   gradients, glass panels, scroll animations.

   NO @import, NO WEBFONT REQUEST. Type is a system stack: it renders on the
   first paint, weighs nothing, and looks native on every platform. A downloaded
   display face would cost 100-200 ms of invisible text for a difference most
   visitors could not name.
   ============================================================================= */

:root {
    /* ── Public palette ────────────────────────────────────────────────────
       Anchored on the product's own brand green so the site and the app are
       obviously the same company. The ink scale is warmer than pure neutral —
       long-form marketing copy set in cold grey reads as a spreadsheet. */
    --ps-brand: var(--ds-brand-500, #1ab394);
    --ps-brand-dark: var(--ds-brand-700, #0e7361);
    --ps-brand-deep: var(--ds-brand-900, #0d4b41);
    --ps-brand-soft: var(--ds-brand-50, #eefbf6);

    /* Phase 715 — THE GRADIENT'S SECOND COLOUR, and the reason these pages did not
       look like the home page.

       This was #6366f1, an indigo. It appears in every gradient the Platform pages
       draw: icon tiles, the "Most popular" badge, primary buttons, the hero aurora,
       the CTA band. The home page does not use indigo ANYWHERE — home-premium.css
       builds its gradient from `--ds-accent` to `--ds-accent-active`, i.e. brand
       green to darker brand green. So the two halves of the same site were running
       different palettes, and a visitor moving from the home page to a Platform page
       saw the accent colour change from green to purple.

       Pointing the gradient's end at the brand's own dark step matches the home page
       and keeps the depth a gradient exists for. --ps-accent itself is kept (a few
       places still want a distinct second hue) but no longer feeds the gradient. */
    --ps-gradient-end: var(--ds-brand-700, #0e7361);
    --ps-accent: var(--ds-brand-700, #0e7361);
    --ps-accent-warm: #f59e0b; /* used sparingly: badges, highlights */

    --ps-ink: #0b1220;
    --ps-ink-soft: #334155;
    --ps-ink-muted: #64748b;
    --ps-ink-faint: #94a3b8;

    --ps-surface: #ffffff;
    --ps-surface-alt: #f8fafc;
    --ps-surface-deep: #0b1220;
    --ps-line: #e2e8f0;
    --ps-line-soft: #f1f5f9;

    /* ── Type ──────────────────────────────────────────────────────────────
       clamp() everywhere: one declaration covers phone to desktop with no
       breakpoint, and nothing jumps at a magic width. */
    --ps-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --ps-display-xl: clamp(2.25rem, 1.4rem + 3.6vw, 4rem);
    --ps-display-lg: clamp(1.9rem, 1.3rem + 2.6vw, 3rem);
    --ps-display-md: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
    --ps-display-sm: clamp(1.2rem, 1.05rem + 0.7vw, 1.5rem);
    --ps-body-lg: clamp(1.02rem, 0.98rem + 0.25vw, 1.15rem);
    --ps-body: 1rem;

    /* ── Space, radius, shadow ─────────────────────────────────────────── */
    --ps-section-y: clamp(3.5rem, 2rem + 6vw, 7rem);
    --ps-gutter: clamp(1rem, 0.5rem + 2vw, 2rem);
    --ps-max: 1180px;

    --ps-radius-sm: 10px;
    --ps-radius: 16px;
    --ps-radius-lg: 24px;
    --ps-radius-pill: 999px;

    /* Phase 715: elevation matched to the home page's own scale (home-premium.css
       --home-elev-1/-2). Those are NEUTRAL slate shadows; these were tuned separately
       and read slightly cooler and heavier, which is part of why a Platform page did
       not feel like the same site as the home page. */
    --ps-shadow-sm: 0 2px 8px rgba(15, 23, 42, .05);
    --ps-shadow: 0 12px 32px rgba(15, 23, 42, .08);
    --ps-shadow-lg: 0 24px 60px -20px rgba(15, 23, 42, .18);
    --ps-shadow-brand: 0 14px 30px rgba(var(--ds-accent-rgb, 26, 179, 148), .30);

    --ps-gradient: linear-gradient(160deg, var(--ps-brand) 0%, var(--ps-gradient-end) 100%);
    --ps-gradient-deep: linear-gradient(160deg, #0b1220 0%, #12233a 55%, #0e4a3f 100%);
}

/* ── Reset, only where the shared CSS leaves gaps ─────────────────────────── */
.ps { font-family: var(--ps-font); color: var(--ps-ink); background: var(--ps-surface); }
.ps *, .ps *::before, .ps *::after { box-sizing: border-box; }
.ps img, .ps svg { max-width: 100%; height: auto; }
/* text-transform: none is not cosmetic here. The site theme uppercases every
   heading, which suits a three-word banner and ruins a sentence: "STOP DEFAULTING
   TO ONE COURIER OUT OF HABIT" is markedly harder to read than the same words in
   sentence case, and these pages are written in sentences. Scoped to .ps, so the
   theme's own headings are untouched. */
.ps h1, .ps h2, .ps h3, .ps h4 { margin: 0 0 .6em; line-height: 1.15; letter-spacing: -.022em; font-weight: 800; text-transform: none; }
.ps p { margin: 0 0 1em; line-height: 1.65; color: var(--ps-ink-soft); }
.ps a { color: inherit; text-decoration: none; }
.ps ul { margin: 0; padding: 0; list-style: none; }

/* ── Layout primitives ───────────────────────────────────────────────────── */
.ps-container { width: 100%; max-width: var(--ps-max); margin-inline: auto; padding-inline: var(--ps-gutter); }
.ps-section { padding-block: var(--ps-section-y); }
.ps-section--tight { padding-block: calc(var(--ps-section-y) * .6); }
.ps-section--alt { background: var(--ps-surface-alt); }
.ps-section--deep { background: var(--ps-gradient-deep); color: #fff; }
.ps-section--deep p { color: rgba(255, 255, 255, .78); }
.ps-section--deep h2, .ps-section--deep h3 { color: #fff; }

/* ── Page hero ───────────────────────────────────────────────────────────────
   A HERO IS AN OPENER, NOT A SECTION IN ITS OWN RIGHT. Left as a plain
   .ps-section it contributed its own bottom padding and the content below added
   a full top padding on top of that — measured at 1440px: 67px + 112px, so 216px
   of white between the page title and the first card. It read as a rendering
   fault rather than as breathing room, which is what the screenshot showed.

   The hero now carries the space for both, and whatever follows it starts flush. */
.ps-page-hero { padding-block: clamp(2rem, 1.2rem + 2.5vw, 3.25rem) clamp(1.5rem, 1rem + 1.5vw, 2.25rem); }
.ps-page-hero + .ps-section { padding-top: 0; }
.ps-page-hero + .ps-section--alt,
.ps-page-hero + .ps-section--deep { padding-top: var(--ps-section-y); }  /* a change of background needs its own space */

.ps-grid { display: grid; gap: clamp(1rem, .6rem + 1.4vw, 1.75rem); }
.ps-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.ps-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.ps-grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

/* ── Section headings ────────────────────────────────────────────────────── */
.ps-eyebrow {
    display: inline-flex; align-items: center; gap: .5rem;
    font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ps-brand-dark); background: var(--ps-brand-soft);
    border-radius: var(--ps-radius-pill); padding: .4rem .9rem; margin-bottom: 1rem;
}
.ps-section--deep .ps-eyebrow { color: #7bead0; background: rgba(123, 234, 208, .12); }
.ps-h2 { font-size: var(--ps-display-lg); }
.ps-h3 { font-size: var(--ps-display-md); }
.ps-lead { font-size: var(--ps-body-lg); color: var(--ps-ink-muted); max-width: 62ch; }
.ps-center { text-align: center; }
.ps-center .ps-lead { margin-inline: auto; }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.ps-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
    font-family: inherit; font-size: .95rem; font-weight: 700; line-height: 1;
    padding: .95rem 1.6rem; border-radius: var(--ps-radius-pill); border: 1.5px solid transparent;
    cursor: pointer; text-align: center; white-space: nowrap;
    transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease, color .18s ease;
    /* 44px min target: the WCAG pointer-target guidance, and simply easier to hit. */
    min-height: 44px;
}
.ps-btn--primary { background: var(--ps-gradient); color: #fff; box-shadow: var(--ps-shadow-brand); }
.ps-btn--primary:hover { transform: translateY(-2px); color: #fff; }
.ps-btn--dark { background: var(--ps-ink); color: #fff; }
.ps-btn--dark:hover { transform: translateY(-2px); color: #fff; }
.ps-btn--ghost { background: transparent; border-color: var(--ps-line); color: var(--ps-ink); }
.ps-btn--ghost:hover { border-color: var(--ps-brand); color: var(--ps-brand-dark); }
.ps-btn--on-dark { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .25); color: #fff; }
.ps-btn--on-dark:hover { background: rgba(255, 255, 255, .18); color: #fff; }
.ps-btn--lg { padding: 1.1rem 2rem; font-size: 1rem; }

/* Focus is never removed, only restyled: keyboard users need to see where they are. */
.ps :is(a, button, input, select, textarea, summary):focus-visible {
    outline: 3px solid var(--ps-brand); outline-offset: 3px; border-radius: 6px;
}

/* ── Cards ───────────────────────────────────────────────────────────────── */
.ps-card {
    background: var(--ps-surface); border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius); padding: clamp(1.25rem, 1rem + .8vw, 1.85rem);
    box-shadow: var(--ps-shadow-sm);
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.ps-card--hover:hover { transform: translateY(-4px); box-shadow: var(--ps-shadow); border-color: var(--ps-brand-soft); }
.ps-card__icon {
    width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center;
    background: var(--ps-brand-soft); color: var(--ps-brand-dark); font-size: 1.15rem; margin-bottom: 1rem;
}
.ps-card__title { font-size: 1.08rem; font-weight: 750; margin-bottom: .45rem; }
.ps-card p { font-size: .92rem; margin-bottom: 0; }

/* Glass, used only over the dark gradient where there is something to refract. */
.ps-glass {
    background: rgba(255, 255, 255, .07);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: var(--ps-radius);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    padding: clamp(1.25rem, 1rem + .8vw, 1.75rem);
}

/* ── Stats ───────────────────────────────────────────────────────────────── */
.ps-stat__value {
    font-size: clamp(1.9rem, 1.4rem + 1.8vw, 2.9rem); font-weight: 850; line-height: 1;
    background: var(--ps-gradient); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ps-section--deep .ps-stat__value { background: linear-gradient(160deg, #7bead0, #34d399); -webkit-background-clip: text; background-clip: text; }
.ps-stat__label { font-size: .85rem; color: var(--ps-ink-muted); margin-top: .4rem; }
.ps-section--deep .ps-stat__label { color: rgba(255, 255, 255, .7); }

/* ── Accordion (FAQ) — <details>, so it works before any JS runs ─────────── */
.ps-faq { border: 1px solid var(--ps-line); border-radius: var(--ps-radius); background: #fff; overflow: hidden; }
.ps-faq + .ps-faq { margin-top: .75rem; }
.ps-faq > summary {
    cursor: pointer; list-style: none; padding: 1.1rem 1.35rem; font-weight: 700; font-size: 1rem;
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.ps-faq > summary::-webkit-details-marker { display: none; }
.ps-faq > summary::after { content: "+"; font-size: 1.35rem; font-weight: 400; color: var(--ps-brand-dark); transition: transform .2s ease; }
.ps-faq[open] > summary::after { transform: rotate(45deg); }
.ps-faq__body { padding: 0 1.35rem 1.25rem; color: var(--ps-ink-soft); font-size: .94rem; line-height: 1.65; }

/* ── Scroll reveal ───────────────────────────────────────────────────────────
   The animated state is applied by JS only after IntersectionObserver confirms
   support. Without JS the content is simply visible — an animation that fails
   open is a page that never appears. */
.ps-reveal { opacity: 1; }
.ps-js .ps-reveal { opacity: 0; transform: translateY(18px); transition: opacity .55s ease, transform .55s ease; }
.ps-js .ps-reveal.is-visible { opacity: 1; transform: none; }

/* Every animation in this file is switched off by one query. Motion sensitivity
   is not a preference to be overridden by a marketing page. */
@media (prefers-reduced-motion: reduce) {
    .ps *, .ps *::before, .ps *::after {
        animation-duration: .001ms !important; animation-iteration-count: 1 !important;
        transition-duration: .001ms !important; scroll-behavior: auto !important;
    }
    .ps-js .ps-reveal { opacity: 1; transform: none; }
}

/* ── Header ──────────────────────────────────────────────────────────────── */
.ps-header {
    position: sticky; top: 0; z-index: 1000;
    background: rgba(255, 255, 255, .82); backdrop-filter: saturate(180%) blur(16px); -webkit-backdrop-filter: saturate(180%) blur(16px);
    border-bottom: 1px solid transparent; transition: border-color .2s ease, box-shadow .2s ease;
}
.ps-header.is-stuck { border-bottom-color: var(--ps-line); box-shadow: 0 4px 20px -12px rgba(11, 18, 32, .25); }
.ps-header__inner { display: flex; align-items: center; gap: 1.25rem; min-height: 68px; }
.ps-logo { display: flex; align-items: center; gap: .6rem; font-weight: 850; font-size: 1.05rem; letter-spacing: -.02em; }
.ps-logo img { height: 34px; width: auto; }

.ps-nav { display: flex; align-items: center; gap: .25rem; margin-inline-start: auto; }
.ps-nav__link {
    padding: .6rem .85rem; border-radius: 10px; font-size: .93rem; font-weight: 600; color: var(--ps-ink-soft);
    transition: color .16s ease, background-color .16s ease;
}
.ps-nav__link:hover, .ps-nav__link[aria-current="page"] { color: var(--ps-brand-dark); background: var(--ps-brand-soft); }
.ps-header__cta { display: flex; align-items: center; gap: .6rem; margin-inline-start: .75rem; }

/* Mega menu — a <details> so it opens without JS and closes with Escape natively. */
.ps-mega { position: relative; }
.ps-mega > summary { list-style: none; cursor: pointer; }
.ps-mega > summary::-webkit-details-marker { display: none; }
.ps-mega__panel {
    position: absolute; top: calc(100% + .6rem); inset-inline-start: 50%; transform: translateX(-50%);
    width: min(92vw, 720px); background: #fff; border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius-lg); box-shadow: var(--ps-shadow-lg); padding: 1.35rem;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .35rem;
}
.ps-mega__item { display: flex; gap: .8rem; padding: .8rem; border-radius: 12px; transition: background-color .15s ease; }
.ps-mega__item:hover { background: var(--ps-surface-alt); }
.ps-mega__item i { color: var(--ps-brand-dark); font-size: 1rem; margin-top: .15rem; }
.ps-mega__item strong { display: block; font-size: .92rem; font-weight: 700; }
.ps-mega__item span { font-size: .82rem; color: var(--ps-ink-muted); }

.ps-burger { display: none; background: none; border: none; font-size: 1.3rem; color: var(--ps-ink); cursor: pointer; padding: .5rem; margin-inline-start: auto; }

@media (max-width: 960px) {
    .ps-burger { display: block; }
    .ps-nav {
        position: fixed; inset: 68px 0 auto; flex-direction: column; align-items: stretch; gap: .15rem;
        background: #fff; border-bottom: 1px solid var(--ps-line); padding: 1rem var(--ps-gutter) 1.5rem;
        margin: 0; max-height: calc(100dvh - 68px); overflow-y: auto;
        transform: translateY(-12px); opacity: 0; visibility: hidden; transition: all .22s ease;
    }
    .ps-nav.is-open { transform: none; opacity: 1; visibility: visible; }
    .ps-mega__panel { position: static; transform: none; width: 100%; box-shadow: none; border: none; padding: .35rem 0 .35rem 1rem; }
    .ps-header__cta { margin: .75rem 0 0; flex-direction: column; align-items: stretch; }
    .ps-header__cta .ps-btn { width: 100%; }
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.ps-footer { background: var(--ps-surface-deep); color: rgba(255, 255, 255, .72); padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem) 2rem; }
.ps-footer h4 { color: #fff; font-size: .82rem; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 1rem; }
.ps-footer a { color: rgba(255, 255, 255, .72); font-size: .9rem; display: inline-block; padding: .3rem 0; transition: color .15s ease; }
.ps-footer a:hover { color: #fff; }
.ps-footer__bottom { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid rgba(255, 255, 255, .1); display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; font-size: .85rem; }

/* ── Skip link — the first thing in the tab order, invisible until focused ── */
.ps-skip {
    position: absolute; inset-inline-start: -9999px; top: 0; z-index: 1100;
    background: var(--ps-ink); color: #fff; padding: .85rem 1.25rem; border-radius: 0 0 10px 0; font-weight: 700;
}
.ps-skip:focus { inset-inline-start: 0; color: #fff; }

/* ── Floating CTA (mobile) ───────────────────────────────────────────────── */
.ps-float { display: none; }
@media (max-width: 720px) {
    .ps-float {
        display: flex; position: fixed; inset-inline: var(--ps-gutter); bottom: 1rem; z-index: 900;
        gap: .6rem;
    }
    .ps-float .ps-btn { flex: 1; box-shadow: var(--ps-shadow-lg); }
    .ps-footer { padding-bottom: 5.5rem; }
}

/* =============================================================================
   Auth cards: registration and OTP confirmation                    (Phase 659)
   =============================================================================
   The public site had no form styling of any kind — every page up to now was
   read-only marketing, so .ps-field, .ps-input and .ps-alert simply did not
   exist. Direct User registration is the first public page that asks for
   anything, and an unstyled form on an otherwise finished site reads as broken
   rather than plain.

   Built from the same tokens as everything above, so it inherits the palette,
   radius and shadow rather than restating them.
   ========================================================================== */

.ps-auth {
    display: flex;
    justify-content: center;
}

.ps-auth__card {
    width: 100%;
    max-width: 30rem;
    margin: 0 auto;
    padding: 2.5rem;
    background: #fff;
    border: 1px solid var(--ps-line-soft);
    border-radius: var(--ps-radius-lg);
    box-shadow: var(--ps-shadow);
}

.ps-auth__title {
    font-size: var(--ps-display-sm);
    margin: 0 0 .5rem;
}

.ps-auth__lede {
    color: var(--ps-ink-muted);
    margin: 0 0 1.75rem;
}

.ps-auth__alt {
    margin: 1.5rem 0 0;
    text-align: center;
    color: var(--ps-ink-muted);
    font-size: .95rem;
}

.ps-auth__resend {
    margin-top: .75rem;
}

/* ── Fields ─────────────────────────────────────────────────────────────── */

.ps-field {
    margin-bottom: 1.15rem;
}

.ps-label {
    display: block;
    margin-bottom: .4rem;
    font-weight: 600;
    font-size: .9rem;
    color: var(--ps-ink);
}

.ps-input {
    display: block;
    width: 100%;
    padding: .8rem 1rem;
    font-family: inherit;
    font-size: 1rem;
    color: var(--ps-ink);
    background: #fff;
    border: 1.5px solid var(--ps-line);
    border-radius: var(--ps-radius-sm);
    transition: border-color .18s ease, box-shadow .18s ease;
    /* Matches the 44px pointer target the buttons already commit to. */
    min-height: 44px;
}

.ps-input:focus {
    outline: none;
    border-color: var(--ps-brand);
    /* A visible focus ring, not just a colour change — the colour alone fails
       WCAG 1.4.11 for anyone who cannot distinguish it. */
    box-shadow: 0 0 0 3px var(--ps-brand-soft);
}

/* The 6-digit code: spaced and centred so it reads as digits being counted,
   not as a word. */
.ps-input--code {
    text-align: center;
    letter-spacing: .5em;
    /* The letter-spacing is applied after the last character too, which pushes
       the visual centre left; the indent puts it back. */
    text-indent: .5em;
    font-size: 1.35rem;
    font-weight: 700;
}

.ps-field__error {
    display: block;
    margin-top: .35rem;
    font-size: .85rem;
    color: #b42318;
}

/* Server-side validation marks invalid inputs with this class. */
.ps-input.input-validation-error {
    border-color: #b42318;
}

/* ── Alerts ─────────────────────────────────────────────────────────────── */

.ps-alert {
    padding: .85rem 1.1rem;
    margin-bottom: 1.25rem;
    border-radius: var(--ps-radius-sm);
    font-size: .92rem;
    border: 1px solid transparent;
}

.ps-alert--error {
    background: #fef3f2;
    border-color: #fda29b;
    color: #912018;
}

.ps-alert--info {
    background: #eff8ff;
    border-color: #b2ddff;
    color: #175cd3;
}

/* ── Full-width button ──────────────────────────────────────────────────── */

.ps-btn--block {
    display: flex;
    width: 100%;
}

.ps-btn[disabled] {
    opacity: .55;
    cursor: not-allowed;
    transform: none;
}

@media (max-width: 480px) {
    .ps-auth__card { padding: 1.75rem 1.25rem; }
}

/* =============================================================================
   PLATFORM PAGE COMPONENTS                                          Phase 710
   -----------------------------------------------------------------------------
   WHY THIS BLOCK EXISTS. The nine pages under the Platform menu were written with
   their design inline: every card, list, badge and table cell carried its own
   style="" attribute. Three costs followed, and this block removes all three at once.

     1. HTML WEIGHT. The markup was mostly presentation — a feature card spent more
        characters on styling than on words. The pages below now read as content.
     2. NO SHARED LOOK. Two pages solving the same problem (a list with ticks, a
        highlighted card) each invented it, so nothing quite matched and nothing
        could be improved in one place. Every rule here is used by several pages.
     3. NOTHING COULD BE IMPROVED. An inline style beats any stylesheet, so the
        pages could not be made to look better without editing all nine. That is
        exactly why they looked plainer than the home page.

   RESPONSIVE BY CONSTRUCTION. No component below states a pixel width. Sizes come
   from clamp(), columns from auto-fit/minmax, and the only media query is the one
   place a table has to become a card. That is what makes these pages work from
   360px up without a per-page breakpoint.
   ============================================================================= */

/* ── Section header: eyebrow + heading + lede ─────────────────────────────────
   Repeated on nearly every section, previously as .ps-center with an inline
   margin-bottom that differed page to page (2rem here, 1.5 there). */
.ps-section-head { text-align: center; margin-bottom: clamp(2rem, 1.4rem + 1.6vw, 3rem); }
.ps-section-head .ps-lead { margin-inline: auto; }
.ps-section-head > :last-child { margin-bottom: 0; }

/* Constrains prose-width sections. Replaces style="max-width:820px|900px" — one
   measure, so the reading line is the same on every page that uses it. */
.ps-narrow { max-width: 900px; }
.ps-narrow--tight { max-width: 820px; }

/* ── Tick / bullet lists ─────────────────────────────────────────────────────
   Was a flex row with an inline-styled <i> per item, restated on four pages. The
   marker is drawn with ::before so the markup is a plain <li> — the list reads as
   a list to a screen reader and to anyone editing it. */
.ps-checks { display: grid; gap: .55rem; margin: 0 0 1.1rem; padding: 0; list-style: none; }
.ps-checks li {
    position: relative; padding-left: 1.75rem;
    font-size: .92rem; line-height: 1.55; color: var(--ps-ink-soft);
}
.ps-checks li::before {
    content: "\f058";                      /* fa-circle-check */
    font-family: "Font Awesome 6 Pro", "Font Awesome 6 Free", "Font Awesome 5 Pro", "Font Awesome 5 Free", sans-serif;
    font-weight: 900;
    position: absolute; left: 0; top: .05em;
    color: var(--ps-brand);
}
.ps-checks--sm li { font-size: .88rem; }
/* The honest half of a comparison: what a thing does NOT do. */
.ps-checks--minus li { color: var(--ps-ink-muted); }
.ps-checks--minus li::before { content: "\f068"; color: #d97706; font-size: .72em; top: .3em; }
.ps-checks--plain li::before { content: "\f00c"; }   /* bare tick, no circle */

/* ── Kicker: the small uppercase label above a sub-list ──────────────────── */
.ps-kicker {
    font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ps-ink-faint); margin-bottom: .45rem;
}
.ps-kicker--pos { color: #047857; }
.ps-kicker--neg { color: #b45309; }

/* ── Note: the "In practice:" band under a feature ────────────────────────── */
.ps-note {
    background: var(--ps-surface-alt);
    border-left: 3px solid var(--ps-brand);
    border-radius: 0 var(--ps-radius-sm) var(--ps-radius-sm) 0;
    padding: .85rem 1.05rem; font-size: .9rem; margin: 0; color: var(--ps-ink-soft);
}
.ps-note strong { color: var(--ps-ink); }

/* ── Callout: an editorial warning that is not part of the product ────────── */
.ps-callout { background: #fffbeb; border-color: #fde68a; }
.ps-callout p { margin: 0; font-size: .9rem; color: #92400e; }

/* ── Feature card ────────────────────────────────────────────────────────────
   PREMIUM WITHOUT NOISE. The card earns its look from three cheap things rather
   than from decoration: a gradient hairline that wipes across the top on hover, a
   gradient-filled icon tile, and a lift. Everything transitions, nothing moves on
   load, and the whole effect is disabled under prefers-reduced-motion below. */
.ps-feature { position: relative; overflow: hidden; height: 100%; }
.ps-feature::before {
    content: ""; position: absolute; inset: 0 0 auto; height: 3px;
    background: var(--ps-gradient);
    transform: scaleX(0); transform-origin: left;
    transition: transform .35s cubic-bezier(.4, 0, .2, 1);
}
.ps-feature:hover::before { transform: scaleX(1); }
.ps-feature:hover { transform: translateY(-4px); box-shadow: var(--ps-shadow); border-color: transparent; }
.ps-feature__head { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1rem; }
.ps-feature__head .ps-card__icon { margin-bottom: 0; flex-shrink: 0; }
.ps-feature__tag {
    display: block; font-size: .72rem; font-weight: 800; letter-spacing: .08em;
    text-transform: uppercase; color: var(--ps-ink-faint); margin-bottom: .25rem;
}
.ps-feature__title { font-size: 1.2rem; font-weight: 750; line-height: 1.3; margin: 0; }
.ps-feature > p { margin-bottom: 1.1rem; }

/* Gradient icon tile — the single strongest "premium" cue on these pages, because
   it is the only saturated colour in an otherwise quiet card. */
.ps-card__icon--grad { background: var(--ps-gradient); color: #fff; box-shadow: var(--ps-shadow-brand); }

/* ── Accent card: the one option a comparison is steering toward ─────────── */
.ps-card--accent { border-color: var(--ps-brand); box-shadow: var(--ps-shadow); }
.ps-card--muted { background: var(--ps-surface-alt); }
/* A card that is a flex column so its button can sit on the bottom edge however
   long the copy above it runs — this is what makes a row of tiers line up. */
.ps-card--stack { display: flex; flex-direction: column; height: 100%; }
.ps-card--stack .ps-checks { flex: 1; }

/* ── Pricing tier ────────────────────────────────────────────────────────── */
.ps-price { position: relative; }
.ps-price--popular { border-color: var(--ps-brand); box-shadow: var(--ps-shadow); }
.ps-price__badge {
    position: absolute; top: -.75rem; left: 50%; transform: translateX(-50%);
    background: var(--ps-gradient); color: #fff; white-space: nowrap;
    font-size: .68rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    padding: .35rem .85rem; border-radius: var(--ps-radius-pill);
    box-shadow: var(--ps-shadow-brand);
}
.ps-price__amount { display: flex; align-items: baseline; gap: .4rem; margin: .5rem 0 .25rem; }
.ps-price__figure { font-size: clamp(1.9rem, 1.5rem + 1.2vw, 2.4rem); font-weight: 850; letter-spacing: -.03em; line-height: 1; }
.ps-price__unit { font-size: .85rem; color: var(--ps-ink-muted); }
.ps-price__blurb { font-size: .9rem; }

/* ── Comparison table ────────────────────────────────────────────────────────
   The wrapper scrolls, not the page: a wide table inside a fixed-width card is the
   most common cause of a whole page scrolling sideways on a phone. */
.ps-table-wrap { padding: 0; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ps-table { width: 100%; border-collapse: collapse; font-size: .92rem; min-width: 620px; }
.ps-table thead tr { background: var(--ps-surface-alt); }
.ps-table th, .ps-table td { padding: .95rem 1.15rem; text-align: left; }
.ps-table thead th { font-size: .8rem; font-weight: 750; }
.ps-table tbody tr { border-top: 1px solid var(--ps-line); }
.ps-table tbody tr:hover { background: var(--ps-surface-alt); }
.ps-table tbody th { font-weight: 700; color: var(--ps-ink); }
.ps-table td { color: var(--ps-ink-muted); }
/* The column the table is arguing for. */
.ps-table .ps-col-us, .ps-table thead .ps-col-us { color: var(--ps-brand-dark); font-weight: 650; }
.ps-table thead .ps-col-us { background: var(--ps-brand-soft); }

/* Below the table's own min-width there is no room for columns at all, so each row
   becomes a small stacked card. This is the only breakpoint in the file. */
@media (max-width: 640px) {
    .ps-table { min-width: 0; }
    .ps-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
    .ps-table tbody tr { display: block; padding: .35rem 0; }
    .ps-table tbody th { display: block; padding-bottom: .35rem; }
    .ps-table tbody td { display: flex; gap: .75rem; padding: .3rem 1.15rem; }
    .ps-table tbody td::before {
        content: attr(data-label);
        flex: 0 0 42%; font-size: .78rem; font-weight: 700; color: var(--ps-ink-faint);
        text-transform: uppercase; letter-spacing: .05em;
    }
}

/* ── Numbered steps ──────────────────────────────────────────────────────── */
.ps-step { position: relative; padding-left: 3.25rem; }
.ps-step__n {
    position: absolute; left: 0; top: 0;
    width: 2.25rem; height: 2.25rem; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--ps-brand-soft); color: var(--ps-brand-dark);
    font-weight: 800; font-size: .95rem;
}

/* ── Code sample (Developers) ────────────────────────────────────────────── */
.ps-code {
    background: var(--ps-surface-deep); color: #e2e8f0;
    border-radius: var(--ps-radius); padding: 1.1rem 1.25rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .84rem; line-height: 1.6; overflow-x: auto; margin: 0;
}
.ps-code .tok-key { color: #7bead0; }
.ps-code .tok-str { color: #fcd34d; }

/* ── Logo / integration tile ─────────────────────────────────────────────── */
.ps-tile {
    display: flex; align-items: center; gap: .75rem;
    padding: .9rem 1.05rem; border: 1px solid var(--ps-line);
    border-radius: var(--ps-radius-sm); background: var(--ps-surface);
    font-weight: 650; font-size: .92rem;
    transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.ps-tile:hover { border-color: var(--ps-brand); transform: translateY(-2px); box-shadow: var(--ps-shadow-sm); }
.ps-tile i { color: var(--ps-brand-dark); font-size: 1.05rem; width: 1.25rem; text-align: center; }

/* ── Small helpers that were inline on every page ────────────────────────── */
.ps-mt { margin-top: clamp(1.5rem, 1rem + 1.5vw, 2rem); }
.ps-mb-0 { margin-bottom: 0; }
.ps-stretch { align-items: stretch; }
.ps-gap-lg { gap: clamp(1.5rem, 1rem + 1.6vw, 2.5rem); }

/* Motion is an enhancement. Anyone who has asked their OS for less of it gets the
   same layout with nothing that moves. */
@media (prefers-reduced-motion: reduce) {
    .ps-feature::before { transition: none; }
    .ps-feature:hover, .ps-tile:hover { transform: none; }
}

/* =============================================================================
   PAGE HERO + CLOSING CTA — the two surfaces every Platform page shares
                                                                     Phase 712
   -----------------------------------------------------------------------------
   These are the first and last thing a visitor sees on nine pages, and both were
   the plainest things on them: a heading on flat white, and a solid green band.
   Because they are shared partials, everything here lifts all nine pages at once —
   which is why this is where the "make it look premium" budget is best spent.

   The depth is built from gradients and one repeating-linear-gradient, not images:
   nothing extra to download, nothing to go stale, and it scales to any width.
   ============================================================================= */

.ps-page-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: linear-gradient(180deg, #fff 0%, var(--ps-surface-alt) 100%);
    border-bottom: 1px solid var(--ps-line-soft);
}

/* Aurora wash — two soft brand-coloured pools, offset so the light reads as coming
   from the top-left. Sits behind the text via z-index on an isolated stacking context. */
.ps-page-hero::before {
    content: "";
    position: absolute;
    inset: -40% -10% auto -10%;
    height: 150%;
    z-index: -2;
    background:
        radial-gradient(680px 340px at 12% 0%, rgba(26, 179, 148, .18), transparent 62%),
        radial-gradient(560px 300px at 82% 8%, rgba(14, 115, 97, .13), transparent 65%);
}

/* A very faint diagonal hatch. At 3% alpha it is not consciously visible — it just
   stops the background reading as flat, which is most of the difference between
   "a web page" and "a product page". */
.ps-page-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: repeating-linear-gradient(115deg,
        rgba(11, 18, 32, .03) 0 1px, transparent 1px 22px);
    -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 78%);
            mask-image: linear-gradient(180deg, #000 0%, transparent 78%);
}

.ps-crumb { font-size: .82rem; color: var(--ps-ink-faint); margin-bottom: 1rem; }
.ps-crumb a { color: var(--ps-ink-muted); }
.ps-crumb a:hover { color: var(--ps-brand-dark); }
.ps-crumb span[aria-hidden] { margin: 0 .35rem; opacity: .6; }

.ps-hero__title {
    font-size: var(--ps-display-xl);
    line-height: 1.06;
    letter-spacing: -.03em;
    max-width: 18ch;
    margin-bottom: .75rem;
}
/* The lede is wider than the heading measure but still a comfortable line. */
.ps-page-hero .ps-lead { max-width: 58ch; }

/* ── Closing CTA ───────────────────────────────────────────────────────────
   Was a flat fill of the brand gradient. Now the deep ink gradient with the brand
   pooled into it, which makes the white type sit on something with depth and lets
   the buttons carry the brand colour instead of competing with the background. */
.ps-cta {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--ps-gradient-deep);
    color: #fff;
}
.ps-cta::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(620px 320px at 18% 110%, rgba(26, 179, 148, .40), transparent 60%),
        radial-gradient(520px 300px at 85% -20%, rgba(14, 115, 97, .34), transparent 62%);
}
.ps-cta__title { color: #fff; margin-bottom: .6rem; }
.ps-cta__lead { color: rgba(255, 255, 255, .82); max-width: 52ch; margin: 0 auto 1.6rem; }

/* A button row that centres, wraps and keeps its gap — replaces the inline flex
   repeated in the partial. */
.ps-btn-row { display: flex; gap: .75rem; flex-wrap: wrap; }
.ps-btn-row--center { justify-content: center; }

/* The primary action ON the dark band: solid white, brand ink. Highest possible
   contrast against the gradient, which is what a final CTA wants. */
.ps-btn--on-deep { background: #fff; color: var(--ps-brand-deep); }
.ps-btn--on-deep:hover { background: #fff; color: var(--ps-brand-deep); transform: translateY(-2px); box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .5); }

@media (prefers-reduced-motion: reduce) {
    .ps-btn--on-deep:hover { transform: none; }
}

/* =============================================================================
   BUTTON INK — specificity repair                                   Phase 712
   -----------------------------------------------------------------------------
   A REAL BUG, found by rendering rather than by reading. Every button colour is
   declared on a single class — `.ps-btn--primary { color: #fff }` — which scores
   (0,1,0). But the reset a few hundred lines above sets

       .ps a { color: inherit }        (0,1,1)  <- element + class

   and every one of these buttons IS an <a>. (0,1,1) beats (0,1,0), so the reset
   won and the buttons took their colour from whatever section they sat in.
   Measured on the live stylesheet:

       .ps-btn--dark   on a light section   #0b1220 text on a #0b1220 fill  (invisible)
       .ps-btn--primary on a light section  dark ink on the brand gradient  (low contrast)
       .ps-btn--on-deep on the dark band    #fff text on a #fff fill        (invisible)

   Restating each colour at `.ps a.ps-btn--*` — (0,2,1) — puts the intended value
   back on top. Written as a separate block, rather than by editing the originals,
   so the rule that was actually beating them stays visible next to the repair;
   raising the originals' specificity in place would have hidden the reason.
   !important was avoided deliberately: it would win here but would also block a
   page from ever overriding a button, which these pages legitimately do.
   ============================================================================= */
.ps a.ps-btn--primary { color: #fff; }
.ps a.ps-btn--dark { color: #fff; }
.ps a.ps-btn--ghost { color: var(--ps-ink); }
.ps a.ps-btn--ghost:hover { color: var(--ps-brand-dark); }
.ps a.ps-btn--on-dark { color: #fff; }
.ps a.ps-btn--on-deep { color: var(--ps-brand-deep); }
