
    :root {
                --canvas: 246 246 247;
                --surface: 255 255 255;
                --surface-muted: 242 242 244;
                --surface-sunken: 234 234 237;
                --line: 230 230 233;
                --line-strong: 211 211 216;
                --ink: 10 10 11;
                --ink-2: 86 87 93;
                --ink-3: 110 111 119;
                --panel: 18 19 23;
        --on-panel: 250 250 250;
        --brand-ink: 48 103 239;
        --brand-fill: 48 104 242;
        --on-brand: 255 255 255;
        --band-from: 43 92 214;
        --band-to: 33 70 164;

        
                        --c-brand: 50 108 252;
                --c-brand-50: 235 240 255;
                --c-brand-100: 214 226 254;
                --c-brand-200: 173 196 254;
                --c-brand-300: 132 167 253;
                --c-brand-400: 91 137 253;
                --c-brand-500: 50 108 252;
                --c-brand-600: 43 92 214;
                --c-brand-700: 33 70 164;
                --c-brand-800: 23 49 113;
                --c-brand-900: 13 27 63;
                                --c-success: 16 185 129;
                --c-success-50: 231 248 242;
                --c-success-100: 207 241 230;
                --c-success-200: 159 227 205;
                --c-success-300: 112 213 179;
                --c-success-400: 64 199 154;
                --c-success-500: 16 185 129;
                --c-success-600: 14 157 110;
                --c-success-700: 10 120 84;
                --c-success-800: 7 83 58;
                --c-success-900: 4 46 32;
                                --c-warning: 247 147 26;
                --c-warning-50: 254 244 232;
                --c-warning-100: 253 233 209;
                --c-warning-200: 252 212 163;
                --c-warning-300: 250 190 118;
                --c-warning-400: 249 169 72;
                --c-warning-500: 247 147 26;
                --c-warning-600: 210 125 22;
                --c-warning-700: 161 96 17;
                --c-warning-800: 111 66 12;
                --c-warning-900: 62 37 7;
                                --c-danger: 239 68 68;
                --c-danger-50: 253 236 236;
                --c-danger-100: 252 218 218;
                --c-danger-200: 249 180 180;
                --c-danger-300: 245 143 143;
                --c-danger-400: 242 105 105;
                --c-danger-500: 239 68 68;
                --c-danger-600: 203 58 58;
                --c-danger-700: 155 44 44;
                --c-danger-800: 108 31 31;
                --c-danger-900: 60 17 17;
                
        --shadow-card: 0 1px 2px rgba(16, 24, 40, .04);
        --shadow-lift: 0 1px 2px rgba(16, 24, 40, .04), 0 8px 20px -8px rgba(16, 24, 40, .10);
        --shadow-pop:  0 8px 16px rgba(16, 24, 40, .06), 0 24px 48px -12px rgba(16, 24, 40, .16);

        color-scheme: light;
    }

    .dark {
                --canvas: 10 14 23;
                --surface: 21 25 33;
                --surface-muted: 31 34 43;
                --surface-sunken: 7 9 15;
                --line: 37 41 49;
                --line-strong: 54 57 65;
                --ink: 250 250 250;
                --ink-2: 154 155 162;
                --ink-3: 140 141 148;
                --panel: 49 53 60;
        --brand-ink: 71 123 252;
        --band-from: 33 70 164;
        --band-to: 23 49 113;

        --shadow-card: 0 1px 2px rgba(0, 0, 0, .28);
        --shadow-lift: 0 1px 2px rgba(0, 0, 0, .28), 0 8px 20px -8px rgba(0, 0, 0, .40);
        --shadow-pop:  0 8px 16px rgba(0, 0, 0, .35), 0 24px 48px -12px rgba(0, 0, 0, .55);

        color-scheme: dark;
    }

    /* A select's open list is drawn by the browser. Over a see-through field
       (dark:bg-white/[0.04]) it can't use that colour and falls back to white,
       while the options keep the theme's light ink: white on white in dark
       mode. Solid theme colours for every option, in both themes. */
    select option,
    select optgroup {
        background-color: rgb(var(--surface));
        color: rgb(var(--ink));
    }


    #nav-progress {
        position: fixed; inset: 0 auto auto 0; z-index: 9999; height: 3px; width: 0;
        background: var(--np-color, rgb(var(--brand-fill, 50 108 252)));
        box-shadow: 0 0 10px var(--np-color, rgb(var(--brand-fill, 50 108 252)));
        border-radius: 0 3px 3px 0; opacity: 0; pointer-events: none;
        transition: width .25s ease-out, opacity .3s ease;
    }
    #nav-progress.is-on { opacity: 1; }
    @media (prefers-reduced-motion: reduce) { #nav-progress { transition: opacity .3s ease; } }

    /* The page being opened, from its first paint: drawn by CSS on <html>,
       since the body doesn't exist yet when this runs. */
    html.np-carry::before {
        content: ''; position: fixed; inset: 0 auto auto 0; z-index: 9999; height: 3px; width: 70%;
        background: var(--np-color, rgb(var(--brand-fill, 50 108 252)));
        box-shadow: 0 0 10px var(--np-color, rgb(var(--brand-fill, 50 108 252)));
        border-radius: 0 3px 3px 0;
        animation: npCarry 10s cubic-bezier(.1, .7, .2, 1) forwards;
    }
    @keyframes npCarry { to { width: 92%; } }
    @media (prefers-reduced-motion: reduce) { html.np-carry::before { animation: none; } }


    html { -webkit-text-size-adjust: 100%; }

    body {
        font-feature-settings: 'cv02','cv03','cv04','ss01';
        -webkit-font-smoothing: antialiased;
        text-rendering: optimizeLegibility;
    }

    /* Every figure in a bank is read in a column against the figure above
       it, so lining numerals are the default rather than an opt-in. */
    .tnum, table, .font-display { font-variant-numeric: tabular-nums; }

    ::-webkit-scrollbar { width: 9px; height: 9px; }
    ::-webkit-scrollbar-track { background: transparent; }
    ::-webkit-scrollbar-thumb { background: rgb(var(--line-strong)); border-radius: 99px; }
    ::-webkit-scrollbar-thumb:hover { background: rgb(var(--ink-3)); }

    /* One focus ring for the whole shell. Individual components
       were opting in one at a time, so most controls fell back to the
       UA default outline — a different shape and colour per browser. */
    :focus-visible {
        outline: 2px solid rgb(var(--brand-fill));
        outline-offset: 2px;
        border-radius: 4px;
    }

    [x-cloak] { display: none !important; }

    /* The one entrance animation in the system. Sections stagger via an
       inline --d so a page resolves top-down instead of all at once. */
    @keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
    .rise { animation: riseIn .5s cubic-bezier(.16,1,.3,1) both; animation-delay: var(--d, 0ms); }

    @media (prefers-reduced-motion: reduce) {
        *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
    }


        /* Sizes reserved before Tailwind (a runtime CDN build) arrives, so
           the first paint doesn't jump. */
        .site-header { height: 64px; }
        .hero-stage { min-height: 380px; }
        @media (min-width: 640px) { .hero-stage { min-height: 520px; } }

        /*
         * Reveal: elements rise and come into focus as they scroll into
         * view. Scoped to .js and to people who haven't asked for less
         * motion; everyone else simply sees the page.
         */
        @media (prefers-reduced-motion: no-preference) {
            .js [data-reveal] {
                opacity: 0;
                transform: translateY(18px);
                filter: blur(8px);
                transition: opacity .9s cubic-bezier(.16,1,.3,1), transform .9s cubic-bezier(.16,1,.3,1), filter .9s cubic-bezier(.16,1,.3,1);
                transition-delay: var(--d, 0ms);
                transition-duration: var(--dur, .9s);
            }
            /* A headline line is never invisible: it only sharpens and settles. */
            .js [data-reveal="line"] { opacity: 1; transform: translateY(10px); filter: blur(10px); }
            .js [data-reveal].is-in { opacity: 1; transform: none; filter: none; }

            @keyframes floatA { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
            @keyframes floatB { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
            @media (min-width: 640px) {
                .float-a { animation: floatA 7s ease-in-out infinite; }
                .float-b { animation: floatB 8s ease-in-out infinite; }
            }

            @keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
            .marquee-track { animation: marquee var(--marquee-duration, 40s) linear infinite; }
            .marquee:hover .marquee-track,
            [data-marquee-paused] .marquee-track { animation-play-state: paused; }
        }

        /* Nothing moves for those who asked for less motion, so nothing to pause. */
        @media (prefers-reduced-motion: reduce) { .marquee-toggle { display: none !important; } }

        /* Section anchors land below the sticky header. */
        [data-section] { scroll-margin-top: 80px; }

        /* A theme change is drawn as one circle growing from the switch
           (bankTheme().set), not the browser's default crossfade. */
        html.theme-swap::view-transition-old(root),
        html.theme-swap::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
    

    /* The tracker fills and the savings bars rise as their tile comes into view.
       Without JS or with reduced motion they are drawn complete. */
    @media (prefers-reduced-motion: no-preference) {
        .js [data-reveal] .track-fill { transform-origin: top; transform: scaleY(0); transition: transform 2s cubic-bezier(.16,1,.3,1) .5s; }
        .js [data-reveal].is-in .track-fill { transform: scaleY(1); }
        .js [data-reveal] .track-dot { transform: scale(.4); opacity: .3; transition: transform .5s cubic-bezier(.34,1.56,.64,1), opacity .4s; transition-delay: calc(.5s + var(--i) * .42s); }
        .js [data-reveal].is-in .track-dot { transform: none; opacity: 1; }
        .js [data-reveal] .save-bar { transform-origin: bottom; transform: scaleY(0); transition: transform 1.1s cubic-bezier(.16,1,.3,1); transition-delay: calc(.45s + var(--i) * .09s); }
        .js [data-reveal].is-in .save-bar { transform: none; }
        .js [data-reveal] .save-goal { opacity: 0; transform: translateY(6px); transition: opacity .6s, transform .8s cubic-bezier(.16,1,.3,1); transition-delay: .3s; }
        .js [data-reveal].is-in .save-goal { opacity: 1; transform: none; }
    }


    /* The dark glow: behind the phone, which sits under the heading on a
       phone and in the right column from lg. */
    .hiw-glow {
        background:
            radial-gradient(70% 38% at 50% 58%, rgb(var(--brand-fill) / .18), transparent 72%),
            radial-gradient(60% 30% at 50% 0%, rgb(var(--brand-fill) / .07), transparent 70%);
    }
    .hiw-dots {
        background-image: radial-gradient(rgb(255 255 255 / .06) 1px, transparent 1.2px);
        background-size: 22px 22px;
        -webkit-mask-image: radial-gradient(55% 32% at 50% 58%, #000, transparent 75%);
                mask-image: radial-gradient(55% 32% at 50% 58%, #000, transparent 75%);
    }
    @media (min-width: 1024px) {
        .hiw-glow {
            background:
                radial-gradient(38% 62% at 76% 52%, rgb(var(--brand-fill) / .2), transparent 72%),
                radial-gradient(34% 48% at 6% 0%, rgb(var(--brand-fill) / .07), transparent 70%),
                linear-gradient(90deg, transparent 40%, rgb(var(--brand-fill) / .03));
        }
        .hiw-dots {
            -webkit-mask-image: radial-gradient(30% 55% at 76% 52%, #000, transparent 75%);
                    mask-image: radial-gradient(30% 55% at 76% 52%, #000, transparent 75%);
        }
    }
    .hiw-bar { animation: hiw-fill 6s linear forwards; transform: scaleX(0); }
    @keyframes hiw-fill { to { transform: scaleX(1); } }
    @media (prefers-reduced-motion: no-preference) {
        .hiw-caret { animation: hiw-blink 1s steps(1) infinite; }
        .hiw-scan { animation: hiw-scan 2.6s cubic-bezier(.45,0,.55,1) infinite; }
    }
    @keyframes hiw-blink { 50% { opacity: 0; } }
    @keyframes hiw-scan { 0% { transform: translateY(-100%); } 100% { transform: translateY(420%); } }


    /* Panels switch instantly (x-show alone: an Alpine enter transition
       interrupted by the next click left the old panel showing). The one
       that appears fades in with a CSS animation, which restarts each
       time its display changes and can't get stuck. */
    @media (prefers-reduced-motion: no-preference) {
        .ptab-panel { animation: ptab-in .35s cubic-bezier(.16,1,.3,1); }
    }
    @keyframes ptab-in { from { opacity: 0; transform: translateY(4px); } }


    @media (prefers-reduced-motion: no-preference) {
        .sec-ring { animation: sec-ring 3.2s cubic-bezier(.16,1,.3,1) infinite; }
    }
    .sec-ring { opacity: 0; }
    @media (prefers-reduced-motion: reduce) { .sec-ring { opacity: .5; } }
    @keyframes sec-ring {
        0% { opacity: .6; transform: translate(-50%, -50%) scale(.7); }
        100% { opacity: 0; transform: translate(-50%, -50%) scale(1.35); }
    }


    /* Without motion, the rows stand still and wrap; the copies go. */
    @media (prefers-reduced-motion: reduce) {
        .tm-marquee { -webkit-mask-image: none; mask-image: none; }
        .tm-track { width: auto; flex-wrap: wrap; justify-content: center; padding: 0 1rem; }
        .tm-copy { display: none; }
    }

:root{}

            /* The floor: with no bottom bar the only thing to clear is the
               home indicator. Set on <html> rather than <body> so a shell
               that does have a bar overrides it from its own body rule
               whichever of the two partials renders first. */
            html { --pwa-bottom: env(safe-area-inset-bottom, 0px); }

            #pwa-card { bottom: var(--pwa-bottom, 0px); }
            @media (min-width: 640px) {
                #pwa-card { bottom: calc(var(--pwa-bottom, 0px) + 1.5rem); }
            }
        

        /* The widget injects a banner that pushes the page down, a hover
           tooltip and a highlight on translated text. The switcher is the
           control; none of that chrome belongs on the page. */
        .goog-te-banner-frame,
        iframe.skiptranslate,
        .VIpgJd-ZVi9od-ORHb-OEVmcd,
        #goog-gt-tt { display: none !important; }
        body { top: 0 !important; }
        .goog-text-highlight,
        .VIpgJd-yAWNEb-VIpgJd-fmcmS-sn54Q { background: none !important; box-shadow: none !important; }
    