/*
 * gf-components.css
 *
 * Sitewide component library, consolidated from the page-specific `.cli-*`
 * styles previously embedded (and duplicated) in the gforge-cli and jenkins
 * pages, plus component patterns found across the rest of the site
 * (comparison tables, quote cards, pricing cards, FAQ/accordion — the last
 * one replacing four separate incompatible implementations). Renamed to
 * the sitewide `.gf-*` BEM namespace — see docs/redesign-notes.md.
 * `.gf-btn` variants live in styles.css alongside the existing button
 * system rather than here.
 *
 * Authored mobile-first: base rules target small screens, `min-width`
 * media queries layer in enhancements for larger ones. Breakpoints used
 * throughout: 600px (small/tablet), 900px (desktop layout shifts), 1024px
 * (full desktop grids).
 */

/* === BASE === */
.gf-hero, .gf-section, .gf-mcp-section, .gf-cta-section, .gf-post {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.gf-text-accent { color: #99cc33; }
.gf-narrow { max-width: 700px; margin: 0 auto; }
.gf-link-plain { color: #99cc33; font-weight: 700; text-decoration: none; }
.gf-link-plain:hover { text-decoration: underline; }

/* === FOOTER CTA ===
 * Two short "question + link" prompts, given real visual separation
 * instead of being crammed onto one line with a middot. */
.gf-footer-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}
.gf-footer-cta p { margin: 0; font-size: 16px; color: #718096; }
@media (min-width: 600px) {
    .gf-footer-cta { flex-direction: row; justify-content: center; gap: 40px; }
}

/* === WHAT'S NEW BANNER === */
.gf-whats-new {
    display: block;
    background: #0f172a;
    border-bottom: 1px solid rgba(153,204,51,0.25);
    padding: 11px 20px;
    text-align: center;
    text-decoration: none;
    transition: background 0.15s;
}
a.gf-whats-new:hover {
    background: #16213b;
    text-decoration: none;
}
.gf-whats-new__inner {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px;
    max-width: 1100px;
    margin: 0 auto;
}
.gf-whats-new__tag {
    background: #99cc33;
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .09em;
    padding: 3px 9px;
    border-radius: 100px;
    flex-shrink: 0;
}
.gf-whats-new__text {
    color: #94a3b8;
    font-size: 13px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.gf-whats-new__text strong { color: #e2e8f0; }

/* .gf-whats-new--nav: same dark banner, holding in-page jump links
 * instead of a release-announcement badge+text. Non-sticky — inherits
 * that from the base .gf-whats-new, which has never been sticky. */
.gf-whats-new--nav .gf-whats-new__inner a {
    color: #94a3b8;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none !important;
    white-space: nowrap;
    transition: color .15s;
}
.gf-whats-new--nav .gf-whats-new__inner a:hover {
    color: #99cc33;
    text-decoration: none !important;
}

/* === PRIMARY NAV (mobile toggle) ===
 * `#primaryNav` still carries Bootstrap's `.collapse`/`.navbar-collapse`
 * classes (Bootstrap CSS is still loaded for pages not yet migrated), but
 * visibility is now driven by our own `.gf-nav-open` class (toggled by
 * js/gf-nav.js) instead of Bootstrap's JS — see docs/redesign-notes.md. */
#primaryNav.collapse { display: none; }
#primaryNav.collapse.gf-nav-open { display: block; }
@media (min-width: 768px) {
    #primaryNav.collapse { display: block !important; }
}
/* === HEADER SEARCH (icon toggle + overlay) ===
 * The trigger is a real WordPress menu item ("Search", positioned
 * between the divider and Login via WP-CLI) rather than a hand-coded
 * header.php element — same technique already used for the divider:
 * hide the link's own text, render an icon instead. gf-nav.js toggles
 * the overlay below on click. Same underlying WP search form/behavior
 * (method=get, name="s") throughout — this only changes how it's
 * triggered and replaces ~220-250px of always-visible input+button with
 * a small icon. */
/* padding matches .gf-mainnav__link's own 15px vertical (horizontal
 * trimmed since there's no text) so this sits at the same vertical
 * center as every other nav item instead of using a mismatched fixed
 * height. */
.gf-mainnav__item--search > .gf-mainnav__link {
    font-size: 0;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    padding: 15px 12px !important;
}
/* gf-nav.js returns focus here on close (both via the X and via
 * Escape) so keyboard users aren't left stranded — but the default
 * browser outline was requested off entirely, not just restyled. */
.gf-mainnav__item--search > .gf-mainnav__link:focus {
    outline: none;
}
.gf-mainnav__item--search > .gf-mainnav__link::before {
    content: '';
    width: 18px;
    height: 18px;
    background-color: currentColor;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}
/* position: fixed + a z-index above anything else in the theme (the
 * next-highest is .gf-sticky-nav at 200) — this is viewport-anchored,
 * not dependent on any particular page's own content/stacking, so it
 * works identically everywhere without per-page adjustment. */
.gf-search-overlay {
    position: fixed;
    inset: 0;
    z-index: 500;
    display: none;
}
.gf-search-overlay--open { display: block; }
.gf-search-overlay__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(10,14,26,0.6);
}
/* position: absolute + right (not margin:0 auto) so it can be anchored
 * to the search icon's actual on-screen position — gf-nav.js sets
 * `right` on open, computed from the icon's own getBoundingClientRect,
 * so the panel's right edge lines up with the icon's right edge exactly,
 * not just "somewhere on the right side of the header." */
.gf-search-overlay__panel {
    position: absolute;
    top: 0;
    right: 20px;
    display: flex;
    align-items: center;
    gap: 12px;
    width: 420px;
    max-width: calc(100vw - 40px);
    padding: 16px;
    background: #fff;
    border-radius: 0 0 12px 12px;
    box-shadow: 0 16px 40px rgba(0,0,0,0.3);
}
.gf-search-overlay__form {
    flex: 1;
    display: flex;
    gap: 3px;
    padding: 3px;
    background: #f7fafc;
    border: 1px solid #e2e8f0;
    border-radius: 9px;
}
.gf-search-overlay__input {
    flex: 1;
    height: 36px;
    padding: 0 12px;
    background: transparent;
    border: 0;
    border-radius: 6px;
    font-size: 15px;
    color: #1a202c;
    transition: box-shadow 0.15s;
}
.gf-search-overlay__input:focus {
    outline: none;
    background: #fff;
    box-shadow: 0 0 0 2px #99cc33;
}
.gf-search-overlay__submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    background: #99cc33;
    border: 0;
    border-radius: 6px;
    color: #fff;
    cursor: pointer;
    transition: background 0.15s;
}
.gf-search-overlay__submit:hover { background: #7ab32a; }
.gf-search-overlay__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    background: transparent;
    border: 0;
    color: #718096;
    cursor: pointer;
    transition: color 0.15s;
}
.gf-search-overlay__close:hover { color: #1a202c; }

/* === PRIMARY NAV DROPDOWNS ===
 * Restyles Bootstrap's default `.dropdown-menu` (flat border, 4px radius,
 * plain hover) to match the rest of the design system. `.gf-dropdown__item
 * --secondary` (set via the menu item's CSS Classes field in wp-admin) is
 * used for lower-priority items like "Legacy Downloads" — visually
 * separated with a divider rather than looking equal to current products. */
.dropdown-menu {
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(26,31,53,0.12);
    padding: 6px;
    overflow: hidden;
    margin-top: 8px;
}
.dropdown-menu > li > a.gf-mainnav__link {
    display: block;
    padding: 8px 14px;
    border-radius: 6px;
    font-size: 14px;
    color: #2d3748;
}
.dropdown-menu > li > a.gf-mainnav__link:hover,
.dropdown-menu > li > a.gf-mainnav__link:focus {
    background: #f2f9e6;
    color: #1a202c;
}
/* --divider: a plain separator between groups of otherwise-equal items
 * (e.g. Product's Overview/AI vs. its feature-category items) — structure
 * only, no change in visual weight. --secondary shares the same
 * divider/spacing (a lesser-items group still needs visual separation
 * from what's above it) and additionally de-emphasizes its own text —
 * kept as two classes, not one, so a plain grouping divider never
 * implies "these items matter less" the way --secondary deliberately
 * does (e.g. Legacy Downloads). */
.dropdown-menu > li.gf-dropdown__item--divider,
.dropdown-menu > li.gf-dropdown__item--secondary {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid #e2e8f0;
}
.dropdown-menu > li.gf-dropdown__item--secondary > a.gf-mainnav__link {
    color: #a0aec0;
    font-size: 13px;
}
/* External-link indicator for any dropdown item that opens in a new tab
 * (target="_blank", set via WP-CLI --target on the menu item) — an
 * unannounced context change is disorienting, especially for screen
 * readers, so this is a real accessibility signal, not just decoration.
 * Applies generally to any current/future off-site dropdown link, not
 * hardcoded to one item. */
.dropdown-menu > li > a.gf-mainnav__link[target="_blank"]::after {
    content: '';
    display: inline-block;
    width: 11px;
    height: 11px;
    margin-left: 6px;
    vertical-align: -1px;
    background-color: currentColor;
    opacity: 0.55;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

/* === HEADER: logo + nav share one row, vertically centered ===
 * The logo SVG renders ~50px tall — taller than a single nav-link row.
 * Nothing was vertically centering it against the nav, so .navbar-header
 * (float:left) and #primaryNav (float:right) just stacked: the float
 * model has no way to center two different-height siblings against a
 * shared middle line, so the nav row sat directly *below* the logo
 * instead of beside it. Same continuous dark background on both, so it
 * doesn't read as an obvious split the way a visible seam would — but
 * it's the same bug as the nav-items-wrap problem, one level up.
 * Flexbox with align-items:center solves this directly: it centers
 * items of different heights against each other by construction, which
 * floats have no equivalent for. */
@media (min-width: 768px) {
    .site-nav > .container-fluid {
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
    }
    .site-nav .navbar-header {
        float: none;
    }
    .site-nav #primaryNav {
        flex: 1;
        /* Flex items refuse to shrink below their content's natural size
         * by default (min-width:auto is the initial value) — without
         * this override, that would fight the white-space:nowrap +
         * max-width:100% overflow handling below, forcing the row wider
         * than the space actually available instead of letting it
         * overflow (which gf-nav.js/that CSS is what's supposed to
         * catch and collapse into "More"). */
        min-width: 0;
        /* .gf-mainnav is still float:right (Bootstrap's .navbar-right) —
         * mixing a float child inside a min-width:0 flex item produced a
         * real, visible bug: content (the "Get Started" button) clipped
         * off the edge instead of triggering the overflow collapse,
         * since float width-resolution inside a shrunk flex item is a
         * known inconsistent edge case. Making #primaryNav a flex
         * container itself and right-aligning .gf-mainnav via
         * justify-content instead of float removes the mixed model
         * entirely — .gf-mainnav's max-width:100% then resolves cleanly
         * against #primaryNav's actual flex-allocated width. */
        display: flex;
        justify-content: flex-end;
    }
    .site-nav .gf-mainnav {
        float: none;
    }
}

/* === PRIMARY NAV OVERFLOW ("More" menu) ===
 * Built entirely in JS (gf-nav.js), not server-rendered — it collapses
 * .gf-mainnav__item--collapsible items (in reverse order) into a "More"
 * dropdown when the nav would otherwise wrap to a second line, restoring
 * them as space allows.
 *
 * gf-nav.js needs to detect "does this overflow" WITHOUT waiting for an
 * actual visual wrap to happen first — checking rendered row position
 * after the fact turned out to be racy across browsers/timing (a real
 * width range showed a stuck two-row state before "More" ever kicked in).
 * These two properties make that detection deterministic instead:
 * white-space:nowrap stops items from ever wrapping to a second row (so
 * there's nothing to race against — they overflow horizontally instead),
 * and max-width:100% gives the floated <ul> (normally width:auto,
 * shrink-to-fit) an actual boundary to overflow *against* — without a
 * constrained width there's nothing for scrollWidth to exceed. Together
 * this makes clientWidth vs scrollWidth a plain, reliable arithmetic
 * check for "does the content fit," with no dependency on wrap having
 * already occurred. Deliberately NOT paired with overflow:hidden — every
 * dropdown-menu is an absolutely-positioned descendant that extends below
 * the nav bar, and overflow:hidden here would clip all of them, not just
 * the horizontal spillover. Unclipped horizontal overflow is fine: within
 * a single reflow() call the correction happens synchronously before any
 * paint, so it's never actually visible except in the rare case where
 * even full collapse can't fit right at the 768px floor. */
@media (min-width: 768px) {
    .gf-mainnav {
        white-space: nowrap;
        max-width: 100%;
    }
}

/* Collapsed items are hidden in place, never relocated in the DOM — see
 * the architecture note at the top of the "More" menu code in gf-nav.js
 * for why (in short: toggling this is far cheaper per resize tick than
 * physically moving nodes, which is what microsoft.com's own header does
 * too). display:none removes it from layout entirely, exactly as if the
 * node had been removed, without the DOM-tree-restructuring cost of
 * actually doing so.
 * !important is deliberate: `.gf-mainnav > li.menu-item { display:
 * inline-block }` in styles.css (0,2,1) otherwise outranks a single class
 * (0,1,0) on the exact same property, which would silently make every
 * collapsed item ignore this rule entirely — the whole mechanism depends
 * on this actually winning regardless of what else targets `display`. */
.gf-mainnav__item--collapsed {
    display: none !important;
}

/* Only the nested case needs new CSS here beyond the above: a
 * collapsed item that itself has a submenu (e.g. Compare) becomes a
 * dropdown nested inside the "More" dropdown, and Bootstrap 3 has no
 * built-in support for that — by default a nested .dropdown-menu would
 * stack below its toggle like a top-level one, inside an already-open
 * menu. This flies it out sideways instead. Always opens to the LEFT:
 * "More" sits at the far-right edge of the header, so a rightward flyout
 * would run off the viewport — a static leftward default is correct here
 * without needing edge-collision detection (gf-nav.js has the matching
 * click-handling fix for the Bootstrap "closes parent" bug this exposes). */
.dropdown-menu .dropdown-menu {
    top: -7px;
    left: auto;
    right: 100%;
    margin-right: 2px;
}
/* The base .dropdown-menu rule sets overflow:hidden purely so hover
 * backgrounds respect its own rounded corners — harmless for a normal
 * dropdown, but it also clips the flyout above since that's positioned
 * outside this box (right: 100%). Only .gf-mainnav__more-menu can ever
 * contain a nested dropdown, so only it needs the override; every other
 * .dropdown-menu keeps the corner-clipping behavior. */
.gf-mainnav__more-menu {
    overflow: visible;
}

/* === STICKY NAV === */
.gf-sticky-nav {
    position: sticky;
    top: 0;
    z-index: 200;
    background: #fff;
    border-bottom: 1px solid #e2e8f0;
    box-shadow: 0 2px 8px rgba(0,0,0,.06);
}
.gf-sticky-nav__inner {
    max-width: 1100px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 0 20px;
}
.gf-sticky-nav__inner::-webkit-scrollbar { display: none; }
.gf-sticky-nav a {
    display: block;
    padding: 13px 14px;
    font-size: 13px;
    font-weight: 600;
    color: #718096;
    text-decoration: none !important;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    transition: color .15s, border-color .15s;
}
.gf-sticky-nav a:hover {
    color: #99cc33;
    border-bottom-color: #99cc33;
    text-decoration: none !important;
}
@media (min-width: 600px) {
    /* justify-content:center only above the mobile breakpoint — combined
     * with overflow-x:auto on a narrow viewport, centered flex content
     * can make the start of an overflowing row unreachable by scroll in
     * some browsers, so mobile keeps the default (flex-start) instead. */
    .gf-sticky-nav__inner { padding: 0 24px; justify-content: center; }
    .gf-sticky-nav a { padding: 13px 16px; }
}

/* === HERO === */
.gf-hero {
    background: #1a1f35;
    padding: 48px 20px;
    color: #fff;
}
.gf-hero__content {
    max-width: 1100px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr;
    gap: 36px;
    align-items: center;
}
.gf-hero__eyebrow {
    display: inline-block;
    background: rgba(153,204,51,0.1);
    border: 1px solid rgba(153,204,51,0.3);
    color: #99cc33;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 4px 12px;
    border-radius: 100px;
    margin-bottom: 20px;
}
.gf-hero h1 {
    font-size: 30px;
    font-weight: 800;
    line-height: 1.15;
    margin: 0 0 16px;
    color: #fff;
    letter-spacing: -0.02em;
}
.gf-hero__desc {
    font-size: 16px;
    line-height: 1.6;
    color: #a0aec0;
    margin-bottom: 28px;
}
.gf-hero__buttons {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}
@media (min-width: 900px) {
    .gf-hero { padding: 40px 40px 56px; }
    .gf-hero__content { grid-template-columns: 1fr 1fr; gap: 60px; }
    .gf-hero h1 { font-size: 46px; }
    .gf-hero__desc { font-size: 18px; }
}

/* .gf-hero--centered: single-column variant for pages with no side-by-side
 * graphic (e.g. a terminal demo) — just a centered headline and copy. */
.gf-hero--centered .gf-hero__content { grid-template-columns: 1fr; max-width: 700px; text-align: center; }
.gf-hero--centered .gf-checklist { align-items: center; }
.gf-hero--centered .gf-hero__buttons { justify-content: center; }

/* .gf-hero__visual: layered real-screenshot composite for the base
 * (non-centered) two-column hero. Hidden below 900px rather than
 * reflowed into the single column — three overlapping rotated cards
 * only read as a coherent image at the size the desktop column gives
 * them; shrunk into a mobile-width column they'd just overlap illegibly.
 * The homepage is the first page to use the non-centered .gf-hero, so
 * this is new, not a rename of something existing. */
.gf-hero__visual { display: none; }
@media (min-width: 900px) {
    .gf-hero__visual {
        display: block;
        position: relative;
        width: 100%;
        aspect-ratio: 1 / 0.85;
    }
    .gf-hero__visual-card {
        position: absolute;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: 0 20px 50px rgba(0,0,0,0.35);
        border: 1px solid rgba(255,255,255,0.12);
    }
    .gf-hero__visual-card img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
    .gf-hero__visual-card--1 { top: 0; left: 0; width: 62%; height: 60%; transform: rotate(-4deg); z-index: 1; }
    .gf-hero__visual-card--2 { top: 14%; left: 30%; width: 66%; height: 62%; transform: rotate(2deg); z-index: 2; }
    .gf-hero__visual-card--3 { bottom: 0; right: 0; width: 50%; height: 46%; transform: rotate(6deg); z-index: 3; }
}

/* === TERMINAL === */
.gf-terminal {
    position: relative;
    background: #0a0e1a;
    border-radius: 12px;
    border: 1px solid rgba(255,255,255,0.12);
    overflow: hidden;
    box-shadow: 0 24px 64px rgba(0,0,0,0.5);
}
/* .gf-terminal--scrollable is toggled by gf-nav.js when a terminal's
 * content actually overflows — the fade only appears when there's really
 * more to scroll to, not as a permanent decoration. */
.gf-terminal--scrollable::after {
    content: '';
    position: absolute;
    left: 1px;
    right: 1px;
    bottom: 1px;
    height: 100px;
    background: linear-gradient(to bottom, rgba(10,14,26,0), rgba(10,14,26,0.92));
    border-radius: 0 0 11px 11px;
    pointer-events: none;
    z-index: 1;
}
/* Down-arrow scroll hint — sits on top of the fade, hides on hover since
 * a cursor inside the terminal already implies the visitor found it. On
 * touch devices (no hover state) it just stays visible, which is the
 * right fallback there. */
.gf-terminal--scrollable::before {
    content: '↓';
    position: absolute;
    left: 50%;
    bottom: 12px;
    transform: translateX(-50%);
    width: 28px;
    height: 28px;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #99cc33;
    color: #0a0e1a;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    border-radius: 50%;
    box-shadow: 0 2px 8px rgba(0,0,0,0.35);
    pointer-events: none;
    transition: opacity 0.15s;
}
.gf-terminal--scrollable:hover::before {
    opacity: 0;
}
.gf-terminal__header {
    background: #131825;
    padding: 12px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.gf-terminal__dot { width: 12px; height: 12px; border-radius: 50%; }
.gf-terminal__dot--red    { background: #ff5f57; }
.gf-terminal__dot--yellow { background: #ffbd2e; }
.gf-terminal__dot--green  { background: #28ca41; }
.gf-terminal__title {
    color: #a0aec0;
    font-size: 12px;
    margin-left: 8px;
    font-family: monospace;
}
.gf-terminal__body {
    padding: 16px;
    font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', monospace;
    font-size: 12px;
    line-height: 1.6;
    max-height: 420px;
    overflow-x: auto;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(153,204,51,0.4) transparent;
}
.gf-terminal__body::-webkit-scrollbar { width: 8px; height: 8px; }
.gf-terminal__body::-webkit-scrollbar-track { background: transparent; }
.gf-terminal__body::-webkit-scrollbar-thumb {
    background: rgba(153,204,51,0.4);
    border-radius: 4px;
}
.gf-terminal__body::-webkit-scrollbar-thumb:hover { background: rgba(153,204,51,0.6); }
.gf-terminal__line {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-bottom: 4px;
    white-space: pre;
}
.gf-terminal__prompt  { color: #99cc33; flex-shrink: 0; }
.gf-terminal__output  { color: #a0aec0; }
.gf-terminal__output--success { color: #99cc33; }
@media (min-width: 600px) {
    .gf-terminal__body { padding: 20px; font-size: 13px; }
}

/* === CONVERSATION ELEMENTS (hero + MCP demo) === */
.gf-convo__user {
    background: rgba(153,204,51,0.1);
    border: 1px solid rgba(153,204,51,0.2);
    border-radius: 8px;
    padding: 10px 14px;
    margin-bottom: 12px;
    color: #e2e8f0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 13px;
}
.gf-convo__user-label {
    font-size: 10px;
    font-weight: 700;
    color: #99cc33;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 5px;
}
.gf-convo__tool {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    font-family: monospace;
    font-size: 12px;
    color: #a0aec0;
}
.gf-convo__tool-dot { color: #99cc33; font-weight: 700; }
.gf-convo__tool-name {
    color: #99cc33;
    background: rgba(153,204,51,0.1);
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 11px;
}
.gf-convo__tool-meta { color: #a0aec0; font-size: 11px; }
.gf-convo__response {
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 8px;
    padding: 14px;
    margin-top: 10px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.gf-convo__response-header {
    font-size: 13px;
    font-weight: 700;
    color: #e2e8f0;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.gf-convo__response-item {
    display: grid;
    grid-template-columns: 52px 1fr auto;
    gap: 8px;
    align-items: baseline;
    padding: 4px 0;
    font-size: 12px;
}
.gf-convo__ti { color: #99cc33; font-family: monospace; font-weight: 600; }
.gf-convo__summary { color: #e2e8f0; }
.gf-convo__blocker { color: #fc8181; font-size: 11px; text-align: right; }

/* === SECTIONS === */
.gf-section { padding: 48px 20px; }
.gf-section--gray { background: #f7fafc; }
.gf-section--dark .gf-section__tag { background: rgba(153,204,51,0.1); color: #99cc33; }
.gf-section--dark .gf-section__header h2 { color: #fff; }
.gf-section--dark .gf-section__header p  { color: #a0aec0; }
.gf-section--dark .gf-step-list__content h4 { color: #e2e8f0; }
.gf-section--dark .gf-step-list__content p  { color: #a0aec0; }
.gf-section__header {
    text-align: center;
    max-width: 640px;
    margin: 0 auto 40px;
}
.gf-section__tag {
    display: inline-block;
    background: #f2f9e6;
    color: #99cc33;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 4px 12px;
    border-radius: 100px;
    margin-bottom: 16px;
}
.gf-section__header h2 {
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -0.02em;
    margin: 0 0 16px;
    color: #1a202c;
    line-height: 1.2;
}
.gf-section__header p {
    font-size: 16px;
    color: #718096;
    margin: 0;
    line-height: 1.6;
}
@media (min-width: 768px) {
    .gf-section { padding: 40px 40px 56px; }
    .gf-section__header { margin: 0 auto 60px; }
    .gf-section__header h2 { font-size: 36px; }
    .gf-section__header p { font-size: 18px; }
}

/* === MCP SECTION === */
.gf-mcp-section { padding: 48px 20px; }
.gf-mcp-section, .gf-section--dark { background: #1a1f35; color: #fff; }
.gf-mcp-section__inner { max-width: 1100px; margin: 0 auto; }
.gf-mcp-section__intro {
    text-align: center;
    max-width: 700px;
    margin: 0 auto 40px;
}
.gf-mcp-section__intro .gf-section__tag {
    background: rgba(153,204,51,0.1);
    color: #99cc33;
}
.gf-mcp-section__intro h2 {
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.15;
    color: #fff;
    margin: 0 0 16px;
}
.gf-mcp-section__intro p,
.gf-prompts__intro {
    font-size: 16px;
    color: #a0aec0;
    line-height: 1.6;
    margin: 0;
}
.gf-mcp-section__actions { margin-top: 32px; text-align: center; }
@media (min-width: 768px) {
    .gf-mcp-section { padding: 40px 40px 56px; }
}
@media (min-width: 900px) {
    .gf-mcp-section__intro { margin: 0 auto 60px; }
    .gf-mcp-section__intro h2 { font-size: 40px; }
    .gf-mcp-section__actions { margin-top: 40px; }
}

/* === ARCHITECTURE DIAGRAM === */
.gf-arch-diagram {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    margin: 32px auto 0;
    max-width: 640px;
}
.gf-arch-diagram__node {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    padding: 12px 20px;
    text-align: center;
    min-width: 140px;
}
.gf-arch-diagram__node-label {
    font-size: 13px;
    font-weight: 700;
    color: #e2e8f0;
    white-space: nowrap;
}
.gf-arch-diagram__node-sub {
    font-size: 11px;
    color: #e2e8f0;
    margin-top: 3px;
    white-space: nowrap;
}
.gf-arch-diagram__connector {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 0 10px;
    gap: 3px;
    transform: rotate(90deg);
}
.gf-arch-diagram__connector-arrow {
    color: #99cc33;
    font-size: 20px;
    line-height: 1;
    font-family: monospace;
}
.gf-arch-diagram__connector-label {
    font-size: 10px;
    color: #99cc33;
    font-family: 'SF Mono', 'Monaco', monospace;
    letter-spacing: .04em;
}
@media (min-width: 560px) {
    .gf-arch-diagram { flex-direction: row; flex-wrap: wrap; gap: 0; margin-top: 36px; }
    .gf-arch-diagram__connector { flex-direction: column; transform: none; }
}

.gf-mcp-pillars {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
    margin-bottom: 40px;
}
.gf-mcp-pillar {
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 12px;
    padding: 28px;
}
.gf-mcp-pillar__icon {
    width: 40px;
    height: 40px;
    background: rgba(153,204,51,0.1);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 16px;
    color: #99cc33;
}
.gf-mcp-pillar__icon svg { width: 20px; height: 20px; stroke: #99cc33; fill: none; }
.gf-mcp-pillar h3 { font-size: 16px; font-weight: 700; color: #fff; margin: 0 0 8px; }
.gf-mcp-pillar p  { font-size: 14px; color: #a0aec0; line-height: 1.6; margin: 0; }
.gf-mcp-pillar code {
    font-family: monospace;
    font-size: 12px;
    color: #99cc33;
    background: rgba(153,204,51,0.1);
    padding: 1px 6px;
    border-radius: 4px;
}
@media (min-width: 900px) {
    .gf-mcp-pillars { grid-template-columns: repeat(3, 1fr); margin-bottom: 60px; }
}

/* === PROMPTS (grouped) === */
.gf-prompts__label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #4a5568;
    margin-bottom: 8px;
    text-align: center;
}
.gf-prompts__intro {
    text-align: center;
    max-width: 520px;
    margin: 0 auto;
}
.gf-prompts__category-header {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: #99cc33;
    padding-bottom: 10px;
    margin: 32px 0 16px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.gf-prompts__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    margin-bottom: 4px;
}
@media (min-width: 600px) {
    .gf-prompts__grid--3, .gf-prompts__grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
    .gf-prompts__grid--3 { grid-template-columns: repeat(3, 1fr); }
    /* .gf-prompts__grid--4's 4-col rule lives with .gf-feature-grid--4 further
     * down, after .gf-feature-grid's own 3-col rule — cascade order matters
     * here since both this and that rule can match at the same viewport. */
}
.gf-prompt-card {
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 10px;
    padding: 20px 18px;
    transition: border-color 0.15s;
}
.gf-prompt-card:hover { border-color: rgba(153,204,51,0.3); }
.gf-prompt-card__name {
    font-family: 'SF Mono', 'Monaco', monospace;
    font-size: 12px;
    color: #99cc33;
    background: rgba(153,204,51,0.1);
    display: inline-block;
    padding: 3px 8px;
    border-radius: 4px;
    margin-bottom: 10px;
}
.gf-prompt-card h4 { font-size: 13px; font-weight: 700; color: #e2e8f0; margin: 0 0 6px; }
.gf-prompt-card p  { font-size: 12px; color: #718096; margin: 0; line-height: 1.5; }

/* MCP demo */
.gf-mcp-demo {
    display: grid;
    grid-template-columns: 1fr;
    gap: 32px;
    align-items: start;
    margin-bottom: 40px;
}
.gf-mcp-demo__text h3 {
    font-size: 22px;
    font-weight: 800;
    color: #fff;
    margin: 0 0 16px;
    letter-spacing: -0.01em;
    line-height: 1.3;
}
.gf-mcp-demo__text p {
    font-size: 15px;
    color: #a0aec0;
    line-height: 1.7;
    margin: 0 0 16px;
}
.gf-mcp-demo__setup {
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 10px;
    overflow: hidden;
    margin-top: 28px;
}
.gf-mcp-demo__setup-header {
    background: rgba(255,255,255,0.04);
    padding: 10px 16px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #a0aec0;
    font-family: monospace;
}
.gf-mcp-demo__setup pre {
    padding: 16px;
    margin: 0;
    background: transparent;
    border: none;
    font-family: 'SF Mono', 'Monaco', monospace;
    font-size: 12px;
    color: #a0aec0;
    white-space: pre;
    line-height: 1.8;
    overflow-x: auto;
}
@media (min-width: 900px) {
    .gf-mcp-demo { grid-template-columns: 1fr 1fr; gap: 48px; margin-bottom: 48px; }
    .gf-mcp-demo__text h3 { font-size: 26px; }
}

/* === CALCULATOR (interactive savings calculator) ===
 * First used on /pricing/. Lives inside a dark section (.gf-mcp-section)
 * for the same reasons every other dark-section content does. Purely
 * visual — the calculator's own JS (see the page's script) only ever
 * touches these elements by `id`, never by class, so this styling layer
 * can change freely without touching the calculation logic or the real
 * competitor-pricing data it's driven by. */
.gf-calculator {
    max-width: 940px;
    margin: 0 auto;
    padding: 24px;
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 12px;
}
.gf-calculator__inputs {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    margin-bottom: 32px;
}
.gf-calculator__field { flex: 1; min-width: 240px; }
.gf-calculator__field label {
    display: block;
    font-weight: 700;
    font-size: 14px;
    margin-bottom: 10px;
    color: #e2e8f0;
}
.gf-calculator__field select {
    width: 100%;
    padding: 12px 14px;
    font-size: 15px;
    border: 1px solid rgba(255,255,255,0.2);
    border-radius: 8px;
    background: rgba(255,255,255,0.08);
    color: #fff;
    cursor: pointer;
}
.gf-calculator__field select option,
.gf-calculator__field select optgroup { background: #1a1f35; color: #fff; }
.gf-calculator__slider { display: flex; align-items: center; gap: 16px; }
.gf-calculator__slider input[type="range"] {
    flex: 1;
    height: 6px;
    border-radius: 4px;
    background: rgba(255,255,255,0.2);
    -webkit-appearance: none;
}
.gf-calculator__slider input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #99cc33;
    cursor: pointer;
    border: 3px solid #fff;
}
.gf-calculator__slider-value { font-size: 16px; font-weight: 700; color: #99cc33; min-width: 90px; text-align: right; }
.gf-calculator__results {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin-bottom: 24px;
}
.gf-calculator__result {
    flex: 1;
    min-width: 240px;
    max-width: 340px;
    padding: 22px;
    border-radius: 10px;
    text-align: center;
}
.gf-calculator__result--competitor { background: rgba(220,53,69,0.12); border: 1px solid rgba(220,53,69,0.3); }
.gf-calculator__result--gforge { background: rgba(153,204,51,0.1); border: 1px solid rgba(153,204,51,0.35); }
.gf-calculator__result-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.5); margin-bottom: 6px; }
.gf-calculator__result-product { font-size: 14px; font-weight: 700; margin-bottom: 8px; min-height: 20px; }
.gf-calculator__result-product a { color: inherit; }
.gf-calculator__result-amount { font-size: 30px; font-weight: 800; margin-bottom: 4px; }
.gf-calculator__result--competitor .gf-calculator__result-amount { color: #ff6b6b; }
.gf-calculator__result--gforge .gf-calculator__result-amount { color: #99cc33; }
.gf-calculator__result-period { font-size: 13px; color: rgba(255,255,255,0.5); margin-bottom: 10px; }
.gf-calculator__result-breakdown { font-size: 12px; color: rgba(255,255,255,0.45); line-height: 1.5; min-height: 32px; }
.gf-calculator__result-breakdown a { color: #99cc33; }
.gf-calculator__vs { font-size: 18px; font-weight: 700; color: rgba(255,255,255,0.25); flex-shrink: 0; }
.gf-calculator__savings {
    text-align: center;
    padding: 22px;
    background: rgba(153,204,51,0.08);
    border: 1px solid rgba(153,204,51,0.25);
    border-radius: 10px;
    margin-bottom: 20px;
}
.gf-calculator__savings-label { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.6); margin-bottom: 8px; }
.gf-calculator__savings-amount { font-size: 38px; font-weight: 800; color: #99cc33; margin-bottom: 18px; }
.gf-calculator__savings-ctas { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.gf-calculator__disclaimer { text-align: center; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.1); }
.gf-calculator__disclaimer p { font-size: 12px; color: rgba(255,255,255,0.4); margin: 0; line-height: 1.6; }
.gf-calculator__disclaimer a { color: rgba(255,255,255,0.55); }
@media (max-width: 700px) {
    .gf-calculator__results { flex-direction: column; }
    .gf-calculator__result { max-width: 100%; width: 100%; }
    .gf-calculator__vs { transform: rotate(90deg); margin: 2px 0; }
}

/* === INCLUDED COMPARISON (itemized $$$ vs checkmark, two columns) ===
 * First used on /pricing/'s "Everything Included" section. Distinct
 * from .gf-compare-table (a feature-by-feature table with numeric cost
 * cells) and .gf-compare-card (a link-out grid) — this is a static,
 * non-linking side-by-side item list. */
.gf-included-compare {
    display: flex;
    flex-wrap: wrap;
    gap: 32px;
    max-width: 800px;
    margin: 0 auto;
}
.gf-included-compare__col { flex: 1; min-width: 280px; padding: 28px; border-radius: 12px; }
.gf-included-compare__col--bad { background: #fef2f2; border: 1px solid #fecaca; }
.gf-included-compare__col--good { background: #f0fdf4; border: 1px solid #bbf7d0; }
.gf-included-compare__col h3 { text-align: center; font-size: 18px; margin: 0 0 18px; color: #1a202c; }
.gf-included-compare__list { list-style: none; padding: 0; margin: 0 0 18px; }
.gf-included-compare__list li {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 0;
    border-bottom: 1px solid rgba(0,0,0,0.08);
    font-size: 14px;
    color: #2d3748;
}
.gf-included-compare__list li:last-child { border-bottom: none; }
.gf-included-compare__cost { color: #dc2626; font-weight: 700; }
.gf-included-compare__check { color: #16a34a; font-weight: 700; font-size: 16px; }
.gf-included-compare__total { text-align: center; font-weight: 700; padding: 12px; border-radius: 8px; font-size: 14px; }
.gf-included-compare__total--bad { background: #fecaca; color: #991b1b; }
.gf-included-compare__total--good { background: #bbf7d0; color: #166534; }

/* === SHARED CODE SYNTAX-HIGHLIGHT UTILITIES ===
 * Previously duplicated as .hl-key/.hl-str (mcp setup) and
 * .cli-code-comment/-command/-flag/-string (quickstart) and
 * .comment/.success/.tool (use-case code). Consolidated to one set. */
.gf-syntax--key      { color: #f6ad55; }
.gf-syntax--string    { color: #68d391; }
.gf-syntax--comment   { color: #a0aec0; }
.gf-syntax--command   { color: #68d391; }
.gf-syntax--flag      { color: #99cc33; }
.gf-syntax--success   { color: #68d391; }
.gf-syntax--tool      { color: #99cc33; font-size: 11px; }

/* === DOWNLOAD === */
.gf-download-grid {
    display: grid;
    /* auto-fit collapses unused tracks to 0 instead of leaving them empty,
     * so this adapts to however many cards a page actually has (2 on
     * downloads, 4 on gforge-cli) without a fixed column count leaving
     * dead space when there are fewer cards than the grid was sized for. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    max-width: 1000px;
    margin: 0 auto;
}
.gf-download-card {
    background: #fff;
    border: 2px solid #e2e8f0;
    border-radius: 12px;
    padding: 24px 20px;
    text-align: center;
    text-decoration: none;
    color: #2d3748;
    transition: all 0.2s ease;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    position: relative;
    cursor: pointer;
}
.gf-download-card:hover {
    border-color: #99cc33;
    box-shadow: 0 4px 20px rgba(153,204,51,0.15);
    text-decoration: none;
    color: #2d3748;
    transform: translateY(-2px);
}
.gf-download-card--detected,
.gf-download-card--recommended { border-color: #99cc33; background: #f2f9e6; }
.gf-download-card--recommended .gf-download-card__badge { opacity: 1; }
.gf-download-card__badge {
    position: absolute;
    top: -10px;
    left: 50%;
    transform: translateX(-50%);
    background: #99cc33;
    color: white;
    font-size: 10px;
    font-weight: 700;
    padding: 2px 10px;
    border-radius: 100px;
    white-space: nowrap;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    opacity: 0;
    transition: opacity 0.2s;
}
.gf-download-card--detected .gf-download-card__badge { opacity: 1; }
.gf-download-card__icon { width: 48px; height: 48px; }
.gf-download-card__icon svg { width: 100%; height: 100%; fill: #4a5568; }
.gf-download-card--detected .gf-download-card__icon svg { fill: #99cc33; }
.gf-download-card__name { font-weight: 700; font-size: 14px; }
.gf-download-card__arch { font-family: monospace; font-size: 11px; color: #a0aec0; }
.gf-download-card__version { font-size: 12px; color: #718096; }
.gf-download-card__checksum {
    font-size: 10px;
    color: #a0aec0;
    font-family: 'SF Mono', 'Monaco', monospace;
    line-height: 1.4;
    text-align: center;
    padding: 0 4px;
}
.gf-download-card__link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #99cc33;
    font-size: 13px;
    font-weight: 600;
    margin-top: 4px;
}
.gf-download-card__link svg { width: 14px; height: 14px; }
.gf-checklist {
    list-style: none;
    padding: 0;
    margin: 16px 0;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.gf-checklist li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 14px;
    color: #4a5568;
}
.gf-checklist li::before {
    content: '✓';
    color: #99cc33;
    font-weight: 700;
    flex-shrink: 0;
}
/* --light: for use on a dark background, e.g. inside .gf-hero */
.gf-checklist--light { margin: 0 0 32px; }
.gf-checklist--light li { color: #e2e8f0; font-size: 15px; }
.gf-version-note {
    max-width: 640px;
    margin: 32px auto 0;
    text-align: center;
    font-size: 14px;
    color: #718096;
    line-height: 1.6;
}
.gf-version-note .gf-btn { margin-top: 14px; }

/* === FEATURE CARDS === */
.gf-feature-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
    max-width: 1000px;
    margin: 0 auto;
}
@media (min-width: 480px) {
    .gf-feature-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 768px) {
    .gf-feature-grid { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}
@media (min-width: 900px) {
    .gf-prompts__grid--4, .gf-feature-grid--4 { grid-template-columns: repeat(4, 1fr); }
}
/* --2: pins at 2 columns instead of upgrading to 3 at 768px — for a grid
 * that will only ever hold 2 cards (e.g. one grouped cluster within a
 * larger capability map), where 3 columns would leave an uneven gap.
 * First used on the Overview page's Plan & Track / Build & Ship / Know &
 * Collaborate clusters. */
.gf-feature-grid--2 { grid-template-columns: 1fr; }
@media (min-width: 480px) {
    .gf-feature-grid--2 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 768px) {
    .gf-feature-grid--2 { grid-template-columns: repeat(2, 1fr); }
}
.gf-feature-card {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    padding: 24px;
    transition: box-shadow 0.2s;
}
.gf-feature-card:hover { box-shadow: 0 4px 20px rgba(0,0,0,0.08); }
.gf-feature-card--stack { display: flex; flex-direction: column; }
.gf-feature-card--stack p { flex: 1; }
.gf-feature-card--stack .gf-btn { margin-top: 16px; align-self: flex-start; }
.gf-feature-card__icon {
    width: 44px;
    height: 44px;
    background: #f2f9e6;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 16px;
}
.gf-feature-card__icon svg { width: 22px; height: 22px; stroke: #99cc33; fill: none; }
.gf-feature-card h3 { font-size: 16px; font-weight: 700; color: #1a202c; margin: 0 0 8px; }
.gf-feature-card p  { font-size: 14px; color: #718096; margin: 0; line-height: 1.6; }
.gf-feature-card code {
    background: #f0f4f8;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 12px;
    color: #c53030;
    border: 1px solid #e2e8f0;
}

/* === COMMIT LINKING / INFO BOX === */
.gf-info-box {
    max-width: 860px;
    margin: 0 auto;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 16px;
    padding: 24px;
}
.gf-info-box h3 {
    font-size: 18px;
    font-weight: 700;
    color: #1a202c;
    margin: 0 0 12px;
    display: flex;
    align-items: center;
    gap: 10px;
}
.gf-info-box h3 svg { width: 22px; height: 22px; stroke: #99cc33; fill: none; flex-shrink: 0; }
.gf-info-box > p { color: #718096; font-size: 15px; line-height: 1.6; margin: 0 0 24px; }
.gf-info-box__methods { display: grid; grid-template-columns: 1fr; gap: 20px; }
.gf-info-box__method { background: #f7fafc; border-radius: 10px; padding: 20px; }
.gf-info-box__method h4 { font-size: 14px; font-weight: 700; color: #1a202c; margin: 0 0 8px; }
.gf-info-box__method p  { font-size: 13px; color: #718096; margin: 0 0 12px; line-height: 1.5; }
.gf-info-box__method code {
    display: block;
    background: #1a202c;
    color: #68d391;
    padding: 12px 14px;
    border-radius: 6px;
    font-family: monospace;
    font-size: 12px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}
@media (min-width: 768px) {
    .gf-info-box { padding: 40px; }
    .gf-info-box h3 { font-size: 20px; }
    .gf-info-box > p { margin: 0 0 28px; }
    .gf-info-box__methods { grid-template-columns: 1fr 1fr; gap: 24px; }
}

/* === USE CASES === */
.gf-usecase-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
    max-width: 1000px;
    margin: 0 auto;
}
@media (min-width: 768px) {
    .gf-usecase-grid { grid-template-columns: repeat(2, 1fr); gap: 24px; }
}
.gf-usecase-card {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    padding: 24px;
}
.gf-usecase-card__tag {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 3px 10px;
    border-radius: 100px;
    background: #f2f9e6;
    color: #99cc33;
    margin-bottom: 12px;
}
.gf-usecase-card h3 { font-size: 18px; font-weight: 700; color: #1a202c; margin: 0 0 8px; }
.gf-usecase-card p  { font-size: 14px; color: #718096; line-height: 1.6; margin: 0 0 16px; }
.gf-usecase-card__code {
    background: #1a202c;
    border-radius: 8px;
    padding: 14px 16px;
    font-family: 'SF Mono', 'Monaco', monospace;
    font-size: 12px;
    color: #a0aec0;
    line-height: 1.7;
    overflow-x: auto;
}

/* === QUICK START === */
.gf-quickstart {
    max-width: 640px;
    margin: 0 auto;
}
.gf-quickstart > p { color: #718096; font-size: 15px; margin: 0 0 32px; line-height: 1.6; }
/* --split: side-by-side variant — step list on the left, a .gf-code-block
 * (or any reference content) on the right, instead of .gf-quickstart's
 * default single narrow column. Overrides the base max-width/centering
 * since a 2-up layout wants the wider section width instead. First used
 * on /jenkins/'s "up and running in four steps" + env-var reference. */
.gf-quickstart--split {
    max-width: 900px;
    display: grid;
    grid-template-columns: 1fr;
    gap: 48px;
    align-items: start;
}
@media (min-width: 900px) {
    .gf-quickstart--split { grid-template-columns: 1fr 1fr; gap: 60px; }
}
.gf-step-list { list-style: none; padding: 0; margin-top: 0; margin-bottom: 0; display: flex; flex-direction: column; gap: 20px; }
.gf-step-list li { display: flex; gap: 16px; align-items: flex-start; }
.gf-step-list__number {
    width: 32px; height: 32px;
    background: #99cc33;
    color: #fff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    flex-shrink: 0;
}
.gf-step-list__content h4 { font-size: 15px; font-weight: 700; color: #1a202c; margin: 4px 0 4px; }
.gf-step-list__content p  { font-size: 14px; color: #718096; margin: 0; line-height: 1.5; }
.gf-step-list__content code {
    background: #f0f4f8;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 12px;
    color: #c53030;
    border: 1px solid #e2e8f0;
}
.gf-step-list__item--optional .gf-step-list__number { background: #e2e8f0; color: #718096; }
.gf-step-list__content .gf-terminal { margin-top: 12px; }
.gf-code-block { background: #1a202c; border-radius: 12px; overflow: hidden; }
.gf-code-block__header {
    background: #2d3748;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.gf-code-block__filename { color: #a0aec0; font-size: 12px; font-family: monospace; }
.gf-copy-btn {
    background: transparent;
    border: 1px solid #718096;
    color: #a0aec0;
    font-size: 12px;
    padding: 4px 10px;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
    transition: all 0.15s;
}
.gf-copy-btn:hover { border-color: #a0aec0; color: #e2e8f0; }
.gf-code-block__content {
    padding: 16px;
    font-family: 'SF Mono', 'Monaco', monospace;
    font-size: 12px;
    line-height: 1.8;
    color: #a0aec0;
    white-space: pre-wrap;
    overflow-x: auto;
}
/* white-space/color/background above only reach plain text content — a
 * <pre> child ignores all of them, since Bootstrap's own bare `pre { }`
 * rule (still loaded sitewide) targets the element directly and wins
 * over anything only set on this wrapper: no wrapping (horizontal
 * scroll instead, found on the /ask-ai/ starter prompt) *and* a stray
 * light-gray Bootstrap code-block background/border showing through a
 * dark box. Re-declare every property Bootstrap's `pre` rule sets,
 * directly on <pre>, so nothing is left for it to win. */
.gf-code-block__content pre {
    margin: 0;
    padding: 0;
    background: transparent;
    border: none;
    color: inherit;
    font: inherit;
    white-space: pre-wrap;
    word-break: break-word;
}
@media (min-width: 600px) {
    .gf-code-block__content { padding: 20px; font-size: 13px; }
}

/* === FAQ / ACCORDION ===
 * Consolidates four previously separate, incompatible implementations:
 * pricing.html's static (non-collapsing) `.faq-item` card grid,
 * products-faq.html's inline-styled native <details>, support.html's
 * `.gf-faq-item` click-to-expand accordion, and the cli-derived
 * `.gf-faq__item` above. Built on native <details>/<summary> — no JS
 * needed, keyboard-accessible, and matches modern best practice. */
.gf-faq-section {
    padding: 48px 20px;
    background: #f7fafc;
}
.gf-faq-section__list {
    max-width: 760px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.gf-faq {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    overflow: hidden;
}
.gf-faq__question {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 16px 20px;
    font-size: 15px;
    font-weight: 700;
    color: #1a202c;
    cursor: pointer;
    list-style: none;
}
.gf-faq__question::-webkit-details-marker { display: none; }
.gf-faq__question:hover { background: #f7fafc; }
.gf-faq__question::after {
    content: '+';
    flex-shrink: 0;
    font-size: 20px;
    font-weight: 400;
    color: #99cc33;
    transition: transform 0.15s;
}
.gf-faq[open] > .gf-faq__question::after { transform: rotate(45deg); }
.gf-faq__answer {
    padding: 0 20px 18px;
    font-size: 15px;
    color: #4a5568;
    line-height: 1.7;
}
.gf-faq__answer code {
    background: #edf2f7;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 13px;
    font-family: 'SF Mono', 'Monaco', monospace;
    color: #c53030;
    border: 1px solid #e2e8f0;
}
@media (min-width: 768px) {
    .gf-faq-section { padding: 40px 40px 56px; }
}

/* === COMPARISON TABLE ===
 * Replaces raw Bootstrap `.table.table-striped.comparison-table` markup
 * used on the *-alternative pages. Wrapped in an overflow-x:auto
 * container since tables don't reflow — that's a universal safeguard,
 * not breakpoint-specific. */
.gf-compare-table-wrap {
    overflow-x: auto;
    border-radius: 12px;
    border: 1px solid #e2e8f0;
}
.gf-compare-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
    min-width: 480px;
}
.gf-compare-table thead {
    background: #1a202c;
}
.gf-compare-table th {
    color: #fff;
    text-align: left;
    padding: 14px 16px;
    font-weight: 700;
    white-space: nowrap;
}
.gf-compare-table th.gf-compare-table__num,
.gf-compare-table td.gf-compare-table__num { text-align: right; }
.gf-compare-table td {
    padding: 12px 16px;
    border-top: 1px solid #e2e8f0;
    color: #4a5568;
}
.gf-compare-table tbody tr:nth-child(even) { background: #f7fafc; }
/* Category divider row spanning all columns — for long tables grouped
 * into sections (e.g. "Project Management", "Code & Version Control").
 * First used on atlassian-alternative's full feature-by-feature table. */
.gf-compare-table__category td {
    background: #eef2f7 !important;
    font-weight: 700;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #4a5568;
}
.gf-compare-table__cost {
    display: inline-block;
    background: #fed7d7;
    color: #c53030;
    font-weight: 700;
    padding: 2px 10px;
    border-radius: 100px;
    font-size: 13px;
}
.gf-compare-table__cost--good {
    background: #f2f9e6;
    color: #5a8a1e;
}
/* --warn: a middle state distinct from the default (red, "not
 * available") and --good (green, "included") — "technically possible,
 * but as a separate paid add-on." First used on the *-alternative
 * pages' feature-checklist tables (e.g. "Bitbucket" as Atlassian's
 * answer to Git hosting — not absent, just a separate product/cost). */
.gf-compare-table__cost--warn {
    background: #fef3d7;
    color: #92660a;
}

/* === CALLOUT (tinted aside box) ===
 * First used on the *-alternative pages' "Who GForge Is NOT For"
 * section — deliberately plain, no checkmarks (unlike .gf-checklist,
 * which implies affirmative "you get this"). Generic enough to reuse
 * for any honest-caveat or important-aside content elsewhere. */
.gf-callout {
    max-width: 800px;
    margin: 0 auto;
    padding: 28px 32px;
    background: #f7fafc;
    border-left: 4px solid #99cc33;
    border-radius: 0 10px 10px 0;
}
.gf-callout h3 { margin: 0 0 14px; font-size: 20px; color: #1a202c; }
.gf-callout ul { margin: 0; padding-left: 20px; }
.gf-callout li { margin-bottom: 10px; color: #4a5568; line-height: 1.6; }
.gf-callout li:last-child { margin-bottom: 0; }

/* === COMPARE CARDS ===
 * Distinct from .gf-compare-table above: that's a feature-by-feature
 * table for a single comparison page. This is a small link-out grid —
 * "here are the head-to-head pages, go read the one that applies to
 * you" — for a page (the homepage) that isn't itself a comparison page. */
.gf-compare-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
    max-width: 1000px;
    margin: 0 auto;
}
@media (min-width: 700px) {
    .gf-compare-grid { grid-template-columns: repeat(3, 1fr); }
}
.gf-compare-card {
    display: block;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 28px 24px;
    text-decoration: none !important;
    transition: transform .15s, box-shadow .15s;
}
.gf-compare-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.1); }
.gf-compare-card h3 { font-size: 17px; font-weight: 700; color: #1a202c; margin: 0 0 8px; }
.gf-compare-card p { font-size: 14px; color: #718096; line-height: 1.6; margin: 0 0 16px; }
.gf-compare-card__link { font-size: 14px; font-weight: 700; color: #99cc33; }

/* === LOGO STRIP ===
 * The homepage's "who trusts this" bar — a row of real customer
 * logos above a single pull-quote. Logos are dimmed to --opacity and
 * desaturated so mismatched source-logo colors don't compete with each
 * other; hovering a single logo restores it, a small affordance that
 * costs nothing and signals the row is real logos, not a decorative
 * image. */
.gf-logo-strip__label {
    text-align: center;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #a0aec0;
    margin: 0 0 28px;
}
.gf-logo-strip__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 36px 48px;
    max-width: 1000px;
    margin: 0 auto 48px;
}
.gf-logo-strip__row img {
    height: 32px;
    width: auto;
    max-width: 140px;
    object-fit: contain;
    filter: grayscale(100%);
    opacity: 0.55;
    transition: opacity .15s, filter .15s;
}
.gf-logo-strip__row img:hover { opacity: 1; filter: grayscale(0%); }
.gf-logo-strip__quote {
    max-width: 700px;
    margin: 0 auto;
    text-align: center;
}
.gf-logo-strip__quote blockquote {
    font-size: 18px;
    font-style: italic;
    color: #4a5568;
    line-height: 1.7;
    margin: 0 0 14px;
}
.gf-logo-strip__quote cite {
    font-size: 14px;
    font-style: normal;
    font-weight: 700;
    color: #1a202c;
    display: block;
}
.gf-logo-strip__quote small {
    display: block;
    font-size: 12px;
    color: #a0aec0;
    margin-top: 4px;
}

/* === QUOTE / TESTIMONIAL CARDS ===
 * Replaces the Bootstrap-carousel-dependent `.gf-carousel`/`.gf-thumbnail`
 * pattern with a static responsive grid — no JS/carousel-plugin
 * dependency, same content, works everywhere. */
.gf-quote-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
}
@media (min-width: 600px) {
    .gf-quote-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
    .gf-quote-grid { grid-template-columns: repeat(3, 1fr); }
}
/* --2: pins at 2 columns instead of upgrading to 3 at 1024px — for a grid
 * that will only ever hold 2 quotes, where the default 3-column upgrade
 * leaves them left-aligned with an empty third slot instead of centered.
 * First used on the /about/ rebuild's 2-testimonial section. */
.gf-quote-grid--2 { grid-template-columns: 1fr; }
@media (min-width: 600px) {
    .gf-quote-grid--2 { grid-template-columns: repeat(2, 1fr); }
}
.gf-quote-card {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-left: 4px solid #99cc33;
    border-radius: 8px;
    padding: 20px 22px;
}
.gf-quote-card p {
    font-size: 14px;
    color: #2d3748;
    line-height: 1.6;
    margin: 0 0 12px;
}
.gf-quote-card footer {
    font-size: 12px;
    color: #a0aec0;
}
.gf-quote-card footer a { color: #718096; }

/* === VIDEO + TESTIMONIAL === */
.gf-video-testimonial { max-width: 800px; margin: 0 auto; }
.gf-video-testimonial__frame {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 8px 30px rgba(0,0,0,0.12);
}
.gf-video-testimonial__frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}
.gf-video-testimonial__quote {
    max-width: 700px;
    margin: 32px auto 0;
    text-align: center;
    padding: 28px 24px;
    background: #f7fafc;
    border-radius: 12px;
    border-left: 4px solid #99cc33;
}
.gf-video-testimonial__quote blockquote {
    font-size: 17px;
    font-style: italic;
    color: #4a5568;
    line-height: 1.7;
    margin: 0 0 14px;
}
.gf-video-testimonial__quote cite {
    font-size: 14px;
    font-style: normal;
    font-weight: 700;
    color: #1a202c;
}
@media (min-width: 768px) {
    .gf-video-testimonial__quote { margin-top: 40px; padding: 32px; }
    .gf-video-testimonial__quote blockquote { font-size: 18px; }
}

/* === PRICING CARDS === */
.gf-pricing-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
    max-width: 1000px;
    margin: 0 auto;
}
@media (min-width: 900px) {
    .gf-pricing-grid { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}
.gf-pricing-grid__header {
    display: none;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #718096;
    text-align: center;
}
@media (min-width: 900px) {
    .gf-pricing-grid__header { display: block; }
}
.gf-pricing-card {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    padding: 28px 24px;
    display: flex;
    flex-direction: column;
}
.gf-pricing-card--highlight {
    border-color: #99cc33;
    box-shadow: 0 4px 20px rgba(153,204,51,0.15);
}
.gf-pricing-card h3 { font-size: 22px; font-weight: 800; color: #1a202c; margin: 0 0 16px; }
.gf-pricing-card__starts { font-size: 14px; font-weight: 400; color: #718096; }
.gf-pricing-card__unit { font-size: 14px; font-weight: 400; color: #718096; }
.gf-pricing-card__details {
    font-size: 14px;
    color: #4a5568;
    line-height: 1.8;
    margin: 0 0 16px;
}
.gf-pricing-card__desc {
    font-size: 14px;
    color: #718096;
    line-height: 1.6;
    margin: 0 0 24px;
    flex-grow: 1;
}
.gf-pricing-card__footer { margin-top: auto; }
.gf-pricing-note {
    text-align: center;
    font-size: 14px;
    color: #718096;
    margin-top: 32px;
}

/* === BADGE ===
 * Small inline status/label element (found on support.html) — one
 * component, no responsive behavior needed. */
.gf-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 3px 10px;
    border-radius: 100px;
    background: #f2f9e6;
    color: #99cc33;
}
.gf-badge--dark { background: rgba(153,204,51,0.1); color: #99cc33; }

/* === CLOSING CTA === */
.gf-cta-section {
    background: #1a1f35;
    padding: 48px 20px;
    text-align: center;
    border-top: 1px solid rgba(255,255,255,0.05);
}
.gf-cta-section__inner { max-width: 600px; margin: 0 auto; }
.gf-cta-section__inner h2 {
    font-size: 26px;
    font-weight: 800;
    color: #fff;
    letter-spacing: -0.02em;
    margin: 0 0 16px;
    line-height: 1.2;
}
.gf-cta-section__inner p { font-size: 16px; color: #a0aec0; margin: 0 0 28px; line-height: 1.6; }
.gf-cta-section__buttons { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
@media (min-width: 768px) {
    .gf-cta-section { padding: 40px 40px 56px; }
    .gf-cta-section__inner h2 { font-size: 36px; }
    .gf-cta-section__inner p { font-size: 18px; margin: 0 0 36px; }
}

/* === MOBILE FULL-BLEED ===
 * The theme's `.home` wrapper (header.php) applies a percentage-based
 * side margin that insets everything inside it, including our full-width
 * section backgrounds — visible as unwanted white gutters on small
 * screens. Break these sections out to true full viewport width,
 * anchored to the viewport rather than the parent, so the fix holds
 * regardless of how `.home`'s inset is implemented. Desktop layout is
 * untouched — this only applies below the tablet breakpoint. */
@media (max-width: 767px) {
    .gf-whats-new,
    .gf-hero,
    .gf-section,
    .gf-mcp-section,
    .gf-faq-section,
    .gf-cta-section {
        width: 100vw;
        position: relative;
        left: 50%;
        margin-left: -50vw;
    }
}

/* === SCREENSHOT + FEATURE TEXT (two-column, alternating) ===
 * Pairs a real product screenshot with supporting copy. Same responsive
 * shape as .gf-mcp-demo (1 column mobile, 1fr 1fr desktop) — deliberately
 * reused rather than a new grid pattern. --reverse flips which side the
 * image sits on, for visual rhythm across repeated sections on one page.
 * Uses the existing .gf-checklist for feature bullets rather than a new
 * list style. First used on the AI product page. */
.gf-shot-feature {
    display: grid;
    grid-template-columns: 1fr;
    gap: 28px;
    align-items: center;
    margin-bottom: 48px;
}
.gf-shot-feature:last-child { margin-bottom: 0; }
.gf-shot-feature__frame {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    padding: 8px;
    box-shadow: 0 8px 30px rgba(0,0,0,0.10);
}
.gf-shot-feature__frame img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 7px;
}
.gf-shot-feature__caption {
    margin: 10px 4px 0;
    font-size: 13px;
    color: #718096;
    text-align: center;
}
.gf-shot-feature__text h3 {
    font-size: 22px;
    font-weight: 800;
    color: #1a202c;
    margin: 0 0 12px;
    letter-spacing: -0.01em;
}
.gf-shot-feature__text p {
    font-size: 15px;
    color: #4a5568;
    line-height: 1.7;
    margin: 0 0 16px;
}
@media (min-width: 900px) {
    .gf-shot-feature {
        grid-template-columns: 1fr 1fr;
        gap: 56px;
        margin-bottom: 64px;
    }
    .gf-shot-feature--reverse .gf-shot-feature__media { order: 2; }
    .gf-shot-feature--reverse .gf-shot-feature__text { order: 1; }
    .gf-shot-feature__text h3 { font-size: 26px; }
}

/* === STORY SCROLL (pinned visual, advancing panels) ===
 * First used on the homepage's platform section, replacing what would
 * otherwise be a flat feature-tile grid — a small number of real
 * differentiators, each backed by a real screenshot, feel considered;
 * a dozen generic tiles read as filler. NOT a rename/variant of
 * .gf-mcp-pillar (that's a static 3-card icon grid on the AI page) —
 * this pins a visual via `position: sticky` while panels scroll past
 * it, swapping which image shows via .is-active. Below 900px the pinned
 * visual is dropped entirely rather than attempted at a size too narrow
 * to make the swap-on-scroll effect legible — panels just read as a
 * plain stacked list, still fully informative without the animation.
 * Interaction (which panel is "current", swapping .is-active) lives in
 * gf-nav.js, guarded to no-op on any page without this markup. */
.gf-story-scroll { display: flex; flex-direction: column; gap: 0; max-width: 1100px; margin: 0 auto; }
.gf-story-scroll__panel {
    padding: 32px 0;
    border-top: 1px solid #e2e8f0;
    opacity: 0.45;
    transition: opacity .25s ease;
}
.gf-story-scroll__panel:first-child { border-top: none; }
.gf-story-scroll__panel.is-active { opacity: 1; }
.gf-story-scroll__icon {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: rgba(153,204,51,0.1);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 16px;
}
.gf-story-scroll__icon svg { width: 20px; height: 20px; stroke: #99cc33; fill: none; }
.gf-story-scroll__panel h3 { font-size: 20px; font-weight: 800; color: #1a202c; margin: 0 0 8px; letter-spacing: -0.01em; }
.gf-story-scroll__panel p { font-size: 15px; color: #718096; line-height: 1.65; margin: 0 0 14px; }
.gf-story-scroll__panel a { font-size: 14px; font-weight: 700; color: #99cc33; text-decoration: none; }
.gf-story-scroll__panel a:hover { text-decoration: underline; }
.gf-story-scroll__visual { display: none; }
@media (min-width: 900px) {
    .gf-story-scroll { flex-direction: row; gap: 64px; align-items: flex-start; }
    .gf-story-scroll__panels { flex: 0 0 40%; min-width: 0; }
    .gf-story-scroll__panel { padding: 72px 0; }
    .gf-story-scroll__panel:first-child { padding-top: 0; }
    .gf-story-scroll__panel:last-child { padding-bottom: 0; }
    .gf-story-scroll__visual {
        display: block;
        flex: 1;
        position: sticky;
        /* Centers the image's own vertical middle against the viewport's
         * middle, rather than pinning its top edge near the top of the
         * screen — with a shorter image than the (much taller) panel
         * column, a top-pin just leaves it stranded near the top with
         * dead space below for most of the scroll. */
        top: 50%;
        transform: translateY(-50%);
        align-self: flex-start;
    }
    .gf-story-scroll__visual-frame {
        position: relative;
        aspect-ratio: 16 / 10;
        border-radius: 12px;
        overflow: hidden;
        border: 1px solid #e2e8f0;
        box-shadow: 0 20px 50px rgba(0,0,0,0.15);
        background: #fff;
    }
    .gf-story-scroll__image {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: top;
        opacity: 0;
        transition: opacity .4s ease;
    }
    .gf-story-scroll__image.is-active { opacity: 1; }
}

/* === LIGHTBOX (native <dialog>) ===
 * General-purpose, not tied to .gf-shot-feature — any image with
 * .gf-lightbox-trigger opens full-size here. Extends the same native
 * <dialog>/::backdrop pattern already used by .gf-dialog (the download
 * flow's email-capture modal) rather than introducing a second modal
 * mechanism. Each page that uses .gf-lightbox-trigger images needs
 * exactly one `<dialog id="gf-lightbox" class="gf-lightbox">` on that
 * page (see Kitchen Sink for the markup) — same "modal lives once per
 * page that needs it" precedent as .gf-dialog, not a global site include.
 * Behavior (open/close wiring) lives in gf-nav.js. */
.gf-lightbox {
    /* Deliberately NOT `position: relative` — a modal <dialog> gets
     * `position: fixed`, centered in the viewport, from the browser's own
     * UA stylesheet by default. Overriding it to `relative` (an earlier
     * version of this rule did, to give the close button a positioning
     * context) breaks that entirely: the dialog then renders at its
     * normal document-flow position instead — in this case, wherever the
     * <dialog> markup happens to sit in the page (near the bottom), which
     * is what actually caused the "opening jumps to the top of the page"
     * bug, not a scroll-restore problem. `fixed` is just as valid a
     * containing block for the close button's `position: absolute` as
     * `relative` would be, so nothing else needs to change to keep that
     * working — only remove the override and let the browser's own
     * default apply. */
    border: none;
    border-radius: 12px;
    padding: 0;
    max-width: min(1100px, 92vw);
    max-height: 90vh;
    background: transparent;
    box-shadow: 0 24px 64px rgba(0,0,0,0.4);
}
.gf-lightbox::backdrop { background: rgba(15,20,35,0.85); }
.gf-lightbox__img {
    display: block;
    width: 100%;
    max-height: 90vh;
    object-fit: contain;
    border-radius: 12px;
}
.gf-lightbox__close {
    /* Inset, not floated outside the dialog box (top:-16px/right:-16px) —
     * the dialog can nearly fill the viewport on a narrower window
     * (max-width: 92vw), and a negative offset then pushes the button
     * past the actual screen edge, clipping it. Staying inside the
     * dialog's own box keeps it within whatever bounds the browser
     * already guarantees for a shown <dialog>.
     * Fully opaque, not semi-transparent, and sized up from an earlier
     * 36px: a screenshot can easily have its own real UI chrome (e.g. a
     * close icon) in roughly the same corner, and a small,
     * see-through button risks visually blending with or being mistaken
     * for whatever's in the photo underneath — happened with a real
     * screenshot on the AI page (a captured app modal that had its own
     * "x" almost exactly where this button sits). Solid fill and a
     * bigger, more forgiving hit target make it unambiguous which mark
     * is the actual control, regardless of what any future screenshot
     * happens to show in that corner. */
    position: absolute;
    top: 12px;
    right: 12px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: #0f1423;
    border: none;
    box-shadow: 0 4px 12px rgba(0,0,0,0.35);
    font-size: 22px;
    line-height: 1;
    color: #fff;
    cursor: pointer;
}
.gf-lightbox-trigger { cursor: zoom-in; }

/* === BLOG POST ===
 * Used by template-parts/content-post.php for both the singular article
 * view and the archive/index excerpt card. Typography values match the
 * one-off .gfblog-* styles already used on the Atlassian AI-training post,
 * so default posts and that hand-styled one read as the same publication. */
/* single.php's <main> uses .gf-post-main instead of the legacy Bootstrap
 * `.container` — that container isn't reliably centered in the viewport
 * at every breakpoint (confirmed via live DOM measurement), which was
 * throwing off centering for everything inside it (thumbnail, body,
 * footer), even though those already have their own self-centering
 * max-width/margin:auto rules. A plain full-width parent fixes that.
 * The small side padding here is just a minimum gutter for raw core WP
 * markup that isn't one of our own gf-post-* components and so has no
 * padding of its own (comments, post-navigation prev/next links) — the
 * gf-post-* elements already pad themselves and are unaffected. Scoped
 * to this one class (not the shared #primary ID, which archive.php/
 * index.php/page.php/search.php/404.php also use) so nothing else is
 * affected. */
.gf-post-main {
    padding-left: 20px;
    padding-right: 20px;
    box-sizing: border-box;
}

/* Full-bleed dark hero, matching .gf-hero used sitewide on product/
 * alternative pages. Rendered by single.php as a direct child of the
 * page wrapper, outside the legacy Bootstrap `.container` (untouched
 * pre-redesign leftover) that constrains the rest of the post — that
 * container isn't reliably centered in the viewport at every breakpoint,
 * which breaks the standard 100vw-breakout CSS trick when nested inside
 * it. Being a direct child of the full-width wrapper instead means a
 * plain 100% width is correct with no breakout math needed at all. */
.gf-post-header {
    background: #1a1f35;
    width: 100%;
    padding: 64px 20px 40px;
    text-align: center;
}
.gf-post-header__inner {
    max-width: 760px;
    margin: 0 auto;
}
.gf-post-header__title {
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.2;
    color: #fff;
    margin: 14px 0 16px;
}
.gf-post-meta {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: #718096;
}
.gf-post-meta__dot { width: 3px; height: 3px; border-radius: 50%; background: #cbd5e0; flex: 0 0 auto; }

.gf-post-thumbnail { max-width: 900px; margin: 0 auto 40px; padding: 0 20px; }
.gf-post-thumbnail__frame { border-radius: 12px; overflow: hidden; box-shadow: 0 8px 30px rgba(0,0,0,0.08); }
.gf-post-thumbnail__frame img { display: block; width: 100%; height: auto; }

/* Only DIRECT children get the narrow reading-column treatment (max-width
 * + auto-centering). A post that embeds its own full-bleed section markup
 * (rare — e.g. a hand-built landing-page-style post) isn't a direct-child
 * <p>/<h2>/etc., so it's left alone to manage its own width. */
.gf-post-body { padding: 0 20px 56px; }
.gf-post-body > p { max-width: 700px; margin: 0 auto 20px; font-size: 16px; line-height: 1.75; color: #4a5568; }
.gf-post-body > h2 { max-width: 700px; margin: 40px auto 16px; font-size: 26px; font-weight: 800; letter-spacing: -0.01em; color: #1a202c; line-height: 1.25; }
.gf-post-body > h3 { max-width: 700px; margin: 32px auto 8px; font-size: 19px; font-weight: 700; color: #1a202c; }
.gf-post-body > ul, .gf-post-body > ol { max-width: 700px; margin: 0 auto 20px; padding-left: 22px; color: #4a5568; font-size: 16px; line-height: 1.75; }
.gf-post-body li { margin-bottom: 8px; }
.gf-post-body a { color: #7ab32a; font-weight: 600; text-decoration: none; }
.gf-post-body a:hover { text-decoration: underline; }
.gf-post-body strong { color: #2d3748; }
.gf-post-body > blockquote { max-width: 700px; margin: 28px auto; padding: 4px 0 4px 20px; border-left: 3px solid #99cc33; color: #2d3748; font-size: 17px; font-style: italic; }
.gf-post-body img { max-width: 100%; height: auto; }
.gf-post-body > img { max-width: 700px; display: block; margin: 8px auto; border-radius: 10px; }
.gf-post-body > figure { max-width: 700px; margin: 32px auto; text-align: center; }
.gf-post-body figcaption { font-size: 13px; color: #a0aec0; margin-top: 10px; }

.gf-post-footer {
    max-width: 760px;
    padding: 24px 20px 56px;
    border-top: 1px solid #e2e8f0;
    font-size: 13px;
    color: #a0aec0;
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}
.gf-post-footer a { color: #718096; }
/* Overrides a `.entry-footer > :first-child { border-top; padding-top }`
 * rule living in the Customizer's "Additional CSS" (not this repo) — it
 * was meant to divider-off whatever the first line of the footer was
 * (originally the now-removed "Posted in [category]" text). Now that
 * category is gone, .edit-link (admin-only — edit_post_link() only
 * renders for users who can edit) becomes the new first-child and
 * inherits a divider it was never meant to have. That Customizer rule
 * has the same CSS specificity as a plain `.gf-post-footer .edit-link`
 * override, and wins on cascade order (loaded after theme CSS), so this
 * chains all three of the footer's own classes to specificity-beat it
 * outright rather than reaching for `!important`. Scoped narrowly here,
 * not a change to the global rule, since that also styles page
 * edit-links elsewhere on the site. */
.entry-footer.gf-post-footer.gf-narrow .edit-link { border-top: none; padding-top: 0; margin-top: 0; }

/* Archive / index excerpt card */
.gf-post-card {
    display: flex;
    flex-direction: column;
    gap: 20px;
    max-width: 800px;
    margin: 0 auto;
    padding: 40px 20px;
    border-bottom: 1px solid #e2e8f0;
}
.gf-post-card:first-child { padding-top: 0; }
.gf-post-card__media { display: block; border-radius: 12px; overflow: hidden; }
.gf-post-card__media img { display: block; width: 100%; height: auto; }
.gf-post-card__title { font-size: 22px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.3; margin: 10px 0 8px; }
.gf-post-card__title a { color: #1a202c; text-decoration: none; }
.gf-post-card__title a:hover { color: #7ab32a; }
.gf-post-meta--sm { justify-content: flex-start; }
.gf-post-card__excerpt { font-size: 15px; line-height: 1.7; color: #4a5568; margin: 8px 0 12px; }
.gf-post-card__link { font-size: 14px; font-weight: 700; color: #7ab32a; text-decoration: none; }
.gf-post-card__link:hover { text-decoration: underline; }

@media (min-width: 640px) {
    .gf-post-card { flex-direction: row; align-items: flex-start; }
    .gf-post-card__media { flex: 0 0 240px; }
    .gf-post-card__body { flex: 1; min-width: 0; }
}

/* === CONTACT PAGE ===
 * /contact/'s form + company-info split. The two-column layout is new
 * (nothing else on the site pairs a Jetpack form with a sidebar card),
 * but everything inside each column reuses existing components —
 * .gf-hero, .gf-section, .gf-feature-card, .gf-link-plain — rather than
 * the page's previous one-off embedded <style> block. */
.gf-contact-layout {
    display: grid;
    gap: 36px;
    max-width: 1000px;
    margin: 0 auto;
}
@media (min-width: 768px) {
    .gf-contact-layout { grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; }
}
.gf-contact-form-area h2 { font-size: 26px; font-weight: 800; color: #1a202c; margin: 0 0 8px; }
.gf-contact-form-area > p { font-size: 15px; color: #718096; margin: 0 0 24px; }

.gf-contact-info { background: #1a1f35; border-radius: 12px; padding: 32px 28px; color: #fff; }
.gf-contact-info h3 { font-size: 20px; font-weight: 700; color: #fff; margin: 0 0 20px; }
.gf-contact-info__item { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 20px; }
.gf-contact-info__item:last-of-type { margin-bottom: 0; }
.gf-contact-info__item svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: 2px; stroke: #99cc33; fill: none; stroke-width: 2; }
.gf-contact-info__label { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.6); margin-bottom: 4px; }
.gf-contact-info__value { font-size: 15px; line-height: 1.6; color: #e2e8f0; }
.gf-contact-info__value a { color: #99cc33; text-decoration: none; }
.gf-contact-info__value a:hover { text-decoration: underline; }
.gf-contact-info__social { display: flex; gap: 12px; margin-top: 24px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,0.15); }
.gf-contact-info__social a { width: 40px; height: 40px; background: rgba(255,255,255,0.08); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #fff; transition: background 0.2s; }
.gf-contact-info__social a:hover { background: #99cc33; }

/* === SUPPORT PAGE ===
 * First used on /support/. */
/* .gf-hero__note: small icon+text highlight line under a centered hero's
 * lead paragraph — a fact worth calling out but not substantial enough
 * for a full .gf-callout (which also assumes a light background; this
 * is for use directly on a dark .gf-hero). */
.gf-hero__note {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-top: 24px;
    padding: 10px 18px;
    background: rgba(153,204,51,0.08);
    border: 1px solid rgba(153,204,51,0.25);
    border-radius: 100px;
    font-size: 14px;
    color: #cbd5e0;
}
.gf-hero__note svg { width: 18px; height: 18px; flex-shrink: 0; stroke: #99cc33; fill: none; stroke-width: 2; }

/* .gf-feature-card--dark: for a .gf-feature-card grid sitting on a dark
 * section (e.g. .gf-mcp-section) instead of the default light one. */
.gf-feature-card--dark { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.1); }
.gf-feature-card--dark h3 { color: #fff; }
.gf-feature-card--dark p { color: #a0aec0; }

/* === FAQ PAGE ===
 * First used on /products/faq/. */
/* .gf-faq-section__category: a category subheading inserted as a direct
 * child of .gf-faq-section__list, for a long FAQ page grouped into
 * several topics (General, Pricing, Deployment...) rather than one flat
 * list — the list's existing flex/gap layout treats it as just another
 * child, so this only needs its own type styling. */
.gf-faq-section__category {
    font-size: 20px;
    font-weight: 800;
    color: #1a202c;
    margin: 28px 0 0;
    padding-bottom: 10px;
    border-bottom: 2px solid #99cc33;
}
.gf-faq-section__category:first-child { margin-top: 0; }

/* .gf-jump-nav: pill links to jump to a category further down the same
 * page — same light-tag visual language as .gf-section__tag, but a real
 * clickable link with a hover state. */
.gf-jump-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    max-width: 700px;
    margin: 32px auto;
    padding: 0 20px;
}
.gf-jump-nav a {
    display: inline-block;
    padding: 8px 18px;
    background: #f2f9e6;
    color: #5f8a1f;
    font-size: 14px;
    font-weight: 700;
    border-radius: 100px;
    text-decoration: none;
    transition: background 0.15s;
}
.gf-jump-nav a:hover { background: #e2f0c8; }

/* === FOOTER ===
 * Replaces the legacy Bootstrap grid (.container-fluid/.row/.col-sm-*)
 * and .section--darker (a pre-redesign light-gray leftover, #cad1da,
 * used nowhere else in the theme) previously used in footer.php. Same
 * dark navy (#1a1f35) as .gf-hero and .gf-cta-section, for visual
 * consistency across every dark section on the site. 3 columns: the
 * footer-1 ("GForge") and footer-3 ("Quick Links") nav menu locations,
 * plus a fixed brand column. footer-2 ("Compare Us With...") is
 * deliberately not rendered here — its one remaining link duplicated
 * the header's own "Compare" dropdown link with no unique content of
 * its own; the menu itself still exists in wp-admin, just unrendered. */
.gf-footer {
    background: #1a1f35;
    padding: 56px 20px 40px;
}
.gf-footer__inner {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr;
    gap: 40px;
}
@media (min-width: 768px) {
    .gf-footer__inner { grid-template-columns: repeat(3, 1fr); gap: 32px; }
}
.gf-footer__heading {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #fff;
    margin: 0 0 18px;
}
.gf-footer__links { list-style: none; margin: 0; padding: 0; }
.gf-footer__links li { margin-bottom: 10px; }
.gf-footer__links li:last-child { margin-bottom: 0; }
.gf-footer__links a {
    color: #a0aec0;
    text-decoration: none;
    font-size: 14px;
    transition: color 0.15s;
}
.gf-footer__links a:hover { color: #99cc33; }

.gf-footer__logo { display: inline-block; margin-bottom: 18px; }
.gf-footer__logo svg { width: 160px; height: auto; display: block; }
.gf-footer__copyright { font-size: 13px; color: #718096; margin: 0 0 6px; }
.gf-footer__legal { font-size: 13px; margin: 0 0 20px; }
.gf-footer__legal a { color: #a0aec0; text-decoration: none; transition: color 0.15s; }
.gf-footer__legal a:hover { color: #99cc33; }
.gf-footer__social { display: flex; gap: 10px; list-style: none; margin: 0; padding: 0; }
.gf-footer__social a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 8px;
    background: rgba(255,255,255,0.06);
    transition: background 0.15s;
}
.gf-footer__social a:hover { background: #99cc33; }
.gf-footer__social svg { width: 17px; height: 17px; stroke: #a0aec0; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: stroke 0.15s; }
.gf-footer__social a:hover svg { stroke: #1a1f35; }

/* === STATS ROW ===
 * A lightweight horizontal row of year/label pairs — for quantifying
 * company history (founding year, ownership milestones) without a full
 * illustrated timeline component. First used on the /about/ rebuild. */
.gf-stats-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
    max-width: 800px;
    margin: 40px auto 0;
    text-align: center;
}
@media (min-width: 600px) {
    .gf-stats-row { grid-template-columns: repeat(3, 1fr); }
}
.gf-stat__number { font-size: 32px; font-weight: 800; color: #99cc33; line-height: 1; }
.gf-stat__label { font-size: 14px; color: #718096; margin-top: 8px; }

/* === TEAM ===
 * Founder/team profile: fixed-width photo column + flexible bio column
 * (asymmetric, unlike .gf-shot-feature's 50/50 split, which is sized for
 * product screenshots rather than a portrait + credential list). First
 * used on the /about/ rebuild. */
.gf-team {
    display: grid;
    grid-template-columns: 1fr;
    gap: 32px;
    max-width: 900px;
    margin: 0 auto;
    align-items: start;
}
@media (min-width: 700px) {
    .gf-team { grid-template-columns: 240px 1fr; gap: 40px; }
}
.gf-team__photo { width: 100%; border-radius: 12px; display: block; }
.gf-team__caption { font-size: 13px; color: #718096; margin-top: 12px; text-align: center; }
.gf-team__name { font-size: 24px; font-weight: 800; color: #1a202c; margin: 0 0 4px; }
.gf-team__title { color: #718096; margin: 0 0 16px; }
.gf-team__bio { color: #4a5568; line-height: 1.7; margin-bottom: 20px; }
.gf-team__credentials {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
    margin-bottom: 20px;
}
@media (min-width: 480px) {
    .gf-team__credentials { grid-template-columns: 1fr 1fr; }
}
.gf-team__credential {
    background: #f7fafc;
    padding: 14px;
    border-radius: 6px;
    border-left: 3px solid #99cc33;
}
.gf-team__credential strong { display: block; font-size: 14px; color: #1a202c; margin-bottom: 4px; }
.gf-team__credential span { font-size: 13px; color: #4a5568; }
.gf-team__more summary {
    cursor: pointer;
    color: #5a8a1e;
    font-weight: 700;
    font-size: 14px;
    list-style: none;
}
.gf-team__more summary::-webkit-details-marker { display: none; }
.gf-team__more[open] summary { margin-bottom: 12px; }
.gf-team__more p { color: #4a5568; line-height: 1.7; margin-bottom: 12px; }
