/* ==========================================================================
   Montserrat, self-hosted.

   Served from Google Fonts until 2026-08-05, which cost a visible flash of
   fallback text on every cold load: the page painted in a system font, then
   swapped when the webfont arrived from a third-party host. Hosting the files
   ourselves removes that round trip entirely, and keeps the site true to the
   rule that what is in the repo is what ships.

   font-display: block, not swap. The text is invisible for a short block
   period rather than painting in the wrong font and reflowing. With the files
   on our own origin they arrive in milliseconds, so there is nothing to see.

   Two subsets per weight. Browsers download only the ranges a page actually
   uses, so the latin-ext files are never fetched for English pages and cost
   nothing to declare.

   Montserrat is licensed under the SIL Open Font License 1.1.
   ========================================================================== */

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 300;
    font-display: block;
    src: url('/assets/fonts/montserrat-300-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 300;
    font-display: block;
    src: url('/assets/fonts/montserrat-300-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url('/assets/fonts/montserrat-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url('/assets/fonts/montserrat-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 600;
    font-display: block;
    src: url('/assets/fonts/montserrat-600-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 600;
    font-display: block;
    src: url('/assets/fonts/montserrat-600-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 700;
    font-display: block;
    src: url('/assets/fonts/montserrat-700-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 700;
    font-display: block;
    src: url('/assets/fonts/montserrat-700-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 900;
    font-display: block;
    src: url('/assets/fonts/montserrat-900-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 900;
    font-display: block;
    src: url('/assets/fonts/montserrat-900-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ==========================================================================
   PlayoffBlitz marketing site (PBI #1184)

   Tokens are lifted from the approved Figma redesign
   (file IccjUOWvANUDC0rDhD4sMS, frame 4311:4579) — not eyeballed.

   Change a value HERE, once. Per the rule Nick set for the content admin,
   sizes and colours are design decisions that live in tokens; the admin
   (#1187) edits words and images only.
   ========================================================================== */

:root {
    /* Surfaces — darkest at the page, lifting toward cards */
    --bg:             #000000;
    --bg-alt:         #000000;
    --surface:        #0e0e0e;
    --surface-2:      #0f0f0f;
    --surface-3:      #141414;

    /* Accent — #4bb5ff is the dominant blue in the design (32 uses) */
    --accent:         #4bb5ff;
    --accent-deep:    #2ca8ff;
    --accent-glow:    rgba(75, 181, 255, 0.15);
    --accent-ink:     #050505;

    /* Text */
    --text:           #ffffff;
    --text-strong:    rgba(255, 255, 255, 0.8);
    --text-muted:     rgba(255, 255, 255, 0.65);
    --text-dim:       rgba(255, 255, 255, 0.45);
    --text-faint:     rgba(255, 255, 255, 0.35);
    --text-ghost:     rgba(255, 255, 255, 0.25);

    /* Lines */
    --hairline:       rgba(255, 255, 255, 0.06);
    --hairline-soft:  rgba(255, 255, 255, 0.05);

    /* Type */
    --font:           'Montserrat', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --w-light:        300;
    --w-regular:      400;
    --w-semi:         600;
    --w-bold:         700;
    --w-black:        900;

    /* Rhythm */
    --radius:         24px;
    --radius-sm:      12px;
    --container:      1123px;
    --section-y:      clamp(64px, 8vw, 112px);
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-weight: var(--w-light);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; line-height: 1.15; font-weight: var(--w-bold); }
p  { margin: 0; }
/* figure carries a UA default of margin: 1em 40px, which was shrinking the
   testimonial cards by 80px inside their grid cells */
figure, blockquote, figcaption { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img { max-width: 100%; height: auto; display: block; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--accent);
    color: var(--accent-ink);
    padding: 10px 16px;
    font-weight: var(--w-bold);
    z-index: 100;
}
.skip-link:focus { left: 8px; top: 8px; }

/* Available to screen readers and crawlers, not painted. The hero wordmark is
   a logo, so the page needs one plain-language line stating what this is. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.container {
    width: 100%;
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 24px;
}

.muted   { color: var(--text-ghost); }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
/* Button spec read from Figma Dev Mode, not eyeballed:
   h-44px · px-32px · rounded-14px · Montserrat Bold 14/20 · tracking 1.4px
   uppercase · primary #4bb5ff on black text with a 25px blue drop-shadow. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 32px;
    border-radius: 14px;
    border: 1.5px solid transparent;
    font-family: var(--font);
    font-size: 14px;
    line-height: 20px;
    font-weight: var(--w-bold);
    letter-spacing: 1.4px;
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }

.btn-primary {
    background: var(--accent);
    color: #000;
    filter: drop-shadow(0 0 25px rgba(75, 181, 255, 0.33));
}
.btn-primary:hover { background: var(--accent-deep); }

.btn-ghost {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.15);
    color: rgba(255, 255, 255, 0.7);
}
.btn-ghost:hover { border-color: rgba(255, 255, 255, 0.32); color: var(--text); }

/* Unavailable plans — reads as deliberate, not broken */
.btn-disabled {
    background: rgba(255, 255, 255, 0.03);
    border-color: var(--hairline);
    color: var(--text-faint);
    cursor: default;
}
.btn-disabled:hover { transform: none; }

.btn-store {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.14);
    color: var(--text);
}

.btn-sm    { min-height: 38px; padding: 0 22px; font-size: 12px; letter-spacing: 1.2px; }
.btn-block { display: flex; width: 100%; border-radius: 16px; }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(12px);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    min-height: 64px;
}

/* The hero wordmark is the logo at the top of the page, so the header slot
   starts empty and the mark travels into it on scroll (assets/js/logo-transition.js).
   The .logo-fx class is set by that script, so without JS the header logo is
   simply visible from the start. */
.logo-fx .site-header .logo img { opacity: 0; }
.logo-fx .site-header .logo img,
.logo-fx .hero-wordmark img,
.logo-fx .hero-wordmark svg { transition: opacity 0.12s linear; }

/* flex: none, or the header logo is squeezed by whatever sits beside it —
   img carries max-width: 100% from the reset, so a shrinking flex item drags
   the image down with it. It went to 0x0 between 720 and 790px, and
   logo-transition.js sizes the hero wordmark to match this element, so the
   mark then scaled to nothing on scroll. The logo holds its size; anything
   else in the header gives way first. */
.logo { display: block; flex: none; line-height: 0; }
.logo:hover { text-decoration: none; }
.logo img { width: 205px; height: auto; max-width: none; }

/* Auto margin eats the free space before justify-content can share it out, so
   the logo holds the left edge and the nav sits against the buttons instead of
   drifting in the middle. With the nav hidden on mobile the header falls back
   to two children and space-between does the right thing on its own. */
.site-nav { margin-left: auto; }
.site-nav ul { display: flex; gap: 28px; }
.site-nav a {
    position: relative;
    display: block;
    padding-bottom: 7px;   /* on every item, so the current one adds no shift */
    color: var(--text-faint);
    font-size: 12px;
    font-weight: var(--w-bold);
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.site-nav a:hover { color: var(--text); text-decoration: none; }

/* The page you are on, marked once in the markup with aria-current and styled
   off that, so the state is announced to a screen reader and drawn from the
   same source rather than a second class that can fall out of step. */
.site-nav a[aria-current="page"] { color: var(--text); }
.site-nav a[aria-current="page"]::after {
    content: '';
    position: absolute;
    left: 0;
    /* uppercase tracking hangs a space off the last letter; pull the rule back
       by the same amount so it sits under the glyphs, not past them */
    right: 0.12em;
    bottom: 0;
    height: 2px;
    border-radius: 1px;
    background: var(--accent);
}

.header-actions { display: flex; align-items: center; gap: 12px; }

/* --------------------------------------------------------------------------
   Mobile navigation

   Below 900px the horizontal nav does not fit beside the logo and both
   buttons, so it moves into a panel behind this button. The panel's links
   are in the HTML on every page — the script supplies open/closed state and
   nothing else — and the footer carries the same set, so the links are
   reachable and crawlable whether or not the script runs.
   -------------------------------------------------------------------------- */
.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 42px;
    height: 42px;
    padding: 0;
    border: 1.5px solid rgba(255, 255, 255, 0.15);
    border-radius: 12px;
    background: transparent;
    color: var(--text);
    cursor: pointer;
}
.nav-toggle:hover { border-color: rgba(255, 255, 255, 0.32); }

/* Three bars that fold into a cross: the middle one fades while the outer two
   rotate onto each other, so the button reads as one control changing state
   rather than two different icons swapping places. */
.nav-toggle-bars { position: relative; display: block; width: 18px; height: 12px; }
.nav-toggle-bars i {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.22s ease, opacity 0.12s linear;
}
.nav-toggle-bars i:nth-child(1) { top: 0; }
.nav-toggle-bars i:nth-child(2) { top: 5px; }
.nav-toggle-bars i:nth-child(3) { top: 10px; }

.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* Hangs off the sticky header rather than sitting in the flow, so opening the
   menu never pushes the page down under the reader. */
.mobile-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    background: rgba(0, 0, 0, 0.96);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s linear 0.18s;
}
.nav-open .mobile-nav {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}

.mobile-nav > .container { padding-top: 8px; padding-bottom: 24px; }

.mobile-nav li a {
    display: block;
    padding: 14px 0;
    border-bottom: 1px solid var(--hairline-soft);
    color: var(--text-strong);
    font-size: 13px;
    font-weight: var(--w-bold);
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.mobile-nav li a:hover { color: var(--text); text-decoration: none; }
.mobile-nav li a[aria-current="page"] { color: var(--accent); }
.mobile-nav li:last-child a { border-bottom: 0; }

.mobile-nav .btn { display: flex; width: 100%; margin-top: 18px; }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.hero {
    padding: clamp(64px, 9vw, 130px) 0 0;
    text-align: center;
    background: var(--bg);
    overflow: hidden;   /* contains the photo's 110.6% bleed */
}

/* Reproduced from Figma Dev Mode rather than approximated:
   container 1593x328 in a 1440 frame (=110.6% wide), opacity 58%, and the
   image absolutely offset inside it — w-full, h-323%, top--210.03%.
   Figma offsets the fill; it does not crop, so object-position can't express it. */
.hero-photo {
    position: relative;
    /* The band is full-bleed and the fill is `cover`, so the image is always
       stretched to the band's WIDTH — the zoom is bandWidth / 1920 and nothing
       about the height changes it. Left uncapped, a 2560px monitor renders the
       football at 1.47x, both too large and upscaled past the source's native
       1920px. Capping the band at 1920 holds the football at its intended size
       and keeps it sharp; below ~1736px viewport this is inert and the bleed
       behaves exactly as before. */
    width: min(110.6%, 1920px);
    /* margin-left:50% + translateX(-50%) centres at ANY width. A negative
       margin only centred the one width it was calculated for, and auto
       margins refuse to go negative, so neither survives the cap. */
    margin: clamp(48px, 8.5vw, 123px) 0 0 50%;     /* buttons end 530, photo top 653 */
    transform: translateX(-50%);
    height: clamp(230px, 22.8vw, 380px);
    overflow: hidden;
    line-height: 0;
    /* No edge mask: the source is already pure black for its first ~60px on
       both sides (the ball's tip starts around x=120), so the band meets the
       page with nothing to hide — and a fade would eat the very tip that the
       cap exists to reveal. */
}
.hero-photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;          /* never distort — the design's fixed h-323%
                                   only holds at its exact box size */
    /* object-position is a fraction of the OVERFLOW, not of the image. The
       design's offset shows the 65-96%% band; with a 1113px image in a 346px
       box that is 727/767 of the overflow. */
    object-position: center 95%;
    opacity: 0.58;              /* on the image only — the bolt is in here too */
}
.hero-photo-bolt {
    position: absolute;
    left: 50%;
    bottom: 12px;
    transform: translateX(-50%);
    height: clamp(52px, 6vw, 92px);
    width: clamp(17px, 2vw, 31px);
    /* the symbol paints with currentColor, so this must be color, not fill */
    color: var(--accent);
    z-index: 1;
}

.hero-eyebrow {
    color: var(--text-faint);
    font-size: 11px;
    font-weight: var(--w-bold);
    letter-spacing: 0.22em;
    text-transform: uppercase;
    margin-bottom: 28px;
}

.hero-wordmark {
    margin: 0 auto 36px;
    line-height: 0;
}
.hero-wordmark img,
.hero-wordmark svg {
    margin: 0 auto;         /* block-level: text-align on the parent won't centre it */
    /* ~83% of the frame in the design, not the full width I had */
    width: min(100%, 900px);
    height: auto;
    display: block;
    overflow: visible;      /* the bolt grows past the viewBox on the way in */
}

/* --------------------------------------------------------------------------
   Wordmark build-in — bolt lands first, then the letters sweep left to right.

   NOTE ON SAFETY: no opacity is set on the paths themselves. The hidden state
   lives only inside the keyframes, reached via `backwards` fill during the
   delay. So if the animation never runs — reduced motion, an old browser, a
   crawler rendering with animations off — the finished logo is simply there.
   That is why this needs no .fx class the way the scroll effects do.

   The letters keep their original paint order in the markup (the bolt is drawn
   under the second F and the B, and it must stay that way); --i carries the
   left-to-right READING order independently.
   -------------------------------------------------------------------------- */
@keyframes lg-letter {
    from { opacity: 0; transform: translateY(9px); }
    to   { opacity: 1; transform: none; }
}

/* -240% of the bolt's own box shifts it from its resting spot at 63% across
   to the centre of the frame; percentages resolve against fill-box, so this
   holds at any rendered size. Scale stays at 2 so the tips clear the hero's
   top padding without being clipped by its overflow:hidden. */
@keyframes lg-bolt {
    from { opacity: 0; transform: translateX(-240%) scale(2); }
    to   { opacity: 1; transform: none; }
}

.hero-wordmark path {
    transform-box: fill-box;
    transform-origin: center;
    animation: lg-letter 0.5s cubic-bezier(0.22, 1, 0.36, 1) backwards;
    animation-delay: calc(620ms + var(--i) * 55ms);
}

.hero-wordmark .lg-bolt {
    animation: lg-bolt 0.72s cubic-bezier(0.22, 1, 0.36, 1) backwards;
    animation-delay: 60ms;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: center;
    margin-bottom: 56px;
}

.hero-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
}
.hero-chips li {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px 26px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    min-width: 168px;
}
.hero-chips strong {
    font-size: 14px;
    font-weight: var(--w-bold);
}
.hero-chips span {
    font-size: 12px;
    color: var(--text-faint);
}

/* --------------------------------------------------------------------------
   Interior page hero

   The home page opens on the wordmark; every other page opens on a title.
   Deliberately shallower than the home hero so the content starts high —
   these are pages people arrive at with a question, not to be sold to.
   -------------------------------------------------------------------------- */
.page-hero {
    padding: clamp(48px, 7vw, 88px) 0 clamp(32px, 4vw, 56px);
    text-align: center;
    border-bottom: 1px solid var(--hairline-soft);
}
.page-hero .eyebrow-pill { align-self: center; }

.page-title {
    font-size: clamp(34px, 5.4vw, 60px);
    line-height: 1.12;
    font-weight: var(--w-bold);
    letter-spacing: -0.02em;
    margin-bottom: 18px;
}
.page-lead {
    max-width: 620px;
    margin: 0 auto;
    color: var(--text-muted);
    font-size: 16px;
    line-height: 28px;
}
/* A second lead paragraph carries the positioning without turning the first
   one into a wall. Only the follow-on gets the gap. */
.page-lead + .page-lead { margin-top: 16px; }
.page-meta {
    margin-top: 18px;
    color: var(--text-faint);
    font-size: 13px;
}

/* --------------------------------------------------------------------------
   Segmented control (Rules seasons, Points sides)

   Both panels are ALWAYS in the HTML. The script adds .seg-js, which is what
   activates the tabs — so with JS off both panels simply render in full, each
   under its own heading. Crawlers get everything; readers get the toggle.
   -------------------------------------------------------------------------- */
/* Hidden until the script claims it — a tab strip that does nothing is worse
   than no tab strip. With JS off the panels below simply read as sections. */
.seg { display: none; }
.seg-js .seg {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    margin: 0 auto 48px;
    background: var(--surface-2);
    border: 1px solid var(--hairline);
    border-radius: 999px;
}
.seg button {
    min-height: 38px;
    padding: 0 26px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--text-faint);
    font-family: var(--font);
    font-size: 12px;
    font-weight: var(--w-bold);
    letter-spacing: 1.2px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.seg button:hover { color: var(--text); }
.seg button[aria-selected="true"] {
    background: var(--accent);
    color: #000;
}

/* Without the script this is just a wrapper; the heading above each panel
   keeps the document readable and the outline correct. */
.seg-panel + .seg-panel { margin-top: var(--section-y); }
.seg-js .seg-panel[hidden] { display: none; }
/* The per-panel heading is redundant once the tabs label them. */
.seg-js .seg-panel > .seg-panel-title { display: none; }

.seg-panel-title {
    font-size: 22px;
    font-weight: var(--w-bold);
    letter-spacing: -0.01em;
    margin-bottom: 32px;
    text-align: center;
}

/* --------------------------------------------------------------------------
   Info cards — a 3-up row of headed blocks (rules detail, points groups)
   -------------------------------------------------------------------------- */
.info-grid {
    display: grid;
    /* min() or the track floor wins against a narrower screen and the whole
       page inherits a sideways scroll — 320px leaves only 272px of gutter. */
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
    gap: clamp(16px, 2vw, 21px);
    text-align: left;
}
.card-info h3 {
    font-size: 16px;
    font-weight: var(--w-bold);
    margin: 16px 0 14px;
}
.card-info p { color: var(--text-muted); font-size: 14px; line-height: 24px; }
.card-info p + p { margin-top: 12px; }
/* Colour lives on the bolt only, exactly as it does on the home page rules
   cards. No coloured edge and no coloured title: those made these pages read
   as a different design system. --cat comes from .cat-green / .cat-blue /
   .cat-orange. */
.card-info { --cat: var(--accent); }
.card-info .bolt {
    width: 48px;
    height: 48px;
    background: rgba(75, 181, 255, 0.09);
    border-radius: 14px;
    color: var(--cat);
}
.card-info .bolt .icon-bolt { height: 24px; width: 7.67px; }

/* Trailing caveat on a rules card: quieter than the body, separated by a rule
   so it reads as a footnote rather than another point. */
.card-info-sub {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 13px !important;
    line-height: 21px !important;
    color: var(--text-faint) !important;
}

/* The one rule that genuinely differs by season, split inside its own card
   rather than splitting the whole page into tabs. Straight from the app's
   How To Play screen, and it keeps both halves in the served HTML. */
.split-note {
    display: grid;
    gap: 10px;
    margin-top: 14px;
}
.split-note > div {
    padding: 14px 16px;
    background: rgba(255, 255, 255, 0.03);
    border-radius: 12px;
}
.split-note h4 {
    margin: 0 0 6px;
    font-size: 10px;
    font-weight: var(--w-bold);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--cat);
}
.split-note p { font-size: 13px !important; line-height: 21px !important; }

/* The lineup slots read as a spec, so they get a list rather than prose. */
.slot-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 14px;
}
.slot-list li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: 14px;
    color: var(--text-muted);
}
.slot-list b {
    min-width: 20px;
    color: var(--accent);
    font-weight: var(--w-bold);
}

/* --------------------------------------------------------------------------
   Points — a scoring table per group. Tables, not cards: these are numbers
   people scan and compare, which is exactly what a table is for.
   -------------------------------------------------------------------------- */
.score-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: clamp(16px, 2vw, 21px);
    text-align: left;
}
/* Category colour, carried on the bolt only. The three values are the site's
   OWN bolt palette from the Figma rules assets, rotated across six cards the
   way the app's How To Play screen rotates them. No new brand colours, and
   gold stays out: reserved for Pro Bowl and premium. */
.score-card { --cat: var(--accent); }
.cat-green  { --cat: #18CE0F; }
.cat-blue   { --cat: #2CA8FF; }
.cat-orange { --cat: #F96332; }

.score-card { display: flex; flex-direction: column; }
.score-card .bolt {
    width: 48px;
    height: 48px;
    background: rgba(75, 181, 255, 0.09);
    border-radius: 14px;
    color: var(--cat);
}
.score-card .bolt .icon-bolt { height: 24px; width: 7.67px; }

/* Same size and weight as .card-rule h3, so a scoring card and a rules card
   read as the same component. */
.score-card h3 {
    font-size: 16px;
    font-weight: var(--w-bold);
    margin: 16px 0 10px;
}

/* The headline number the app leads each card with. Gives the eye somewhere
   to land before it reads a table of near-identical rows. */
.score-hero {
    display: flex;
    align-items: baseline;
    gap: 9px;
    margin: 0 0 20px;
    font-size: 42px;
    line-height: 1;
    font-weight: var(--w-bold);
    letter-spacing: -0.04em;
    color: var(--text);
}
.score-hero-unit {
    font-size: 11px;
    font-weight: var(--w-bold);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.score-table { width: 100%; border-collapse: collapse; }
.score-table th { font-weight: var(--w-regular); }
.score-table th,
.score-table td {
    padding: 12px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 14px;
    text-align: left;
    color: var(--text-muted);
}
.score-table tr:last-child th,
.score-table tr:last-child td { border-bottom: 0; }
.score-table td {
    width: 1%;
    white-space: nowrap;
    padding-left: 16px;
    text-align: right;
    font-weight: var(--w-bold);
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   FAQ — native <details>, so it opens with JS disabled and Google can read
   every answer. No accordion script at all.
   -------------------------------------------------------------------------- */
.faq-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 820px;
    margin: 0 auto;
    text-align: left;
}
.faq-item {
    background: #0f0f0f;
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 16px;
    overflow: hidden;
}
.faq-item summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 28px;
    cursor: pointer;
    font-size: 16px;
    font-weight: var(--w-bold);
    list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
    content: '+';
    flex-shrink: 0;
    color: var(--accent);
    font-size: 22px;
    font-weight: var(--w-light);
    line-height: 1;
    transition: transform 0.2s ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item summary:hover { background: rgba(255, 255, 255, 0.02); }
.faq-item > p {
    padding: 0 28px 26px;
    color: var(--text-muted);
    font-size: 15px;
    line-height: 26px;
}

/* Where to go for the whole story, one step quieter than the answer itself.
   It rides inside the answer's own paragraph rather than following it, so it
   inherits that padding instead of adding a second helping of it. */
.faq-more {
    display: block;
    margin-top: 12px;
    color: var(--text-faint);
    font-size: 13px;
}

/* --------------------------------------------------------------------------
   Contact
   -------------------------------------------------------------------------- */
.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: clamp(32px, 5vw, 64px);
    align-items: start;
}
/* Inherits .feature-list, which is the same bolt-plus-heading pattern the home
   page uses. Only the top margin is local. */
.contact-points { margin-top: 32px; }

.form-card {
    background: #0f0f0f;
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 24px;
    box-shadow: 0 20px 25px 0 rgba(0, 0, 0, 0.4);
    padding: clamp(28px, 4vw, 40px);
}
.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}
.field { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.field label {
    font-size: 12px;
    font-weight: var(--w-bold);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.field input,
.field textarea {
    width: 100%;
    padding: 13px 16px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    color: var(--text);
    font-family: var(--font);
    font-size: 15px;
    font-weight: var(--w-light);
}
.field textarea { resize: vertical; min-height: 150px; line-height: 1.6; }
.field input:focus, .field textarea:focus { border-color: var(--accent); outline: none; }
.field input::placeholder, .field textarea::placeholder { color: var(--text-ghost); }

.form-status { margin-top: 18px; font-size: 14px; }
.form-status:empty { margin-top: 0; }
.form-status[data-state="error"]  { color: #ff6b6b; }
.form-status[data-state="ok"]     { color: #18CE0F; }

/* --------------------------------------------------------------------------
   Long-form legal prose

   65ch keeps a comfortable measure; these documents are read, not scanned.
   -------------------------------------------------------------------------- */
.prose { max-width: 72ch; margin: 0 auto; }
.prose h2 {
    font-size: 22px;
    font-weight: var(--w-bold);
    letter-spacing: -0.01em;
    margin: 56px 0 18px;
    scroll-margin-top: 90px;   /* clears the sticky header on anchor jumps */
}
.prose h3 {
    font-size: 16px;
    font-weight: var(--w-bold);
    margin: 32px 0 12px;
    scroll-margin-top: 90px;
}
.prose h4 {
    font-size: 15px;
    font-weight: var(--w-semi);
    margin: 24px 0 10px;
    color: var(--text-strong);
}
.prose p, .prose li {
    color: var(--text-muted);
    font-size: 15px;
    line-height: 28px;
}
.prose p { margin-bottom: 16px; }
/* The legal pages spell URLs out in full, and one unbreakable 306px string
   was pushing the whole page sideways on a 320px screen. */
.prose a { overflow-wrap: anywhere; }
.prose > :first-child { margin-top: 0; }
.prose strong { color: var(--text); font-weight: var(--w-semi); }

.prose ul, .prose ol { margin: 0 0 16px; padding-left: 24px; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin-bottom: 8px; padding-left: 4px; }
.prose li::marker { color: var(--text-ghost); }

.prose-toc { margin: 0 0 16px; padding-left: 24px; list-style: decimal; }
.prose-toc li { margin-bottom: 6px; }
.prose-toc a { color: var(--text-muted); }
.prose-toc a:hover { color: var(--accent); }

.prose-note {
    padding: 20px 24px;
    background: rgba(75, 181, 255, 0.06);
    border-left: 2px solid var(--accent);
    border-radius: 0 12px 12px 0;
    margin-bottom: 24px;
}
.prose-note p:last-child { margin-bottom: 0; }

.prose-table-wrap { overflow-x: auto; margin-bottom: 24px; }
.prose-table {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
    font-size: 14px;
}
.prose-table th, .prose-table td {
    padding: 12px 14px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    text-align: left;
    vertical-align: top;
    color: var(--text-muted);
    line-height: 22px;
}
.prose-table th {
    background: rgba(255, 255, 255, 0.04);
    color: var(--text);
    font-weight: var(--w-semi);
}

/* --------------------------------------------------------------------------
   Statement band (home h1)

   The h1 is NOT the wordmark. A logo is an image, so an h1 wrapping it says
   only "PlayoffBlitz" to a search engine or an AI crawler. This is real text,
   placed where the photo ends and the reader is asking what this actually is.

   Nothing requires an h1 to sit at the top of the page, and putting it here
   also fixes the heading order: previously the first real heading was an h2.
   -------------------------------------------------------------------------- */
.statement {
    padding: clamp(56px, 7vw, 96px) 0 clamp(8px, 2vw, 24px);
    text-align: center;
}
.statement-title {
    font-size: clamp(30px, 4.6vw, 54px);
    line-height: 1.18;
    font-weight: var(--w-bold);
    letter-spacing: -0.02em;
    margin-bottom: 22px;
}
.statement-lead {
    max-width: 660px;
    margin: 0 auto;
    color: var(--text-muted);
    font-size: 16px;
    line-height: 28px;
}

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */
.section     { padding: var(--section-y) 0; }
#how-we-roll { padding-top: 79px; }   /* photo ends 981, content starts 1060 */
#testimonials { padding-bottom: 32px; }
.section-alt { background: var(--bg); }

.section-centered { text-align: center; }
/* bounded by the heading above it, not a wider column — the rules H2 measures
   411px, so the lead breaks to two lines inside the same bounds */
.section-centered .section-lead { margin: 0 auto 32px; max-width: 420px; }

.eyebrow {
    color: var(--accent);
    font-size: 10px;
    line-height: 15px;
    font-weight: var(--w-bold);
    letter-spacing: 1.8px;
    text-transform: uppercase;
    margin-bottom: 16px;
}
/* Figma "Pill": bg rgba(75,181,255,0.15), h-27px, px-16px, fully rounded, no border */
.eyebrow-pill {
    display: inline-flex;
    /* the split columns are flex, and flex items stretch across the cross
       axis — without this the pill spans the whole column */
    align-self: flex-start;
    width: fit-content;
    align-items: center;
    height: 27px;
    padding: 0 16px;
    background: rgba(75, 181, 255, 0.15);
    border-radius: 999px;
}

.section-title {
    font-size: clamp(30px, 4.2vw, 48px);
    line-height: 1.25;              /* 60/48 */
    font-weight: var(--w-bold);
    letter-spacing: -0.02em;
    margin-bottom: 20px;
}

.section-lead {
    color: var(--text-muted);
    font-size: 16px;
    margin-bottom: 24px;
}

.section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 48px;
}
.section-note {
    color: var(--text-faint);
    font-size: 14px;
    text-align: right;
    max-width: 320px;
}

/* Two-column split */
.split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(32px, 5vw, 64px);
    align-items: stretch;      /* both columns share the row height */
    min-height: 456px;         /* the design runs both sides at 456px */
}
.split > * { display: flex; flex-direction: column; justify-content: center; }
/* the card fills its column rather than floating at its content height,
   so both sides read as one balanced row */
.split-aside > .card { flex: 1 1 auto; }
/* DOM order is always heading-first so the heading hierarchy and screen-reader
   reading order stay correct; this only moves the aside visually. */
.split-aside-left .split-aside { order: -1; }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
.card {
    background: transparent;
    /* A 1px border lands on 0.667 device px here and fringes blue along the
       bottom edge. Same 6% ring, drawn inset, with no subpixel artifact. */
    border: 0;
    border-radius: 24px;
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.06),
        0 40px 80px 0 rgba(0, 0, 0, 0.6);
    padding: 56px;
    overflow: hidden;
}
.card p { color: var(--text-muted); font-size: 16px; line-height: 28px; }

.card-title {
    font-size: clamp(30px, 3.6vw, 48px);
    line-height: 1.25;              /* 60/48 */
    font-weight: var(--w-bold);
    letter-spacing: -0.02em;
    margin: 24px 0 16px;
}

.card-feature .btn,
.card-cta .btn { margin-top: 24px; }

/* Bare and large on the feature card — the tiled treatment is only for the
   small list icons. */
.card-feature .bolt {
    width: 48px;
    height: 48px;
    background: none;      /* no tile in the composed design */
    border-radius: 16px;
}
.card-feature .bolt .icon-bolt { height: 59px; width: 20px; }

/* Two stacked fills straight from the design:
   linear-gradient(168.473deg, rgba(75,181,255,0.33) 2.0136%, rgba(0,0,0,0) 53.304%)
   plus a radial hotspot at (158.25, 147.6), rx 369.25 / ry 246,
   rgba(75,181,255,0.08) -> transparent at 60%. */
.card-feature {
    background-image:
        radial-gradient(369.25px 246px at 158.25px 147.6px,
            rgba(75, 181, 255, 0.08) 0%, rgba(0, 0, 0, 0) 60%),
        linear-gradient(168.473deg,
            rgba(75, 181, 255, 0.33) 2.0136%, rgba(0, 0, 0, 0) 53.304%);
}

/* Dev Mode reports rgba(75,181,255,0.72) here, but Figma's own render of node
   4311:6074 samples to roughly 0.22 at the top — the Tailwind conversion
   overstates the alpha. Matched to the rendered design, not the literal value. */
.card-cta {
    position: relative;
    justify-content: center;
    text-align: center;
    background-image: linear-gradient(189.737deg,
        rgba(75, 181, 255, 0.22) 0%, rgba(0, 0, 0, 0) 64%);
}
/* Playbook diagram sits behind the content, low in the card (node 4311:6089:
   499x199 at y=228 inside a 529x456 card). */
.card-playbook {
    /* node 4311:6089 is 499x199 at y=228 in a 529x456 card
       => 94%% wide, 44%% tall, starting halfway down */
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%);
    width: 94%;
    height: 44%;
    object-fit: cover;      /* the design frames it 499x199 (2.5:1) and crops;
                               the source is 1.34:1, so contain left it narrow */
    max-width: none;
    opacity: 0.45;
    pointer-events: none;
    z-index: 0;
}
.card-cta > :not(.card-playbook) { position: relative; z-index: 1; }

/* Inline SVG bolt, inherits colour from its container — matches the design's
   blue bolt instead of the OS emoji, and stays crisp at any size. */
.icon-bolt {
    height: 1em;
    width: 0.33em;          /* the Figma bolt is 30x91 — tall and angled */
    fill: currentColor;
    vertical-align: -0.1em;
}
/* In the wordmark the bolt overshoots the cap height and interlocks with the
   two words, exactly as drawn in the design. */

.bolt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 14px;
    color: var(--accent);
    flex-shrink: 0;
}
.bolt .icon-bolt { height: 20px; width: 6.67px; }

/* ⭐ THE SMALL-CARD RECIPE. Defined once, here, and shared by every small card
   on the site: rules and testimonials on home, the rules cards, and the
   scoring cards. #0f0f0f, a 5% border, r-16 and a shallower 0/20/25 shadow.
   Distinct from the big feature-card recipe above (transparent, inset ring,
   r-24, deep shadow, gradients).

   Anything card-shaped joins this selector rather than restating the values.
   Points and rules drifted into their own near-copies once already and the
   pages stopped looking like they belonged to the same site. */
.card-rule, .card-quote, .card-info, .score-card {
    background: #0f0f0f;
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 16px;
    box-shadow: 0 20px 25px 0 rgba(0, 0, 0, 0.4);
    padding: 33px;
}
.card-rule {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
.card-rule .bolt {
    width: 48px;
    height: 48px;
    background: rgba(75, 181, 255, 0.09);
    border-radius: 14px;
}
.card-rule .bolt .icon-bolt { height: 24px; width: 7.67px; }

/* Sampled from the three exported bolt assets — they are not all blue. */
/* Only the bolt is coloured. All three tiles keep the same
   rgba(75,181,255,0.09) background — nodes 4333:6714/6721/6728 are identical. */
.card-rule-starters .bolt { color: #18CE0F; }
.card-rule-points   .bolt { color: #2CA8FF; }
.card-rule-scoring  .bolt { color: #F96332; }

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    /* cards sit at left 0 / 382 / 764 and are 361px wide -> 21px gaps,
       the same rhythm as the testimonial row */
    gap: clamp(16px, 2vw, 21px);
    margin-top: 48px;
    text-align: left;
}
.card-rule h3, .card-quote strong { font-size: 16px; font-weight: var(--w-bold); }
.card-rule h3 { margin: 16px 0 10px; }

/* Feature + step lists */
.feature-list, .step-list {
    display: flex;
    flex-direction: column;
    gap: 24px;
}
.feature-list li, .step-list li {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}
.feature-list h3, .step-list h3 {
    font-size: 16px;
    line-height: 24px;
    font-weight: var(--w-bold);
    margin-bottom: 6px;
}
.feature-list p, .step-list p {
    color: var(--text-muted);       /* 0.65 in the design, not 0.35 */
    font-size: 14px;
    line-height: 24px;
}

.step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: var(--accent-glow);
    color: var(--accent);
    font-size: 13px;
    font-weight: var(--w-bold);
    flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   Pricing — two league cards. The bundle is retired; the Pro Bowl is an
   individual entry and lives in its own section below.
   -------------------------------------------------------------------------- */
.plan-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: 24px;
    /* Two cards, not three — the bundle is retired. Centred so the row reads as
       deliberate rather than leaving a dead column on the right. */
    max-width: 780px;
    margin: 0 auto;
}

.plan {
    display: flex;
    flex-direction: column;
    background: rgba(17, 19, 20, 0.6);      /* #111314 at opacity-60 */
    border: 0;
    border-radius: 24px;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
    padding: 32px;
}
/* An out-of-season plan reads as unavailable rather than unchosen. It keys off
   its own disabled CTA rather than a separate class, so when the season opens
   there is nothing to remember: swap the span for a real button and the card
   returns to full strength on its own. */
/* `filter: opacity()`, NOT the opacity property — these cards are scroll-reveal
   targets, and `.fx .fx-reveal.fx-in { opacity: 1 }` outranks any sane selector
   here, so a plain opacity is silently overwritten the moment the card scrolls
   in. filter is a separate property: it multiplies with the reveal instead of
   fighting it, so the card fades in and lands dimmed. */
.plan:has(.btn-disabled) { filter: opacity(0.62); }

/* The Pro+ card carries the same "not yet" treatment as the plan cards, on the
   same :has() test, so nothing has to be remembered when it is switched back
   on — restoring the link is the whole reversal.

   It has no header row for the badge to sit in, unlike a plan card, so the pill
   is pinned to the corner instead. 32px rather than the card's own 56px so it
   reads as a corner marker and not as content. */
.card-feature { position: relative; }
.card-feature:has(.btn-disabled) { filter: opacity(0.62); }
.card-corner-badge {
    position: absolute;
    top: 32px;
    right: 32px;
}

/* Grey ticks, not the accent — a blue check reads as "included and active".
   Sits above `.plan-bullets li::before` on specificity, so it wins without
   !important. The scroll-fx tick-down never reaches this card (it is gated on
   an enabled .btn-primary), so nothing turns these green later. */
.plan:has(.btn-disabled) .plan-bullets li::before { color: var(--text-muted); }

/* Featured: its own gradient plus a blue ring and a blue-tinted lift. */
.plan-featured {
    background-image: linear-gradient(175.78deg,
        rgba(75, 181, 255, 0.59) 6.9511%, rgba(0, 0, 0, 0.22) 56.818%);
    background-color: transparent;
    box-shadow:
        0 0 0 1px rgba(75, 181, 255, 0.25),
        0 40px 80px 0 rgba(75, 181, 255, 0.19);
}

.plan-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 24px;
}
.plan-head h3 {
    font-size: 12px;
    font-weight: var(--w-bold);
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.plan-featured .plan-head h3 { color: var(--text-strong); }

.plan-badge {
    padding: 5px 11px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    font-size: 9px;
    font-weight: var(--w-bold);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-dim);
    white-space: nowrap;
}

.plan-price {
    font-size: 70px;
    font-weight: var(--w-bold);
    line-height: 1;
    letter-spacing: -0.05em;
    color: var(--text-strong);
}
.plan-featured .plan-price { color: var(--text); }
.plan-currency {
    font-size: 20px;
    font-weight: var(--w-light);
    color: var(--text-ghost);
    vertical-align: super;
    margin-right: 4px;
}

/* Inaugural-season discount: the old price sits beside the new one, struck
   through. Sized well below the price itself so the number that matters is
   still the one the eye lands on. */
.plan-was {
    font-size: 34px;
    font-weight: var(--w-light);
    color: rgba(255, 255, 255, 0.42);
    margin-right: 12px;
    vertical-align: 0.28em;
    white-space: nowrap;
}
/* The strike lives on the <s>, so the word "was" is not struck through, and
   the line renders even if this stylesheet never arrives. */
.plan-was s { text-decoration: line-through; }

@media (max-width: 900px) {
    .plan-was { font-size: 26px; }
}

/* Same idea at body size, for the comparison table cell. */
.plan-was-inline {
    color: var(--text-ghost);
    white-space: nowrap;
}

/* Honeypot slot on the contact form. Positioned off-screen rather than
   display:none or visibility:hidden, because a bot that reads CSS will skip a
   field it can tell is hidden, and the whole point is that it fills this one
   in. Nothing inside is content, so nothing is withheld from a crawler. */
.hp-slot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* "Save $20" has to be readable at a glance or the discount goes unnoticed,
   so unlike the neutral "Coming Dec" pill this one is a solid chip. */
.plan-badge-save {
    background: #fff;
    border-color: #fff;
    color: #0b1015;
}

.plan-unit {
    color: var(--text-faint);
    font-size: 13px;
    margin: 12px 0 24px;
    padding-bottom: 24px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.plan-featured .plan-unit { border-bottom-color: rgba(255, 255, 255, 0.15); }

.plan-bullets {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 28px;
    flex-grow: 1;
}
.plan-bullets li {
    position: relative;
    padding-left: 26px;
    font-size: 14px;
    color: var(--text-muted);
}
.plan-bullets li::before {
    content: '✓';
    position: absolute;
    left: 0;
    color: var(--accent);
    font-weight: var(--w-bold);
}

/* .card p (0,1,1) outranks .plan-price (0,1,0), which shrank the Pro Bowl
   price to body size. Re-assert the price styles at matching specificity. */
.card .plan-price { font-size: 70px; line-height: 1; color: var(--text); }
.card .plan-unit  { font-size: 13px; line-height: 1.4; color: var(--text-faint); }
.card .plan-bullets li { font-size: 14px; line-height: 1.5; }

.plan-footnote {
    margin-top: 32px;
    color: var(--text-faint);
    font-size: 13px;
}

/* Same footnote used inside .prose, annotating a table rather than a card
   row. `.prose p` (0,1,1) outranks `.plan-footnote` (0,1,0) on size and
   colour, so it has to be re-asserted; and it sits tight under the table
   instead of carrying the 32px lead-in the plan grid needs. */
.prose .plan-footnote {
    margin-top: 4px;
    font-size: 13px;
    line-height: 22px;
    color: var(--text-faint);
}

/* --------------------------------------------------------------------------
   Solo Pro Bowl
   -------------------------------------------------------------------------- */
.solo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 400px);
    gap: clamp(32px, 5vw, 64px);
    align-items: center;
}
.solo-lead {
    color: var(--text-muted);
    font-size: 16px;
    max-width: 480px;
}
/* Same fills as the No Draft info card (node 4311:5993) — the softer
   treatment, not the brighter purchase-card gradient used in pricing. */
.card-solo {
    display: flex;
    flex-direction: column;
    background-image:
        radial-gradient(369.25px 246px at 158.25px 147.6px,
            rgba(75, 181, 255, 0.08) 0%, rgba(0, 0, 0, 0) 60%),
        linear-gradient(168.473deg,
            rgba(75, 181, 255, 0.33) 2.0136%, rgba(0, 0, 0, 0) 53.304%);
}

/* --------------------------------------------------------------------------
   Testimonials
   -------------------------------------------------------------------------- */
/* Testimonials — design values: card #0f0f0f 361x251 p-33, quote block 295px
   at 16px/0.6, a rgba(255,255,255,0.06) divider, and a SOLID #2ca8ff 44px
   avatar (not the tinted circle used elsewhere). */
.quote-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: clamp(16px, 2vw, 20px);   /* tighter than the rules row's 67px */
    margin-top: 48px;
    text-align: left;
}
.card-quote {
    display: flex;
    flex-direction: column;
    padding: 33px;
    /* squared off at the bottom-left so it reads as a message bubble */
    border-radius: 16px 16px 16px 0;
}
.card-quote blockquote {
    margin: 0 0 24px;
    color: rgba(255, 255, 255, 0.6);
    font-size: 16px;
    line-height: 1.6;

}
.card-quote blockquote::before { content: '“'; }
.card-quote blockquote::after  { content: '”'; }

.card-quote figcaption {
    display: flex;
    align-items: center;
    gap: 12px;
    /* pins the row to the foot of an equal-height card so all three align,
       whatever the quote length. flex:1 on the quote does NOT do this — it
       grows each one from its own content size. */
    margin-top: auto;
    padding-top: 24px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}
/* keep both lines unwrapped so every caption is the same height and the three
   rows line up across the set, as the design has them */
.quote-who { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.quote-who strong,
.quote-who small { white-space: nowrap; }
.quote-who strong { font-size: 16px; line-height: 22px; font-weight: var(--w-bold); }
.quote-who small {
    font-size: 10px;
    line-height: 14px;
    font-weight: var(--w-light);
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--accent);
}

.avatar {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: #2ca8ff;
    color: #000;
    font-size: 13px;
    font-weight: var(--w-bold);
    flex-shrink: 0;
}

.store-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    justify-content: center;
    margin-top: 40px;
}
.store-badge {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-width: 196px;
    padding: 11px 22px;
    background: #000;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 16px;
    color: #fff;
    box-shadow: 0 20px 25px 0 rgba(0, 0, 0, 0.4);
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.store-badge:hover {
    text-decoration: none;
    transform: translateY(-2px);
    border-color: rgba(255, 255, 255, 0.55);
}
.store-badge-icon { width: 28px; height: 28px; flex-shrink: 0; }

/* Both stores set a small lead-in over a larger wordmark, roughly 1 : 2.2 */
.store-badge-text {
    display: flex;
    flex-direction: column;
    text-align: left;
    line-height: 1.1;
}
.store-badge-text small {
    font-size: 10px;
    font-weight: var(--w-regular);
    letter-spacing: 0.02em;
    color: #fff;
}
.store-badge-text strong {
    font-size: 20px;
    font-weight: var(--w-semi);
    letter-spacing: -0.01em;
    color: #fff;
}

@media (max-width: 520px) {
    .store-badge { width: 100%; justify-content: center; }
}

/* --------------------------------------------------------------------------
   Closer + footer
   -------------------------------------------------------------------------- */
.closer {
    padding: 8px 0 56px;
    text-align: center;
    color: var(--text-faint);
    font-size: 14px;
}

.site-footer {
    background: var(--bg);
    border-top: 1px solid rgba(255, 255, 255, 0.05);
    padding: 65px 0 32px;
}

.footer-inner {
    display: grid;
    grid-template-columns: 2fr repeat(3, 1fr);
    gap: 40px;
}

.footer-brand .logo img { width: 132px; }

.footer-tagline {
    margin-top: 14px;
    color: var(--text-faint);
    font-size: 13px;
    max-width: 280px;
}

.footer-col h2 {
    font-size: 11px;
    font-weight: var(--w-bold);
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-bottom: 16px;
}
.footer-col ul { display: flex; flex-direction: column; gap: 10px; }
.footer-col a {
    color: var(--text-muted);
    font-size: 13px;
}
.footer-col a:hover { color: var(--text); text-decoration: none; }

.footer-social { flex-direction: row !important; gap: 14px !important; }
.footer-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    font-size: 12px;
    font-weight: var(--w-bold);
}

.footer-legal {
    margin-top: 48px;
    padding-top: 24px;
    border-top: 1px solid var(--hairline-soft);
    color: var(--text-ghost);
    font-size: 12px;
}

/* --------------------------------------------------------------------------
   Responsive — ~80% of traffic is mobile, so these are load-bearing
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .split, .solo { grid-template-columns: minmax(0, 1fr); }
    .split { min-height: 0; }

    /* Stacked, the copy wraps to more lines and ran over the playbook.
       Reserve a band at the foot of the card and sit the diagram in it, so
       they can never collide however the text reflows. */
    .card-cta { padding-bottom: 210px; }
    .card-playbook {
        top: auto;
        bottom: 28px;
        height: 160px;
        width: 88%;
    }
    .split-aside-left .split-aside { order: 0; }
    .footer-inner { grid-template-columns: 1fr 1fr; }
    .section-head { flex-direction: column; align-items: flex-start; }
    .section-note { text-align: left; }

    .contact-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Measured, not guessed: logo 205 + nav 395 + buttons 326 + two 24px gaps +
   48px of container padding = 1022px before the header has to compromise.
   The old 720px breakpoint was far too late, and the overflow was invisible
   only because the logo was being crushed to absorb it. Below this the nav
   and Sign In move into the panel. */
@media (max-width: 1023px) {
    .site-nav { display: none; }
    .header-actions .btn-ghost { display: none; }
    .nav-toggle { display: inline-flex; }
    .mobile-nav { display: block; }
}

@media (max-width: 720px) {
    .plan-price { font-size: 56px; }
}

@media (max-width: 520px) {
    /* Keep the sticky header on one line — the CTA is the only persistent
       conversion path once the hero scrolls away, so it stays visible. */
    .logo img { width: 122px; }
    .header-actions .btn-sm { min-height: 34px; padding: 0 13px; font-size: 11px; letter-spacing: 0.6px; }
    .header-inner { gap: 10px; }
    .nav-toggle { width: 38px; height: 38px; }

    /* 56px of card padding leaves ~215px of content at 375px, which wrapped
       the plan headers. 32px gives them room to stay on one line. */
    .card { padding: 32px; }
    .card-cta { padding-bottom: 210px; }

    .footer-inner { grid-template-columns: 1fr; gap: 32px; }
    .hero-chips li { width: 100%; }
    .hero-actions .btn { width: 100%; }

    /* Two tabs at 375px: let them share the row rather than overflow it. */
    .seg-js .seg { display: flex; width: 100%; }
    .seg button { flex: 1 1 0; padding: 0 12px; letter-spacing: 0.6px; }

    .field-row { grid-template-columns: 1fr; gap: 0; }
    /* Same value the .card rule above uses, so every card on the site pads
       identically at this width. These two do not carry the .card class. */
    .card-info, .score-card { padding: 32px; }
    .faq-item summary { padding: 20px; font-size: 15px; }
    .faq-item > p { padding: 0 20px 22px; }
}

/* Below ~360px (SE-class phones) the logo, the CTA and the menu button no
   longer fit on one line, and the whole site inherited a sideways scroll.
   The header buys back its own margins rather than shrinking the logo, which
   holds its size everywhere; the rest of the page keeps the 24px gutter. */
@media (max-width: 360px) {
    .header-inner { padding-left: 16px; padding-right: 16px; gap: 8px; }
    .header-actions { gap: 8px; }
    .header-actions .btn-sm { padding: 0 10px; font-size: 10px; letter-spacing: 0.4px; }
    .nav-toggle { width: 34px; height: 34px; }
    .mobile-nav > .container { padding-left: 16px; padding-right: 16px; }
}

/* ==========================================================================
   Scroll motion (assets/js/scroll-fx.js)

   The .fx class is added by that script, so with JS off none of these rules
   apply and everything renders visible and in place. Crawlers see the page
   exactly as a reader would.
   ========================================================================== */

/* 1. Reveal on entry — small rise, quick, once. Deliberately understated:
      long distances and slow easings make a fast scroller feel held up. */
.fx .fx-reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.42s ease-out, transform 0.42s ease-out;
}
.fx .fx-reveal.fx-in {
    opacity: 1;
    transform: none;
}

/* 3. Check marks tick down a purchasable card, then its CTA pulses.
      The feature-list bolts no longer animate — motion beside a sentence
      pulls the eye off the words. */
@keyframes fx-pulse-glyph {
    0%   { transform: scale(1);    }
    18%  { transform: scale(1.32); }
    72%  { transform: scale(1.32); }
    100% { transform: scale(1);    }
}
.fx .plan-bullets li::before {
    display: inline-block;
    transform-origin: center;
    transition: color 0.3s ease, filter 0.3s ease;
}
.fx .plan-bullets li.fx-pulse::before {
    animation: fx-pulse-glyph 1.15s ease-out;
    color: #fff;
    filter: drop-shadow(0 0 9px rgba(75, 181, 255, 0.95));
}
/* Settles green once passed, so the list reads as ticked off.
   #18CE0F is the same green the app uses for its swap affordance. */
.fx .plan-bullets li.fx-checked::before {
    color: #18CE0F;
}

/* After the last box is ticked, the CTA takes two slow beats — same rhythm
   as the check marks so it reads as the end of the same gesture. */
@keyframes fx-cta-beat {
    0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(75, 181, 255, 0); }
    35%  { transform: scale(1.045); box-shadow: 0 0 34px 4px rgba(75, 181, 255, 0.55); }
    70%  { transform: scale(1);    box-shadow: 0 0 0 0 rgba(75, 181, 255, 0); }
    100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(75, 181, 255, 0); }
}
.fx .btn-primary.fx-cta-pulse {
    animation: fx-cta-beat 1.5s ease-in-out 2;
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
    .fx .fx-reveal { opacity: 1 !important; transform: none !important; }
    .btn:hover { transform: none; }
}
