
        /* =====================================================
           Same style system as the rest of the site
           ===================================================== */
        *, *::before, *::after {
            box-sizing: border-box;
        }

        html {
            scroll-behavior: smooth;
            /* Safari on iOS inflates text inside any block wider than the viewport,
               so a page carrying a wide diagram gets larger body copy than a page
               without one — which is why Barcrest and OneFile did not match Software
               Creations on a phone despite identical type rules. The diagrams still
               scroll sideways inside their own figure; only the automatic inflation
               is switched off, so every page now sizes text the same way. */
            -webkit-text-size-adjust: 100%;
            text-size-adjust: 100%;
        }

        body {
            margin: 0;
            font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
            line-height: 1.5;
            color: #111;
            background: #fff;
        }

        img {
            max-width: 100%;
            display: block;
        }

        a {
            color: inherit;
            text-decoration: none;
        }

        a:focus-visible {
            outline: 3px solid #111;
            outline-offset: 2px;
        }

        .container {
            width: min(1100px, 100% - 2rem);
            margin-inline: auto;
        }

        .sr-only {
            position: absolute;
            width: 1px;
            height: 1px;
            padding: 0;
            margin: -1px;
            overflow: hidden;
            clip: rect(0, 0, 0, 0);
            white-space: nowrap;
            border: 0;
        }

        /* Parallax background layers */
        .parallax-layer {
            position: fixed;
            inset: 0;
            z-index: -3;
            background-size: cover;
            background-position: center;
            transform: translate3d(0, 0, 0);
            will-change: transform;
        }

        .parallax-layer.layer-1 {
            z-index: -3;
            opacity: 0.75;
        }

        .parallax-layer.layer-3 {
            z-index: -1;
            opacity: 0.20;
            mix-blend-mode: overlay;
        }

        .page-overlay {
            position: fixed;
            inset: 0;
            z-index: -1;
            pointer-events: none;
            background: linear-gradient(180deg, rgba(0, 0, 0, .50), rgba(0, 0, 0, .15) 45%, rgba(255, 255, 255, .85) 78%, rgba(255, 255, 255, .98));
        }

        /* Hero */
        header.hero {
            padding-top: 1rem;
        }

        .hero-card {
            border-radius: 18px;
            overflow: hidden;
            box-shadow: 0 16px 40px rgba(0, 0, 0, .18);
            background: rgba(255, 255, 255, .92);
            backdrop-filter: blur(6px);
        }

        .hero-media {
            position: relative;
            min-height: 260px;
            display: flex;
            align-items: flex-start;
        }

        .hero-media img {
            width: 100%;
            height: clamp(260px, 42vw, 420px);
            object-fit: cover;
            display: block;
        }

        .hero-media img:not(.hero-overlay-img) {
            flex: 1 1 0%;
            min-width: 0;
        }

        .hero-media .hero-overlay-img {
            position: absolute;
            top: 1.2rem;
            left: 1.2rem;
            width: auto;
            height: 60%;
            object-fit: contain;
            background: #fff;
            border-radius: 16px;
            padding: 10px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.10);
            pointer-events: none;
            z-index: 2;
            opacity: 0.98;
            border: 1px solid #eee;
        }

        .hero-badge {
            position: absolute;
            inset: auto 1rem 1rem 1rem;
            z-index: 3;
            color: #fff;
            background: rgba(0, 0, 0, .55);
            padding: .85rem 1rem;
            border-radius: 14px;
            max-width: 70ch;
            box-shadow: 0 10px 24px rgba(0, 0, 0, .25);
        }

        .hero-badge h1 {
            margin: 0 0 .35rem;
            font-size: clamp(1.25rem, 2.2vw + .6rem, 2.4rem);
            line-height: 1.15;
        }

        .hero-badge p {
            margin: 0;
            opacity: .95;
        }

        @media (max-width: 900px) {
            .hero-media .hero-overlay-img {
                width: 68px;
                height: 68px;
                top: .7rem;
                left: .7rem;
                padding: 7px;
            }
        }

        @media (max-width: 560px) {
            .hero-media .hero-overlay-img {
                width: 48px;
                height: 48px;
                top: .4rem;
                left: .4rem;
                padding: 4px;
            }
        }

        /* Primary link bar */
        nav.primary-links {
            background: rgba(255, 255, 255, .92);
            border-top: 1px solid rgba(0, 0, 0, .08);
            padding: .75rem;
        }

        .link-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
            gap: .5rem;
        }

        .link-grid a {
            display: grid;
            place-items: center;
            text-align: center;
            line-height: 1.25;
            padding: .55rem .4rem;
            border-radius: 12px;
            background: rgba(0, 0, 0, .04);
            font-size: .9rem;
            transition: transform .12s ease, background .12s ease;
        }

        /* The second line of a menu item: what the page is, for anybody who cannot tell from a
           one-word label. Small and quiet, so the label still reads as the link. */
        .link-grid a small {
            display: block;
            font-size: .72rem;
            font-weight: 400;
            opacity: .62;
            margin-top: .1rem;
        }


        .link-grid a:hover {
            background: rgba(0, 0, 0, .07);
            transform: translateY(-1px);
        }

        .link-grid a[aria-current="page"] {
            background: #111;
            color: #fff;
        }


        /* =====================================================
           Breadcrumb - sits under the primary links in the header
           ===================================================== */
        nav.breadcrumb {
            background: rgba(255, 255, 255, .92);
            border-top: 1px solid rgba(0, 0, 0, .08);
            padding: .55rem .9rem;
        }

        nav.breadcrumb ol {
            list-style: none;
            margin: 0;
            padding: 0;
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            gap: .1rem .45rem;
            font-size: .88rem;
        }

        nav.breadcrumb li {
            display: flex;
            align-items: center;
            gap: .45rem;
            color: rgba(0, 0, 0, .62);
        }

        nav.breadcrumb li + li::before {
            content: "/";
            color: rgba(0, 0, 0, .3);
        }

        nav.breadcrumb a {
            border-radius: 6px;
        }

        nav.breadcrumb a:hover {
            text-decoration: underline;
        }

        nav.breadcrumb [aria-current="page"] {
            color: #111;
            font-weight: 600;
        }

        /* Sections */
        main {
            padding: 1.25rem 0 2.5rem;
        }

        .section {
            margin-top: 1.1rem;
            background: rgba(255, 255, 255, .92);
            border: 1px solid rgba(0, 0, 0, .08);
            border-radius: 18px;
            overflow: hidden;
            box-shadow: 0 12px 28px rgba(0, 0, 0, .12);
        }

        .section-inner {
            padding: 1.25rem;
        }

        .section h2 {
            margin: 0 0 .75rem;
            font-size: 1.35rem;
            line-height: 1.2;
        }

        .muted {
            color: rgba(0, 0, 0, .72);
        }

        /* =====================================================
           iPhone frame — wraps a 1290x2796 screenshot
           ===================================================== */
        .phone {
            position: relative;
            display: block;
            width: 100%;
            background: #101114;
            border-radius: 13.5% / 6.2%;
            padding: 2.6%;
            box-shadow: 0 14px 30px rgba(0, 0, 0, .30), 0 0 0 1px rgba(255, 255, 255, .12) inset;
        }

        .phone img {
            width: 100%;
            height: auto;
            display: block;
            border-radius: 11% / 5.2%;
            background: #fff;
        }

        /* Dynamic island */
        .phone::after {
            content: "";
            position: absolute;
            top: 2.4%;
            left: 50%;
            transform: translateX(-50%);
            width: 27.6%;
            height: 3.8%;
            background: #101114;
            border-radius: 999px;
        }


        /* Every published screenshot is padded to one of two shapes now -
           the portrait iPhone frame, or that frame turned on its side - so
           the ratio and letterboxing that used to live here is baked into
           the images themselves. What is left is the frame itself. */

        .phone--fit::after {
            display: none;
        }


        /* =====================================================
           App cards — the whole card is a link
           ===================================================== */
        /* Jump list — twelve cards is a long scroll, so offer the way straight to one. */
        .app-jump {
            display: flex;
            flex-wrap: wrap;
            gap: 1rem 2.4rem;
            margin: 0 0 2rem;
            padding: 1.1rem 1.3rem;
            background: var(--fc-off-white);
            border: 1px solid var(--fc-line);
            border-radius: var(--fc-radius);
        }

        .app-jump-group {
            display: flex;
            flex-wrap: wrap;
            align-items: baseline;
            gap: .55rem .7rem;
            min-width: 0;
        }

        .app-jump-label {
            font-size: .72rem;
            font-weight: 800;
            letter-spacing: .12em;
            text-transform: uppercase;
            color: var(--fc-blue);
            flex: none;
        }

        .app-jump ul {
            display: flex;
            flex-wrap: wrap;
            gap: .45rem;
            list-style: none;
            margin: 0;
            padding: 0;
        }

        .app-jump a {
            display: inline-block;
            padding: .34rem .7rem;
            border: 1px solid var(--fc-line);
            border-radius: 999px;
            background: #fff;
            color: var(--fc-ink);
            font-size: .88rem;
            font-weight: 600;
            text-decoration: none;
            white-space: nowrap;
        }

        .app-jump a:hover,
        .app-jump a:focus-visible {
            background: var(--fc-blue);
            border-color: var(--fc-blue);
            color: #fff;
        }

        /* Stops a jumped-to card sitting flush against the top of the window. */
        .app-card[id] {
            scroll-margin-top: 1.5rem;
        }

        .app-list {
            display: grid;
            gap: 1.1rem;
            margin-top: 1rem;
        }

        .app-card {
            display: block;
            border: 1px solid rgba(0, 0, 0, .08);
            border-radius: 18px;
            background: #fff;
            overflow: hidden;
            transition: transform .14s ease, box-shadow .14s ease;
        }

        .app-card:hover,
        .app-card:focus-visible {
            transform: translateY(-3px);
            box-shadow: 0 18px 36px rgba(0, 0, 0, .16);
        }

        .app-card-inner {
            display: grid;
            grid-template-columns: minmax(280px, 46%) 1fr;
            gap: 1.5rem;
            align-items: center;
            padding: 1.25rem;
        }

        /* Fan of three phones */
        /* Three phones, overlapped so each one can be bigger
           than an even three-column split would allow.
           42% each, overlapping 13% either side, fills the row exactly. */
        .shot-fan {
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .shot-fan .phone {
            flex: 0 0 42%;
        }

        .shot-fan .phone:nth-child(1) {
            transform: rotate(-5deg) translateY(8px) scale(.93);
            margin-right: -13%;
        }

        .shot-fan .phone:nth-child(3) {
            transform: rotate(5deg) translateY(8px) scale(.93);
            margin-left: -13%;
        }

        .shot-fan .phone:nth-child(2) {
            z-index: 2;
        }

        .app-meta h3 {
            margin: 0 0 .3rem;
            font-size: 1.5rem;
            line-height: 1.15;
        }

        .app-platform {
            display: inline-block;
            font-size: .78rem;
            letter-spacing: .06em;
            text-transform: uppercase;
            color: rgba(0, 0, 0, .6);
            border: 1px solid rgba(0, 0, 0, .14);
            border-radius: 999px;
            padding: .18rem .6rem;
            margin-bottom: .7rem;
        }

        .feature-chips {
            display: flex;
            flex-wrap: wrap;
            gap: .4rem;
            margin: .9rem 0 1rem;
            padding: 0;
            list-style: none;
        }

        .feature-chips li {
            font-size: .88rem;
            background: rgba(0, 0, 0, .05);
            border: 1px solid rgba(0, 0, 0, .08);
            border-radius: 999px;
            padding: .3rem .7rem;
        }

        /* The price, under the chips and above the call to action. Small and quiet:
           it is a fact somebody scanning the page wants without hunting, not a sell. */
        .app-price {
            margin: .55rem 0 0;
            font-size: .88rem;
            color: rgba(0, 0, 0, .62);
            font-variant-numeric: tabular-nums;
        }

        /* "Free" and "Subscription" carry the line — somebody scanning the page should
           see that there is a free half before they see a price. */
        .app-price b {
            color: rgba(0, 0, 0, .82);
            font-weight: 600;
        }

        /* The two halves are separate paragraphs rather than spans told to behave like
           blocks: a paragraph is block-level on its own, so the two lines survive even
           if this stylesheet is stale in somebody's cache. This only closes the gap
           between them so they still read as a pair. */
        .app-price--sub {
            margin-top: .12rem;
        }

        .cta {
            display: inline-flex;
            align-items: center;
            gap: .45rem;
            font-weight: 600;
            background: #111;
            color: #fff;
            border-radius: 12px;
            padding: .6rem .95rem;
        }

        .app-card:hover .cta {
            background: #000;
        }

        /* Footer links block */
        footer {
            padding: 1.25rem 0 2rem;
        }

        .footer-links {
            background: rgba(255, 255, 255, .92);
            border: 1px solid rgba(0, 0, 0, .08);
            border-radius: 18px;
            box-shadow: 0 12px 28px rgba(0, 0, 0, .12);
            overflow: hidden;
        }

        .all-links {
            display: grid;
            grid-template-columns: repeat(5, 1fr);
            gap: .65rem;
            margin-top: .75rem;
        }

        .all-links a {
            display: block;
            padding: .5rem .6rem;
            border-radius: 12px;
            background: rgba(0, 0, 0, .04);
            font-size: .92rem;
        }

        .all-links a:hover {
            background: rgba(0, 0, 0, .07);
        }

        /* Mobile responsiveness */
        @media (max-width: 900px) {
            .link-grid {
                grid-template-columns: repeat(5, 1fr);
            }

            .app-card-inner {
                grid-template-columns: 1fr;
                gap: 1.1rem;
            }

            .shot-fan {
                max-width: 420px;
                margin-inline: auto;
            }

            .all-links {
                grid-template-columns: repeat(3, 1fr);
            }
        }

        @media (max-width: 560px) {
            .link-grid {
                display: flex;
                overflow-x: auto;
                gap: .5rem;
                padding-bottom: .25rem;
                scroll-snap-type: x mandatory;
            }

            .link-grid a {
                flex: 0 0 auto;
                min-width: 120px;
                scroll-snap-align: start;
                padding: .7rem .8rem;
                font-size: .95rem;
            }

            .all-links {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        @media (prefers-reduced-motion: reduce) {
            html {
                scroll-behavior: auto;
            }

            .parallax-layer {
                will-change: auto;
            }

            .app-card, .link-grid a {
                transition: none;
            }
        }
        /* =====================================================
           Landscape captures
           Some apps only run on their side. The frame turns with them:
           corner radii swap over, the Dynamic Island goes (these are
           simulator grabs with no status bar), and one fixed ratio with
           contain keeps every frame the same height without cropping the
           slightly different sizes.
           These sit at the end of the stylesheet on purpose - they are
           overrides, and at equal specificity the later rule wins.
           ===================================================== */
        .phone--landscape {
            border-radius: 6.2% / 13.5%;
        }

        .phone.phone--landscape img {
            border-radius: 5.2% / 11%;
        }

        .phone--landscape::after {
            display: none;
        }

        /* Three shots fanned like the portrait cards, only turned through
           ninety degrees: the middle one large and in front, the other two
           tucked behind it above and below rather than left and right.
           All three share one grid cell so they overlap; the padding gives
           the two behind somewhere to show. */
        .shot-fan.shot-fan--landscape,
        .hero-shots.hero-shots--landscape {
            display: grid;
            max-width: none;
            /* the two behind are pushed out by a transform, which does not
               reserve space - without this the card's overflow clips them */
            padding-block: 15%;
        }

        .shot-fan--landscape .phone,
        .hero-shots--landscape .phone {
            grid-area: 1 / 1;
            flex: none;
            width: 100%;
            margin: 0;
        }

        .shot-fan--landscape .phone:nth-child(1),
        .hero-shots--landscape .phone:nth-child(1) {
            width: 86%;
            justify-self: center;
            transform: translateY(-34%) rotate(-2.5deg);
            z-index: 1;
        }

        .shot-fan--landscape .phone:nth-child(2),
        .hero-shots--landscape .phone:nth-child(2) {
            z-index: 3;
        }

        .shot-fan--landscape .phone:nth-child(3),
        .hero-shots--landscape .phone:nth-child(3) {
            width: 86%;
            justify-self: center;
            transform: translateY(34%) rotate(2.5deg);
            z-index: 1;
        }

        /* A landscape frame needs the width, so two per view, one when narrow */
        .fc-carousel.fc-carousel--2 {
            --per-view: 2;
            --gap: 0rem;
        }

        @media (max-width: 900px) {
            .fc-carousel.fc-carousel--2 {
                --per-view: 1;
            }
        }

        .slide.slide--wide button {
            width: 100%;
        }



    