/*
 * Netbase UI layer: owner requests of David (CEO), 2026-09-15.
 * Seeded by ThemeStyleSeeder into the theme Custom CSS file; edit here, not in the admin.
 * Exceptions X11-X18 in docs/operations/m1-ui-exceptions-2026-09-14.md.
 * X19-X21 are recorded in the same file; X21 tokens: docs/design/netbase-design-tokens.md.
 * X22 (designed Why Netbase blocks, same token rule) follows X21 at the end of this file.
 */

/* X11 Header dropdowns: one line per item; the panel is as wide as its longest label. */
.navbar .navbar-nav .dropdown-menu {
    min-width: max-content;
}

.navbar .navbar-nav .dropdown-menu .nav-link {
    white-space: nowrap;
}

/* X12 Directory cards: card-wide thumbnail from the approved entry image and a larger title. */
.shortcode-services-style-2 .service-thumbnail {
    aspect-ratio: 16 / 10;
    object-fit: cover;
}

.shortcode-services-style-2 .feature-item strong.fs-6 {
    font-size: 1.25rem !important;
    line-height: 1.35;
    margin-bottom: 0.5rem;
}

/* X13 Business Division tabs: a logo per tab; the tab column is as tall as the panel. */
.shortcode-feature-tabs .feature-tab-logo {
    width: 4.5rem;
    height: 4.5rem;
    padding: 0.25rem;
    box-shadow: var(--tc-shadow-1);
}

.shortcode-feature-tabs .feature-tab-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.shortcode-feature-tabs .nav-pills .nav-link {
    padding-left: 1.5rem;
    font-size: 1.125rem;
}

@media (min-width: 992px) {
    .shortcode-feature-tabs .col-lg-4 > .d-flex,
    .shortcode-feature-tabs .col-lg-4 .nav-pills {
        height: 100%;
    }

    .shortcode-feature-tabs .nav-pills .nav-link {
        flex: 1 1 0;
    }

    .shortcode-feature-tabs .nav-pills .nav-link:last-child {
        margin-bottom: 0;
    }
}

/* X14 Logo and badge grids: centred rows; seven badges sit three over four. */
.shortcode-support-tools .row {
    justify-content: center;
}

.shortcode-support-tools img {
    max-width: 100%;
    height: auto;
}

/* Equal card heights per row; the image is centred in its card. */
.shortcode-support-tools .row > div {
    display: flex;
}

.shortcode-support-tools .row > div > .border {
    flex: 1 1 auto;
    display: flex;
}

.shortcode-support-tools .row > div > .border > div {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

@media (min-width: 992px) {
    .shortcode-support-tools .row:has(> :nth-child(7):last-child) > :nth-child(n + 4) {
        flex: 0 0 25%;
        max-width: 25%;
    }
}

/* X15 Work case-study cards: a visible card edge and shadow, equal image frames and heights. */
.shortcode-blog-posts-style-2 .swiper {
    padding: 0.75rem 0.75rem 2rem;
}

.shortcode-blog-posts-style-2 .swiper-slide {
    height: auto;
}

.shortcode-blog-posts-style-2 .swiper-slide > .card {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border: 1px solid var(--tc-neutral-200) !important;
    box-shadow: 0 0.75rem 2rem rgba(17, 24, 39, 0.1);
}

.shortcode-blog-posts-style-2 .swiper-slide > .card > img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    object-position: top center;
}

.shortcode-blog-posts-style-2 .swiper-slide > .card > .card-body {
    flex: 1 1 auto;
}

/*
 * X16 Detail header: the approved entry image behind the single H1, under a light wash
 * (dark text). Scoped to a style-3 hero that carries a background image, which only
 * netbase-content detail routes set, so directories and every other page are unchanged.
 * Wash stops keep >= 4.5:1 for #111827 text over any pixel under the text column
 * (col-lg-7 ends at <= 58.4% of the viewport; tests/test_detail_templates.py checks it).
 */
.shortcode-hero-banner-style-3[style*="background-image"] {
    min-height: 34rem;
    display: flex;
    align-items: center;
    background-position: center;
    background-repeat: no-repeat;
}

.shortcode-hero-banner-style-3[style*="background-image"]::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 55%, rgba(255, 255, 255, 0.2) 85%);
}

[data-bs-theme="dark"] .shortcode-hero-banner-style-3[style*="background-image"]::before {
    background: linear-gradient(90deg, rgba(28, 27, 31, 0.95) 0%, rgba(28, 27, 31, 0.9) 55%, rgba(28, 27, 31, 0.3) 85%);
}

.shortcode-hero-banner-style-3[style*="background-image"] > .container {
    position: relative;
    z-index: 1;
    width: 100%;
}

.shortcode-hero-banner-style-3[style*="background-image"] .rotateme,
.shortcode-hero-banner-style-3[style*="background-image"] .ellipse-primary {
    display: none;
}

.shortcode-hero-banner-style-3[style*="background-image"] h1.ds-1 {
    font-size: clamp(2.25rem, 1.5rem + 2.4vw, 3.75rem);
    line-height: 1.1;
}

@media (max-width: 991.98px) {
    .shortcode-hero-banner-style-3[style*="background-image"]::before {
        background: rgba(255, 255, 255, 0.9);
    }

    [data-bs-theme="dark"] .shortcode-hero-banner-style-3[style*="background-image"]::before {
        background: rgba(28, 27, 31, 0.9);
    }
}

/* X17 Tech-stack logo cloud (partners style 3): taller tiles; white tiles and brand colours in both themes. */
.shortcode-partners-style-3 .partner-item {
    max-height: none;
    height: 5rem;
}

.shortcode-partners-style-3 .partner-item img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 3rem;
}

[data-bs-theme=dark] .shortcode-partners-style-3 .partner-item {
    background-color: #fff !important;
}

[data-bs-theme=dark] .shortcode-partners-style-3 .partner-item img.filter-invert {
    filter: none;
}

/*
 * X18 Home 5 violet residue: colours Infinia hard-codes outside its theme options follow
 * the navy tokens (X06) in light and dark mode. Theme files are unchanged; inline SVG
 * stroke/fill attributes are matched by value, since CSS properties beat presentation
 * attributes. The breadcrumb band's second blob took the X06 red, which the violet glass
 * turned into a pink (light) or plum (dark) band, worst on mobile: it is navy-blue now.
 */
:root {
    --tc-bg-dark-2: var(--primary-color-dark-soft);
}

:root:not([data-bs-theme="dark"]) {
    --tc-bg-1: color-mix(in srgb, var(--primary-color) 5%, #fff);
}

.bg-primary-soft-keep {
    background-color: color-mix(in srgb, var(--primary-color) 8%, #fff);
}

.alert-primary {
    --bs-alert-bg: rgba(var(--primary-color-rgb), 0.2);
}

[data-bs-theme="dark"] .alert-primary {
    --bs-alert-bg: rgba(var(--primary-color-dark-rgb), 0.2);
}

.border-gradient {
    border-image-source: var(--primary-gradient-bg) !important;
}

.text-gradient {
    background: var(--primary-gradient-bg);
    -webkit-background-clip: text;
    background-clip: text;
}

[data-bs-theme="light"] .shortcode-site-statistics-style-2 {
    --shortcode-background-color: var(--primary-color);
}

[data-bs-theme="light"] .shortcode-platforms-featured {
    --shortcode-background-color: var(--tc-bg-2);
}

[data-bs-theme="light"] .widget-newsletter-style-2[style*="#6d4df2" i] {
    background-color: var(--primary-color) !important;
}

.section-hero-2 .bouncing-blobs-glass,
.section-page-header .bouncing-blobs-glass {
    background-color: rgba(var(--primary-color-rgb), 0.04);
}

.section-page-header .bouncing-blob--green {
    background: var(--primary-color-dark-light) !important;
}

[data-bs-theme="dark"] .section-page-header .bouncing-blob--green {
    background: var(--primary-color-dark-soft) !important;
}

svg [stroke="#6D4DF2" i],
svg [stroke="#6342EC" i] {
    stroke: var(--tc-theme-primary);
}

svg [fill="#6D4DF2" i] {
    fill: var(--tc-theme-primary);
}

svg [fill="#A38CFF" i] {
    fill: var(--primary-color-dark-light);
}

/*
 * X19 round-12 polish (staging 3cb185a review, 2026-09-16). Overrides only; X11-X18 stay as recorded.
 * Detail header wash: lighter, so the right side shows the (1920x720) header photo; under the
 * text column (<= 60% of the viewport) it stays >= 0.52 (light) / >= 0.72 (dark) opaque, which keeps
 * 4.5:1 over any pixel (tests/test_ui_polish.py). Below 992 px the flat wash is re-declared here,
 * since these gradients come after the X16 media query.
 */
.shortcode-hero-banner-style-3[style*="background-image"]::before {
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.92) 0%, rgba(255, 255, 255, 0.85) 45%, rgba(255, 255, 255, 0.62) 60%, rgba(255, 255, 255, 0) 82%);
}

[data-bs-theme="dark"] .shortcode-hero-banner-style-3[style*="background-image"]::before {
    background: linear-gradient(90deg, rgba(28, 27, 31, 0.94) 0%, rgba(28, 27, 31, 0.88) 45%, rgba(28, 27, 31, 0.76) 60%, rgba(28, 27, 31, 0) 85%);
}

/*
 * Detail H1: long words wrap instead of running past the right edge; smaller on phones. The theme sets
 * `.ds-1 { font-size: var(--tc-ds-1) !important }` (var(--tc-ds-3), 64px, below 768 px), which beats the X16
 * font-size, so X19 sets those variables on the H1 instead.
 */
.shortcode-hero-banner-style-3[style*="background-image"] h1.ds-1 {
    overflow-wrap: break-word;
}

@media (max-width: 991.98px) {
    .shortcode-hero-banner-style-3[style*="background-image"]::before {
        background: rgba(255, 255, 255, 0.82);
    }

    [data-bs-theme="dark"] .shortcode-hero-banner-style-3[style*="background-image"]::before {
        background: rgba(28, 27, 31, 0.86);
    }
}

@media (max-width: 575.98px) {
    .shortcode-hero-banner-style-3[style*="background-image"] h1.ds-1 {
        --tc-ds-1: clamp(1.75rem, 1rem + 4.5vw, 2.5rem);
        --tc-ds-3: clamp(1.75rem, 1rem + 4.5vw, 2.5rem);
    }
}

/* Gradient buttons (header "Let's talk"): white text in dark mode too; the theme's dark text fails on the navy end. */
[data-bs-theme="dark"] .btn-gradient,
[data-bs-theme="dark"] .btn-gradient:hover,
[data-bs-theme="dark"] .btn-gradient:focus {
    color: #fff;
}

/* Insights table of contents ({toc}, h2#nb-toc + ul): a compact linked panel, two columns from 768 px. */
#nb-toc + ul {
    list-style: none;
    display: grid;
    gap: 0.125rem 2rem;
    margin: 0 0 2.5rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--tc-neutral-200);
    border-left: 3px solid var(--tc-theme-primary);
    border-radius: 0.75rem;
    counter-reset: nb-toc;
}

#nb-toc + ul > li {
    margin: 0;
    padding: 0;
    counter-increment: nb-toc;
}

#nb-toc + ul > li::marker {
    content: none;
}

#nb-toc + ul a {
    display: flex;
    gap: 0.625rem;
    padding: 0.375rem 0;
    color: var(--tc-theme-primary);
    font-weight: 500;
    line-height: 1.35;
    text-decoration: none;
}

#nb-toc + ul a::before {
    content: counter(nb-toc, decimal-leading-zero);
    flex: 0 0 auto;
    min-width: 1.5rem;
    opacity: 0.6;
    font-variant-numeric: tabular-nums;
}

#nb-toc + ul a:hover,
#nb-toc + ul a:focus-visible {
    text-decoration: underline;
}

@media (min-width: 768px) {
    #nb-toc + ul {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Detail key stats (#nb-stats, site-statistics 3): the number never breaks; a unit is set smaller and may drop below it. */
#nb-stats .count {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: baseline;
    column-gap: 0.2em;
    line-height: 1.1;
}

#nb-stats .count > .odometer {
    white-space: nowrap;
}

#nb-stats .count > span:not(.odometer) {
    font-size: 0.5em;
    white-space: nowrap;
}

/*
 * X20 round-13 polish (staging b00844f review, 2026-09-16). Overrides only; X11-X19 stay as recorded.
 * Detail H1 from 576 px: the theme's `.ds-1 { font-size: var(--tc-ds-1) !important }` kept it at 80 px
 * (4-6 lines at 1440 px), so X20 sets the variables X19 sets below 576 px: 40 px up to ~830 px, 52.8 px at
 * 1440 px, 56 px (3.5rem) from 1600 px; balanced lines. The X19 phone size still applies below 576 px.
 * From 992 px the image hero drops the theme's 120 px section padding, 34rem floor and its larger spacing
 * utilities (Bootstrap spacing utilities are !important, hence the three scoped !important), so the first
 * section starts within ~900 px at 1440 px. Nothing is clipped: no max-height. The wash is unchanged.
 */
@media (min-width: 576px) {
    .shortcode-hero-banner-style-3[style*="background-image"] h1.ds-1 {
        --tc-ds-1: clamp(2.5rem, 1.5rem + 2vw, 3.5rem);
        --tc-ds-3: clamp(2.5rem, 1.5rem + 2vw, 3.5rem);
    }
}

.shortcode-hero-banner-style-3[style*="background-image"] h1.ds-1 {
    text-wrap: balance;
}

@media (min-width: 992px) {
    .shortcode-hero-banner-style-3[style*="background-image"] {
        min-height: 0;
        padding-block: 3rem 0;
    }

    .shortcode-hero-banner-style-3[style*="background-image"] .col-lg-7.pb-10 {
        padding-bottom: 3rem !important;
    }

    .shortcode-hero-banner-style-3[style*="background-image"] .col-lg-7 p.my-6 {
        margin-block: 1.5rem !important;
    }

    .shortcode-hero-banner-style-3[style*="background-image"] .col-lg-7 .mt-6 {
        margin-top: 1.5rem !important;
    }
}

/*
 * Homepage testimonials (style 4): a card without an avatar shows no image. The seeder stores no image for
 * those records (StagingStabilizationSeeder::netbaseTestimonials()), and RvMedia::image() then prints Botble's
 * default placeholder (config core/media default_image, placeholder.png), which is hidden here; the name
 * column moves back to the card edge.
 */
.shortcode-testimonials-style-4 .card-testimonial-3 img[src$="/placeholder.png"] {
    display: none;
}

.shortcode-testimonials-style-4 .card-testimonial-3 img[src$="/placeholder.png"] + .d-flex {
    margin-left: -1rem;
}

/*
 * X20 addendum: detail hero byline (staging d820743 review, 2026-09-16). Overrides only.
 * The byline (`bottom_title`, ContentFamilyRenderer::byline()) sits in the theme's `.max-w-300px` box
 * (`max-width: 300px !important`), so "Reviewed by David (CEO) · Updated 15 Sep 2026" wrapped at 1440 px.
 * `min-width: 100%` wins over that max-width without another !important: the byline gets the full hero column
 * and stays on one line from 992 px; on narrower screens it wraps with balanced lines. No template change.
 */
.shortcode-hero-banner-style-3[style*="background-image"] .col-lg-7 .max-w-300px {
    min-width: 100%;
}

.shortcode-hero-banner-style-3[style*="background-image"] .col-lg-7 .max-w-300px > p {
    text-wrap: balance;
}

/*
 * X16 addendum: purple hero decorations on every detail page (staging fb40fc8 review, round 18, 2026-09-16).
 * The theme's rotating star PNG (`.rotateme`) and the purple ellipse (`.ellipse-primary`) of hero-banner style 3
 * were hidden only when the hero carries a header image, so detail pages without one (named Work case studies)
 * still showed them. A netbase-content detail hero is recognised by its eyebrow hub link (`subtitle`,
 * ContentFamilyRenderer::hubLink(), which directory heroes never set) and by having no hub tiles
 * (`main_image_1..4`, which only directory heroes set). Directory heroes keep their approved tiles and
 * decorations. Overrides only; no template change.
 */
.shortcode-hero-banner-style-3:has(.border-linear-1 a):not(:has(.border-5 img)) .rotateme,
.shortcode-hero-banner-style-3:has(.border-linear-1 a):not(:has(.border-5 img)) .ellipse-primary {
    display: none;
}

/*
 * X16 addendum: markdown tables in detail prose (staging bad6ec3 review, 2026-09-16). Overrides only.
 * Draft tables render as bare `<table>` elements in the `content-page` prose column (`.section-privacy-policy`),
 * where the theme gives cells 1px padding and no rules, so columns ran together ("Certifications and compliance
 * at a glance" on /why-netbase/security-compliance). Scoped to prose sections that follow a netbase-content detail
 * hero (eyebrow hub link `.border-linear-1 a`, as in the decorations addendum), so every detail family and no
 * Botble page. Below 576 px a wide table scrolls inside its own box instead of widening the page. No markup change.
 */
.shortcode-hero-banner-style-3:has(.border-linear-1 a) ~ .section-privacy-policy table {
    width: 100%;
    margin: 1.5rem 0 2rem;
    border-collapse: collapse;
    font-size: 0.9375rem;
    line-height: 1.5;
}

.shortcode-hero-banner-style-3:has(.border-linear-1 a) ~ .section-privacy-policy :is(th, td) {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--tc-neutral-200);
    text-align: left;
    vertical-align: top;
}

.shortcode-hero-banner-style-3:has(.border-linear-1 a) ~ .section-privacy-policy th {
    font-weight: 600;
    background: color-mix(in srgb, var(--tc-theme-primary) 6%, transparent);
    border-bottom: 2px solid var(--tc-theme-primary);
}

@media (max-width: 575.98px) {
    .shortcode-hero-banner-style-3:has(.border-linear-1 a) ~ .section-privacy-policy table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .shortcode-hero-banner-style-3:has(.border-linear-1 a) ~ .section-privacy-policy :is(th, td) {
        padding: 0.625rem 0.75rem;
    }
}

/*
 * ==========================================================================================================
 * X21 Design-token UI blocks and card/section unification (owner feedback and permission of David (CEO),
 * 2026-09-16: "if the theme has no ready UI element block, you may create UI, but follow the design tokens").
 * Tokens: docs/design/netbase-design-tokens.md. Blocks: docs/design/netbase-ui-blocks.md.
 * Rule for everything below: colours only through var() of theme/brand tokens (no hex literals); the --nb-*
 * aliases are defined once here. Overrides only; X11-X20 stay as recorded.
 * ==========================================================================================================
 */

/* --- Tokens: Netbase aliases over the theme variables ----------------------------------------------------- */
:root {
    --nb-radius-section: var(--bs-border-radius-xxl);
    --nb-radius-card: var(--bs-border-radius-xl);
    --nb-radius-control: var(--bs-border-radius-lg);
    --nb-radius-pill: var(--bs-border-radius-pill);
    --nb-surface: var(--tc-system-white);
    --nb-surface-muted: var(--tc-neutral-100);
    --nb-border-color: var(--tc-neutral-200);
    --nb-text: var(--tc-neutral-900);
    --nb-text-body: var(--tc-neutral-700);
    --nb-text-muted: var(--tc-neutral-600);
    --nb-accent: var(--tc-theme-primary);
    --nb-accent-text: var(--tc-theme-primary);
    --nb-accent-soft: color-mix(in srgb, var(--tc-theme-primary) 10%, transparent);
    --nb-brand-navy: var(--primary-color);
    --nb-brand-gradient: var(--primary-gradient-bg);
    /* X30b: the WhatsApp brand green of the chat launcher. The one colour literal in this layer: it is a
     * third-party brand colour, so no theme variable can express it. Owner-approved exception (David (CEO),
     * 2026-09-18, "sua style theo kieu WhatsApp"); every rule uses it through var(). */
    --nb-chat-whatsapp: #25d366;
    --nb-on-brand: var(--tc-neutral-dark-900);
    /* X35: link colour on the navy and dark bands; --nb-on-brand has the same value in both themes. */
    --nb-link-on-dark: var(--nb-on-brand);
    --nb-on-brand-muted: var(--tc-neutral-dark-700);
    --nb-shadow-card: 0 1px 2px color-mix(in srgb, var(--tc-neutral-dark-100) 6%, transparent), 0 8px 24px -12px color-mix(in srgb, var(--tc-neutral-dark-100) 22%, transparent);
    --nb-shadow-card-hover: 0 2px 4px color-mix(in srgb, var(--tc-neutral-dark-100) 8%, transparent), 0 18px 36px -14px color-mix(in srgb, var(--tc-neutral-dark-100) 30%, transparent);
    --nb-focus-ring: 0 0 0 3px color-mix(in srgb, var(--tc-theme-primary) 45%, transparent);
    --nb-space-block: clamp(3rem, 2rem + 3vw, 5rem);
    --nb-gap-grid: clamp(1rem, 0.75rem + 1vw, 1.5rem);
    --nb-fs-block-title: clamp(var(--tc-fs-3), 1.25rem + 1.6vw, var(--tc-fs-1));
    --nb-fs-card-title: var(--tc-fs-5);
}

[data-bs-theme="dark"] {
    --nb-accent-text: var(--tc-theme-dark-primary-light);
    --nb-accent-soft: color-mix(in srgb, var(--tc-theme-dark-primary-light) 16%, transparent);
    --nb-brand-navy: var(--primary-color-dark-soft);
    --nb-shadow-card: 0 1px 2px color-mix(in srgb, var(--tc-neutral-dark-0) 40%, transparent), 0 10px 28px -12px color-mix(in srgb, var(--tc-neutral-dark-0) 70%, transparent);
    --nb-shadow-card-hover: 0 2px 4px color-mix(in srgb, var(--tc-neutral-dark-0) 50%, transparent), 0 20px 40px -14px color-mix(in srgb, var(--tc-neutral-dark-0) 85%, transparent);
    --nb-focus-ring: 0 0 0 3px color-mix(in srgb, var(--tc-theme-dark-primary-light) 55%, transparent);
    --tc-shadow-dark-1: var(--nb-shadow-card);
    --tc-shadow-dark-2: var(--nb-shadow-card);
}

@media (max-width: 767.98px) {
    :root {
        --nb-radius-section: var(--bs-border-radius-xl);
    }
}

/* --- Netbase UI blocks (plugin views themes/blocks/*) ------------------------------------------------------ */
.nb-block {
    padding-block: var(--nb-space-block);
    color: var(--nb-text-body);
}

.nb-block__header {
    max-width: 48rem;
    margin-bottom: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
}

.nb-block__title {
    margin: 0 0 0.75rem;
    font-size: var(--nb-fs-block-title);
    line-height: var(--tc-heading-line-height);
    color: var(--nb-text);
    text-wrap: balance;
}

.nb-block__lead {
    margin: 0;
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--nb-text-body);
}

.nb-block__note {
    max-width: 48rem;
    margin: 1.5rem 0 0;
    font-size: var(--tc-fs-7);
    line-height: 1.6;
    color: var(--nb-text-muted);
}

.nb-block__note a,
.nb-block__lead a,
.nb-card__text a,
.nb-fact__value a {
    color: var(--nb-accent-text);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

.nb-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--nb-gap-grid);
    margin: 0;
    padding: 0;
    list-style: none;
}

.nb-grid > li {
    margin: 0;
}

@media (min-width: 768px) {
    .nb-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .nb-grid[data-count="1"] {
        grid-template-columns: minmax(0, 36rem);
    }
}

@media (min-width: 992px) {
    .nb-grid:not([data-count="1"], [data-count="2"], [data-count="4"]) {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .nb-family-cards .nb-grid:is([data-count="4"], [data-count="8"]),
    .nb-steps .nb-grid[data-count="4"] {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

.nb-card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: clamp(1.25rem, 1rem + 0.5vw, 1.5rem);
    background: var(--nb-surface);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-card);
    box-shadow: var(--nb-shadow-card);
    transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}

.nb-card--link:hover {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--nb-accent-text) 35%, var(--nb-border-color));
    box-shadow: var(--nb-shadow-card-hover);
}

.nb-card--link:focus-within {
    box-shadow: var(--nb-shadow-card-hover), var(--nb-focus-ring);
}

.nb-card__link {
    color: inherit;
    text-decoration: none;
}

.nb-card__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
}

.nb-card__link:focus-visible {
    outline: none;
}

.nb-card__title {
    margin: 0 0 0.5rem;
    font-size: var(--nb-fs-card-title);
    font-weight: var(--tc-fw-bold);
    line-height: 1.3;
    color: var(--nb-text);
}

.nb-card__lead,
.nb-card__text {
    margin: 0;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--nb-text-body);
}

.nb-card__detail {
    margin: auto 0 0;
    padding-top: 1rem;
    border-top: 1px solid var(--nb-border-color);
    font-size: var(--tc-fs-7);
    line-height: 1.5;
    color: var(--nb-text-muted);
}

.nb-card__lead + .nb-card__detail {
    margin-top: auto;
}

.nb-card__lead:has(+ .nb-card__detail) {
    margin-bottom: 1rem;
}

.nb-card__label {
    display: block;
    margin-bottom: 0.25rem;
    font-size: var(--tc-fs-8);
    font-weight: var(--tc-fw-bold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--nb-accent-text);
}

.nb-card__more {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    margin-top: 1rem;
    font-size: var(--tc-fs-7);
    font-weight: var(--tc-fw-bold);
    color: var(--nb-accent-text);
}

.nb-card__more svg {
    width: 1rem;
    height: 1rem;
    transition: transform 0.2s ease;
}

.nb-card--link:hover .nb-card__more svg {
    transform: translateX(3px);
}

.nb-card__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: auto;
    padding-top: 1.25rem;
}

/* Buttons: the CTA treatment for every card grid (blocks and the theme's "Learn More" / "Keep Reading" links). */
.nb-btn,
.shortcode-services-style-2 .feature-item > a.text-primary.fs-7,
.shortcode-blog-posts-style-2 .card-body > a.fw-bold.text-primary {
    position: relative;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: 0.5rem;
    padding: 0.625rem 1rem !important;
    font-size: var(--tc-fs-7) !important;
    font-weight: var(--tc-fw-bold);
    line-height: 1.2;
    color: var(--nb-accent-text) !important;
    white-space: nowrap;
    text-decoration: none;
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--nb-accent-text) 55%, transparent);
    border-radius: var(--nb-radius-control);
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.nb-btn:hover,
.shortcode-services-style-2 .feature-item > a.text-primary.fs-7:hover,
.shortcode-blog-posts-style-2 .card-body > a.fw-bold.text-primary:hover {
    color: var(--nb-on-brand) !important;
    background: var(--nb-accent);
    border-color: var(--nb-accent);
}

.nb-btn:focus-visible,
.shortcode-services-style-2 .feature-item > a.text-primary.fs-7:focus-visible,
.shortcode-blog-posts-style-2 .card-body > a.fw-bold.text-primary:focus-visible {
    outline: none;
    box-shadow: var(--nb-focus-ring);
}

.nb-btn svg,
.shortcode-services-style-2 .feature-item > a.text-primary.fs-7 svg,
.shortcode-blog-posts-style-2 .card-body > a.fw-bold.text-primary svg {
    width: 1rem;
    height: 1rem;
    margin: 0 !important;
}

.shortcode-services-style-2 .feature-item > a.text-primary.fs-7 svg path,
.shortcode-blog-posts-style-2 .card-body > a.fw-bold.text-primary svg path {
    fill: currentColor;
}

.nb-btn--ghost {
    color: var(--nb-text) !important;
    border-color: var(--nb-border-color);
}

.nb-btn--ghost:hover {
    color: var(--nb-text) !important;
    background: var(--nb-surface-muted);
    border-color: var(--tc-neutral-300);
}

/* Family cards */
.nb-family-cards .nb-card__title {
    font-size: 1.125rem;
}

/* Step cards */
.nb-steps__list {
    counter-reset: none;
}

.nb-step {
    overflow: hidden;
    padding-top: clamp(1.5rem, 1.25rem + 0.5vw, 1.75rem);
}

.nb-step::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 4px;
    background: var(--nb-brand-gradient);
}

.nb-step__number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    margin-bottom: 1rem;
    font-size: var(--tc-fs-7);
    font-weight: var(--tc-fw-bold);
    font-variant-numeric: tabular-nums;
    color: var(--nb-on-brand);
    background: var(--nb-accent);
    border-radius: var(--nb-radius-control);
}

.nb-step .nb-card__title {
    font-size: 1.125rem;
}

/* AI band */
.nb-ai-band__panel {
    display: grid;
    gap: clamp(1.5rem, 1rem + 2vw, 3rem);
    padding: clamp(1.75rem, 1rem + 3vw, 3.5rem);
    color: var(--nb-on-brand-muted);
    background: var(--nb-brand-navy);
    border: 1px solid color-mix(in srgb, var(--nb-on-brand) 10%, transparent);
    border-radius: var(--nb-radius-section);
    box-shadow: var(--nb-shadow-card);
}

@media (min-width: 992px) {
    .nb-ai-band__panel {
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
        align-items: start;
    }
}

.nb-ai-band__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: 1rem;
    color: var(--nb-on-brand);
    background: color-mix(in srgb, var(--nb-on-brand) 12%, transparent);
    border-radius: var(--nb-radius-control);
}

.nb-ai-band__icon svg {
    width: 1.5rem;
    height: 1.5rem;
}

.nb-ai-band .nb-block__header {
    margin-bottom: 0;
}

.nb-ai-band .nb-block__title {
    font-size: clamp(var(--tc-fs-4), 1.1rem + 1.2vw, var(--tc-fs-2));
    color: var(--nb-on-brand);
}

.nb-ai-band .nb-block__lead,
.nb-ai-band .nb-block__note {
    color: var(--nb-on-brand-muted);
}

.nb-ai-band .nb-block__note a,
.nb-ai-band .nb-block__lead a {
    color: var(--nb-on-brand);
}

.nb-ai-band__items {
    display: grid;
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 768px) {
    .nb-ai-band__items:not([data-count="1"]) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.nb-ai-band__item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.625rem;
    margin: 0;
    padding: 1.25rem 1.5rem;
    background: color-mix(in srgb, var(--nb-on-brand) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--nb-on-brand) 16%, transparent);
    border-radius: var(--nb-radius-card);
    box-shadow: var(--nb-shadow-card);
    transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.nb-ai-band__item::marker {
    content: none;
}

.nb-ai-band__item.nb-card--link:hover {
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--nb-on-brand) 12%, transparent);
    border-color: color-mix(in srgb, var(--nb-on-brand) 30%, transparent);
}

.nb-ai-band__item.nb-card--link:focus-within {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--nb-on-brand) 60%, transparent);
}

.nb-ai-band__title {
    margin: 0;
    font-size: 1.125rem;
    font-weight: var(--tc-fw-bold);
    line-height: 1.35;
    color: var(--nb-on-brand);
}

.nb-ai-band__title .nb-card__link:hover {
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

.nb-ai-band__text {
    margin: 0;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--nb-on-brand-muted);
}

.nb-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    font-size: var(--tc-fs-8);
    font-weight: var(--tc-fw-bold);
    line-height: 1.3;
    letter-spacing: 0.02em;
    color: var(--nb-on-brand);
    background: color-mix(in srgb, var(--tc-system-dark-success) 26%, transparent);
    border: 1px solid color-mix(in srgb, var(--tc-system-dark-success) 55%, transparent);
    border-radius: var(--nb-radius-pill);
}

.nb-badge::before {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: var(--tc-system-dark-success);
}

.nb-badge--growth {
    background: color-mix(in srgb, var(--tc-system-dark-warning) 18%, transparent);
    border-color: color-mix(in srgb, var(--tc-system-dark-warning) 50%, transparent);
}

.nb-badge--growth::before {
    background: var(--tc-system-dark-warning);
}

/* Fact grid */
.nb-facts__list {
    margin: 0;
}

.nb-fact {
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
}

.nb-fact__icon {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    color: var(--nb-accent-text);
    background: var(--nb-accent-soft);
    border-radius: var(--nb-radius-control);
}

.nb-fact__icon svg {
    width: 1.25rem;
    height: 1.25rem;
}

.nb-fact__body {
    min-width: 0;
}

.nb-fact__label {
    margin: 0 0 0.25rem;
    font-size: var(--tc-fs-8);
    font-weight: var(--tc-fw-semi-bold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--nb-text-muted);
}

.nb-fact__value {
    margin: 0;
    font-size: 1.0625rem;
    font-weight: var(--tc-fw-semi-bold);
    line-height: 1.45;
    color: var(--nb-text);
    overflow-wrap: anywhere;
}

/* Timeline: vertical below 992 px, horizontal from 992 px */
.nb-timeline__list {
    position: relative;
    display: grid;
    gap: 1rem;
    margin: 0;
    padding: 0 0 0 2rem;
    list-style: none;
}

.nb-timeline__list::before {
    content: "";
    position: absolute;
    top: 0.5rem;
    bottom: 0.5rem;
    left: 0.5625rem;
    width: 2px;
    background: linear-gradient(180deg, var(--nb-accent-soft), var(--nb-accent-text));
}

.nb-timeline__item {
    position: relative;
    margin: 0;
}

.nb-timeline__marker {
    position: absolute;
    top: 1.5rem;
    left: -2rem;
    width: 1.25rem;
    height: 1.25rem;
    background: var(--nb-surface);
    border: 3px solid var(--nb-accent-text);
    border-radius: 50%;
}

.nb-timeline__item--current .nb-timeline__marker {
    background: var(--nb-brand-gradient);
    border-color: var(--nb-surface);
    box-shadow: 0 0 0 2px var(--nb-accent-text);
}

.nb-timeline__card {
    height: 100%;
}

.nb-timeline__item--current .nb-timeline__card {
    border-color: color-mix(in srgb, var(--nb-accent-text) 45%, var(--nb-border-color));
    background: linear-gradient(180deg, var(--nb-accent-soft), transparent 70%), var(--nb-surface);
}

.nb-timeline__year {
    margin: 0 0 0.375rem;
    font-size: var(--tc-fs-4);
    font-weight: var(--tc-fw-extra-bold);
    line-height: 1.2;
    color: var(--nb-accent-text);
    font-variant-numeric: tabular-nums;
}

@media (min-width: 992px) {
    .nb-timeline__list {
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
        gap: var(--nb-gap-grid);
        padding: 2.25rem 0 0;
    }

    .nb-timeline__list::before {
        top: 0.5625rem;
        bottom: auto;
        left: 0;
        right: 0;
        width: auto;
        height: 2px;
        background: linear-gradient(90deg, var(--nb-accent-soft), var(--nb-accent-text));
    }

    .nb-timeline__marker {
        top: -2.25rem;
        left: 1.5rem;
    }
}

/* Division cards */
.nb-division__logo {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    height: 4.5rem;
    margin-bottom: 1.25rem;
    padding: 0.75rem 1rem;
    background: var(--nb-on-brand);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-control);
}

.nb-division__logo img {
    width: auto;
    max-width: 100%;
    max-height: 2.75rem;
    object-fit: contain;
}

.nb-division__initial {
    font-size: var(--tc-fs-3);
    font-weight: var(--tc-fw-extra-bold);
    color: var(--nb-brand-navy);
}

/* --- Theme card grids --------------------------------------------------------------------------------------- */

/* Services style 2 (directories, hub child lists, related cards, homepage): 3 / 2 / 1 columns, full-width thumbnail. */
.shortcode-services-style-2 .row {
    row-gap: var(--nb-gap-grid);
}

.shortcode-services-style-2 .row:not(:has(> :nth-child(3))) {
    justify-content: center;
}

.shortcode-services-style-2 .row > [class*="col-"] {
    display: flex;
}

@media (min-width: 992px) {
    .shortcode-services-style-2 .row > .col-lg-3 {
        flex: 0 0 33.3333%;
        max-width: 33.3333%;
    }
}

.shortcode-services-style-2 .feature-item {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    width: 100%;
    margin-bottom: 0 !important;
    padding: 1.5rem !important;
    overflow: hidden;
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card);
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.shortcode-services-style-2 .feature-item:hover {
    box-shadow: var(--nb-shadow-card-hover);
}

.shortcode-services-style-2 .feature-item:focus-within {
    box-shadow: var(--nb-shadow-card-hover), var(--nb-focus-ring);
}

.shortcode-services-style-2 .feature-item > a:has(> .service-thumbnail) {
    margin: -1.5rem -1.5rem 1.25rem !important;
}

.shortcode-services-style-2 .service-thumbnail {
    display: block;
    aspect-ratio: 16 / 9;
    border-radius: 0 !important;
}

.shortcode-services-style-2 .feature-item:has(.service-thumbnail) > .position-absolute.end-0.top-0 {
    display: none;
}

.shortcode-services-style-2 .feature-item strong.fs-6 {
    display: -webkit-box !important;
    margin-bottom: 0.5rem;
    font-size: var(--nb-fs-card-title) !important;
    line-height: 1.3;
    color: var(--nb-text);
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

.shortcode-services-style-2 .feature-item p.truncate-3-custom {
    margin-bottom: 1.25rem;
    color: var(--nb-text-body);
}

.shortcode-services-style-2 .feature-item > a.text-primary.fs-7 {
    margin-top: auto;
}

[data-bs-theme="dark"] .shortcode-services-style-2.bg-primary-light {
    background-color: var(--nb-surface-muted) !important;
}

/* Blog posts style 2 (Work case cards, homepage "Work we delivered"): card radius, token shadow, larger clamped title, CTA button. */
.shortcode-blog-posts-style-2 .swiper-slide > .card {
    border: 1px solid var(--nb-border-color) !important;
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card);
}

.shortcode-blog-posts-style-2 .swiper-slide > .card:hover {
    box-shadow: var(--nb-shadow-card-hover) !important;
}

.shortcode-blog-posts-style-2 .swiper-slide > .card:focus-within {
    box-shadow: var(--nb-shadow-card-hover), var(--nb-focus-ring) !important;
}

.shortcode-blog-posts-style-2 .swiper-slide > .card > img {
    border-radius: 0 !important;
}

.shortcode-blog-posts-style-2 .card-body {
    display: flex;
    flex-direction: column;
}

.shortcode-blog-posts-style-2 .card-body > strong.fs-6 {
    display: -webkit-box !important;
    min-height: calc(2 * 1.3em);
    margin-bottom: 0.75rem !important;
    font-size: var(--nb-fs-card-title) !important;
    line-height: 1.3;
    color: var(--nb-text);
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

.shortcode-blog-posts-style-2 .card-body > a.fw-bold.text-primary {
    margin-top: auto;
}

/* Blog posts style 5 (insight cards): unified radius, shadow and a larger title. */
.shortcode-blog-posts-style-5 .card-team {
    overflow: hidden;
    border-color: var(--nb-border-color) !important;
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card) !important;
}

.shortcode-blog-posts-style-5 .card-team:hover {
    box-shadow: var(--nb-shadow-card-hover) !important;
}

.shortcode-blog-posts-style-5 .card-team strong.fs-6 {
    font-size: var(--nb-fs-card-title) !important;
    line-height: 1.3;
}

.shortcode-blog-posts-style-5 .col-lg-5 img.rounded-3 {
    border-radius: var(--nb-radius-card) !important;
}

/* Features style 1 ({challenges}, {outcomes}, {patterns}, {triggers} cards): 3 / 2 / 1 columns of token cards. */
.shortcode-features-style-1 .row:has(> .col-lg-3) {
    row-gap: var(--nb-gap-grid);
}

.shortcode-features-style-1 .row > .col-lg-3 {
    display: flex;
}

@media (min-width: 992px) {
    .shortcode-features-style-1 .row > .col-lg-3 {
        flex: 0 0 33.3333%;
        max-width: 33.3333%;
    }
}

.shortcode-features-style-1 .feature-item {
    flex: 1 1 auto;
    margin-bottom: 0 !important;
    padding: 1.5rem;
    background: var(--nb-surface);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-card);
    box-shadow: var(--nb-shadow-card);
}

.shortcode-features-style-1 .feature-item strong.fs-6 {
    margin-bottom: 0.5rem;
    font-size: 1.125rem !important;
    line-height: 1.35;
    color: var(--nb-text);
}

/* Tabs, badges, testimonials and logo tiles: the card radius and shadow. */
.shortcode-testimonials-style-4 .card-testimonial-3,
.shortcode-feature-tabs .row.rounded-3,
.shortcode-support-tools .row > div > .border,
.shortcode-partners-style-3 .partner-item,
.shortcode-call-to-action-style-2 .banner {
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card);
}

.shortcode-feature-tabs .feature-tab-logo {
    border-radius: var(--nb-radius-control);
    box-shadow: var(--nb-shadow-card);
}

/* --- Sections with a background: one large radius ----------------------------------------------------------- */
.shortcode-hero-banner-style-3[style*="background-image"],
.shortcode-call-to-action-style-1,
.shortcode-contact-form-style-1,
.shortcode-features-style-8.section-cta-8,
.shortcode-blog-posts-style-2.bg-neutral-100,
.shortcode-services-style-2.bg-primary-light,
.section-faqs-2.bg-4,
.shortcode-feature-tabs.section-services-4,
.shortcode-testimonials-style-4 {
    overflow: hidden;
    border-radius: var(--nb-radius-section);
}

/* Framed sections keep their content clear of the rounded corners. */
.shortcode-hero-banner-style-3[style*="background-image"] > .container,
.shortcode-contact-form-style-1 > .container {
    padding-inline: clamp(1.25rem, 0.5rem + 2.5vw, 3rem);
}

/* Contact section ("Discuss a project"): the form panel takes the card radius; the offset blue edge behind it goes. */
.shortcode-contact-form-style-1 .rectangle-bg {
    display: none;
}

.shortcode-contact-form-style-1 .z-2.rounded-3.bg-primary {
    border: 1px solid color-mix(in srgb, var(--nb-on-brand) 14%, transparent);
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card-hover);
}

.shortcode-contact-form-style-1 .icon-shape.rounded-3 {
    border-radius: var(--nb-radius-control) !important;
}

/* --- FAQ (faqs styles 3 and 4): one aligned column of token cards with a +/- indicator ------------------------ */
.shortcode-faqs h3.ds-3 {
    --tc-ds-3: clamp(var(--tc-fs-2), 1.25rem + 1.8vw, var(--tc-ds-6));
    text-wrap: balance;
}

.section-faqs-2 .row > .col-lg-6 {
    flex: 0 0 100%;
    max-width: 52rem;
    margin-inline: auto;
    margin-top: 0 !important;
}

.shortcode-faqs .accordion .card {
    margin-bottom: 0.75rem !important;
    padding: 0 !important;
    background: var(--nb-surface) !important;
    border: 1px solid var(--nb-border-color) !important;
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card) !important;
    transition: box-shadow 0.2s ease, border-color 0.2s ease;
}

.shortcode-faqs .accordion .card:hover {
    box-shadow: var(--nb-shadow-card-hover) !important;
}

.shortcode-faqs .accordion .card:has(.collapse.show) {
    border-color: color-mix(in srgb, var(--nb-accent-text) 35%, var(--nb-border-color)) !important;
}

.shortcode-faqs .accordion .card .card-header {
    padding: 0 !important;
}

.shortcode-faqs .accordion .card .card-header a {
    gap: 1rem;
    padding: 1rem 1.25rem;
    border-radius: var(--nb-radius-card);
}

.shortcode-faqs .accordion .card .card-header a:focus-visible {
    outline: none;
    box-shadow: var(--nb-focus-ring);
}

.shortcode-faqs .accordion .card .card-header strong.fs-6 {
    font-size: 1.0625rem !important;
    line-height: 1.4;
    color: var(--nb-text);
}

.shortcode-faqs .accordion .card .card-header a .arrow,
.shortcode-faqs .accordion .card .card-header a.collapsed .arrow {
    position: relative;
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    margin: 0 0 0 auto !important;
    background: var(--nb-accent-soft);
    border-radius: 50%;
    transform: none;
}

.shortcode-faqs .accordion .card .card-header a .arrow svg {
    display: none;
}

.shortcode-faqs .accordion .card .card-header a .arrow::before,
.shortcode-faqs .accordion .card .card-header a .arrow::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.75rem;
    height: 2px;
    background: var(--nb-accent-text);
    border-radius: 1px;
    transform: translate(-50%, -50%);
    transition: transform 0.2s ease;
}

/* "+" while closed, "-" while open; read from the panel state, since the theme marks every toggle `collapsed` on load. */
.shortcode-faqs .accordion .card .card-header a .arrow::after {
    transform: translate(-50%, -50%) rotate(90deg);
}

.shortcode-faqs .accordion .card:has(.collapse.show) .card-header a .arrow::after {
    transform: translate(-50%, -50%) rotate(0deg);
}

.shortcode-faqs .accordion .card .collapse > p,
.shortcode-faqs .accordion .card .collapsing > p {
    margin: 0;
    padding: 0 1.25rem 1.25rem !important;
    line-height: 1.65;
    color: var(--nb-text-body);
}

/* --- Header: grouped menu, refined links, one-line CTA ------------------------------------------------------ */
@media (min-width: 992px) {
    .navbar-sticky > .container-fluid {
        gap: 1.5rem;
    }

    .navbar-sticky > .container-fluid > .d-lg-flex {
        flex: 1 1 auto;
        justify-content: center;
        min-width: 0;
    }

    .navbar-sticky > .container-fluid > .d-flex.align-items-center:last-child {
        flex: 0 0 auto;
    }

    .navbar-sticky .navbar-nav.gap-4 {
        gap: 0.125rem !important;
        margin-inline: 0 !important;
    }

    .navbar-sticky .navbar-nav > .nav-item > .nav-link {
        padding: 0.5rem 0.75rem !important;
        font-size: 0.9375rem;
        font-weight: var(--tc-fw-semi-bold) !important;
        white-space: nowrap;
        border-radius: var(--nb-radius-control);
        transition: color 0.2s ease, background-color 0.2s ease;
    }

    .navbar-sticky .navbar-nav > .nav-item > .nav-link:hover,
    .navbar-sticky .navbar-nav > .nav-item > .nav-link:focus-visible,
    .navbar-sticky .navbar-nav > .nav-item.show > .nav-link {
        color: var(--nb-accent-text) !important;
        background: var(--nb-accent-soft);
    }

    .navbar-sticky .navbar-nav > .nav-item > .nav-link.active {
        color: var(--nb-accent-text) !important;
    }

    .navbar-sticky .navbar-nav > .nav-item > .nav-link:focus-visible {
        outline: none;
        box-shadow: var(--nb-focus-ring);
    }

    .navbar-sticky .navbar-nav > .nav-item > .dropdown-toggle::after {
        margin-left: 0.375rem;
    }

    .navbar-sticky .navbar-nav .dropdown-menu {
        border: 1px solid var(--nb-border-color);
        border-radius: var(--nb-radius-card);
        box-shadow: var(--nb-shadow-card-hover);
    }

    .navbar-sticky .btn-gradient {
        padding: 0.625rem 1.25rem;
        font-size: 0.9375rem;
        white-space: nowrap;
        border-radius: var(--nb-radius-control);
    }
}

@media (min-width: 992px) and (max-width: 1199.98px) {
    .navbar-sticky > .container-fluid {
        gap: 0.75rem;
        padding-inline: 1rem !important;
    }

    .navbar-sticky .navbar-nav > .nav-item > .nav-link {
        padding: 0.5rem 0.5rem !important;
        font-size: 0.875rem;
    }

    .navbar-sticky .btn-gradient {
        padding: 0.5rem 0.875rem;
        font-size: 0.875rem;
    }
}

/* --- Homepage "Who we are" (about-us-information-tabs): the stats card stays inside its image ------------------ */
.shortcode-about-us-information-tabs .alltuchtopdown {
    top: auto !important;
    left: auto !important;
    right: 1rem;
    bottom: 1rem;
    margin: 0 !important;
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card-hover);
}

.shortcode-about-us-information-tabs .col-lg-6 > .position-relative.d-inline-block img {
    border-radius: var(--nb-radius-card);
}

/* --- Directory hero (hero-banner style 3 with hub tiles): text and tiles never overlap; no purple asterisk ------ */
.shortcode-hero-banner-style-3 .rotateme {
    display: none;
}

.shortcode-hero-banner-style-3 .border-5.border-white.rounded-4 {
    overflow: hidden;
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card);
}

/* Directory H1: the X20 detail scale instead of the theme's 80 px (4-5 lines at 1440 px, clipped at 390 px). */
.shortcode-hero-banner-style-3:has(.border-5 img) h1.ds-1 {
    --tc-ds-1: clamp(2.25rem, 1.25rem + 2.6vw, 4rem);
    --tc-ds-3: clamp(2.25rem, 1.25rem + 2.6vw, 4rem);
    overflow-wrap: break-word;
    text-wrap: balance;
}

@media (max-width: 1199.98px) {
    .shortcode-hero-banner-style-3:has(.border-5 img) .row > .col-lg-7:first-child {
        padding-bottom: 1.5rem !important;
    }

    .shortcode-hero-banner-style-3:has(.border-5 img) .row > .col-lg-7.position-xl-absolute {
        margin-bottom: 0 !important;
        transform: none !important;
    }
}

@media (min-width: 992px) and (max-width: 1199.98px) {
    .shortcode-hero-banner-style-3:has(.border-5 img) .row > .col-lg-7:first-child {
        flex: 0 0 55%;
        max-width: 55%;
    }

    .shortcode-hero-banner-style-3:has(.border-5 img) .row > .col-lg-7.position-xl-absolute {
        flex: 0 0 45%;
        max-width: 45%;
    }
}

@media (min-width: 1200px) {
    .shortcode-hero-banner-style-3:has(.border-5 img) .row > .col-lg-7:first-child {
        flex: 0 0 52%;
        max-width: 52%;
    }

    .shortcode-hero-banner-style-3:has(.border-5 img) .row > .col-lg-7.position-xl-absolute {
        width: 44%;
        max-width: 44%;
    }
}

/*
 * ==========================================================================================================
 * X22 Designed block UI for Why Netbase and the same shapes site-wide (owner request of David (CEO),
 * 2026-09-16: "the About Netbase detail pages are mostly raw content, upgrade every block"). Same rule as X21:
 * colours only through var() of theme/brand tokens, no new --nb-* aliases. Blocks: docs/design/netbase-ui-blocks.md.
 * ==========================================================================================================
 */

/* The theme hides every <br> below 992 px (!important); block text joins paragraphs with it (lead, note, division description). */
.nb-block :is(.nb-block__lead, .nb-block__note, .nb-card__text) br {
    display: inline !important;
}

/* Adjacent blocks share one gap instead of two paddings. */
.nb-block + .nb-block {
    padding-top: 0;
}

.nb-card__text a,
.nb-checklist__text a,
.nb-stage__body a,
.nb-split__body a,
.nb-record__field dd a,
.nb-step__detail dd a {
    color: var(--nb-accent-text);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* Feature cards: icon tile, title, text */
.nb-feature__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: 1rem;
    color: var(--nb-accent-text);
    background: var(--nb-accent-soft);
    border-radius: var(--nb-radius-control);
}

.nb-feature__icon svg {
    width: 1.375rem;
    height: 1.375rem;
}

/* Record cards: title with a status badge, labelled fields */
.nb-record__head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--nb-border-color);
}

.nb-record__head .nb-card__title {
    margin: 0;
}

.nb-record__fields {
    display: grid;
    gap: 1rem;
    margin: 0;
}

.nb-record__field dd {
    margin: 0;
}

.nb-status {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    font-size: var(--tc-fs-8);
    font-weight: var(--tc-fw-bold);
    line-height: 1.3;
    color: var(--nb-text);
    white-space: nowrap;
    background: var(--nb-surface-muted);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-pill);
}

.nb-status::before {
    content: "";
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: var(--nb-text-muted);
}

.nb-status--success {
    background: color-mix(in srgb, var(--tc-system-dark-success) 14%, var(--nb-surface));
    border-color: color-mix(in srgb, var(--tc-system-dark-success) 45%, transparent);
}

.nb-status--success::before {
    background: var(--tc-system-dark-success);
}

/* Step cards: labelled details of a numbered step table */
.nb-step .nb-card__text:has(+ .nb-step__details) {
    margin-bottom: 1rem;
}

.nb-step__details {
    display: grid;
    gap: 0.75rem;
    margin: auto 0 0;
    padding-top: 1rem;
    border-top: 1px solid var(--nb-border-color);
}

.nb-step__detail dd {
    margin: 0;
    font-size: var(--tc-fs-7);
    line-height: 1.5;
    color: var(--nb-text-body);
}

/* Checklists: one card per list; the two columns of an Included / Not included table side by side */
.nb-checklist__groups {
    display: grid;
    gap: var(--nb-gap-grid);
}

@media (min-width: 768px) {
    .nb-checklist__groups[data-count="2"] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .nb-checklist__groups[data-count="1"] .nb-checklist__list:not([data-count="1"], [data-count="2"], [data-count="3"]) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.nb-checklist__group,
.nb-fit__option,
.nb-stage__panel {
    overflow: hidden;
}

.nb-checklist__groups[data-count="2"] .nb-checklist__group::before,
.nb-fit__option::before,
.nb-stage__panel::before,
.nb-cta__panel::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 4px;
    background: var(--nb-brand-gradient);
}

.nb-checklist__groups[data-count="2"] .nb-checklist__group--yes::before,
.nb-fit__option--yes::before {
    background: var(--tc-system-dark-success);
}

.nb-checklist__groups[data-count="2"] .nb-checklist__group--no::before,
.nb-fit__option--no::before {
    background: var(--bouncing-blob-green-color);
}

.nb-checklist__groups[data-count="2"] .nb-checklist__group--alt::before {
    background: var(--nb-accent-text);
}

.nb-checklist__title {
    margin: 0 0 1rem;
    font-size: 1.125rem;
    font-weight: var(--tc-fw-bold);
    line-height: 1.35;
    color: var(--nb-text);
}

.nb-checklist__list {
    display: grid;
    gap: 0.75rem 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.nb-checklist__item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin: 0;
    line-height: 1.6;
    color: var(--nb-text-body);
}

.nb-checklist__icon,
.nb-fit__icon {
    display: inline-flex;
    flex: 0 0 auto;
    color: color-mix(in srgb, var(--tc-system-dark-success) 70%, var(--nb-text));
}

.nb-checklist__icon {
    margin-top: 0.125rem;
}

.nb-checklist__icon svg,
.nb-fit__icon svg {
    width: 1.375rem;
    height: 1.375rem;
}

.nb-checklist__group--no .nb-checklist__icon,
.nb-fit__option--no .nb-fit__icon {
    color: color-mix(in srgb, var(--bouncing-blob-green-color) 75%, var(--nb-text));
}

.nb-checklist__group--alt .nb-checklist__icon {
    color: var(--nb-accent-text);
}

.nb-checklist__text {
    min-width: 0;
}

/* Link tiles */
.nb-link {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.nb-link__title {
    font-weight: var(--tc-fw-bold);
    line-height: 1.35;
    color: var(--nb-text);
}

.nb-link__arrow {
    display: inline-flex;
    flex: 0 0 auto;
    color: var(--nb-accent-text);
    transition: transform 0.2s ease;
}

.nb-link__arrow svg {
    width: 1.25rem;
    height: 1.25rem;
}

.nb-link:hover .nb-link__arrow {
    transform: translateX(3px);
}

/* Fit cards: "Choose it when" / "Avoid it when" */
.nb-fit__label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.75rem;
    font-size: 1.125rem;
    font-weight: var(--tc-fw-bold);
    line-height: 1.35;
    color: var(--nb-text);
}

/* Stage panels: "Step 3: …" chapters */
.nb-stage {
    padding-block: clamp(0.5rem, 0.25rem + 0.75vw, 1rem);
}

.nb-stage:not(.nb-block + .nb-stage) {
    padding-top: var(--nb-space-block);
}

.nb-stage:not(:has(+ .nb-stage)) {
    padding-bottom: var(--nb-space-block);
}

.nb-stage__panel {
    display: grid;
    gap: clamp(1rem, 0.5rem + 1.5vw, 2.5rem);
    padding: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
}

@media (min-width: 992px) {
    .nb-stage__panel {
        grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
        align-items: start;
    }
}

.nb-stage__intro {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
}

.nb-stage__number {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    font-size: var(--tc-fs-5);
    font-weight: var(--tc-fw-extra-bold);
    font-variant-numeric: tabular-nums;
    color: var(--nb-on-brand);
    background: var(--nb-accent);
    border-radius: var(--nb-radius-control);
}

.nb-stage__title {
    margin: 0.375rem 0 0;
    font-size: clamp(var(--tc-fs-5), 1rem + 0.8vw, var(--tc-fs-4));
    line-height: 1.25;
    color: var(--nb-text);
    text-wrap: balance;
}

.nb-stage__body p {
    margin: 0 0 1rem;
    font-size: 1.0625rem;
    line-height: 1.7;
    color: var(--nb-text-body);
}

.nb-stage__body > p:last-child,
.nb-stage__callout p {
    margin: 0;
}

.nb-stage__callout {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    margin-top: 1.25rem;
    padding: 1rem 1.25rem;
    background: var(--nb-accent-soft);
    border: 1px solid color-mix(in srgb, var(--nb-accent-text) 25%, transparent);
    border-radius: var(--nb-radius-control);
}

.nb-stage__callout p {
    font-size: 1rem;
    line-height: 1.6;
    color: var(--nb-text);
}

.nb-stage__callout strong {
    color: var(--nb-accent-text);
}

.nb-stage__callout-icon {
    display: inline-flex;
    flex: 0 0 auto;
    color: var(--nb-accent-text);
}

.nb-stage__callout-icon svg {
    width: 1.5rem;
    height: 1.5rem;
}

/* CTA band: the closing "next step" chapter with real buttons */
.nb-cta__panel {
    position: relative;
    display: grid;
    gap: 1.5rem;
    padding: clamp(1.75rem, 1rem + 3vw, 3.5rem);
    overflow: hidden;
    background: linear-gradient(135deg, var(--nb-accent-soft), transparent 65%), var(--nb-surface);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-section);
    box-shadow: var(--nb-shadow-card);
}

@media (min-width: 992px) {
    .nb-cta__panel {
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        gap: 3rem;
    }
}

.nb-cta .nb-block__header {
    margin-bottom: 0;
}

.nb-cta .nb-block__title {
    font-size: clamp(var(--tc-fs-4), 1.1rem + 1.2vw, var(--tc-fs-2));
}

.nb-cta__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

.nb-btn.nb-btn--primary {
    padding: 0.875rem 1.375rem !important;
    font-size: 1rem !important;
    color: var(--nb-on-brand) !important;
    background: var(--nb-accent);
    border-color: var(--nb-accent);
}

.nb-btn.nb-btn--primary:hover {
    background: color-mix(in srgb, var(--nb-accent) 82%, var(--tc-neutral-dark-100));
    border-color: color-mix(in srgb, var(--nb-accent) 82%, var(--tc-neutral-dark-100));
}

.nb-cta .nb-btn--ghost {
    padding: 0.875rem 1.25rem !important;
    font-size: 1rem !important;
    background: var(--nb-surface);
}

@media (max-width: 575.98px) {
    .nb-cta__actions .nb-btn {
        justify-content: center;
        width: 100%;
        white-space: normal;
    }
}

/* Editorial split: heading beside the paragraphs of a trust-page chapter */
.nb-split {
    padding-block: clamp(2rem, 1.5rem + 1.5vw, 3rem);
}

.nb-split__inner {
    display: grid;
    gap: 1rem 3rem;
}

@media (min-width: 992px) {
    .nb-split__inner {
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    }
}

.nb-split + .nb-split .nb-split__inner {
    padding-top: clamp(2rem, 1.5rem + 1.5vw, 3rem);
    border-top: 1px solid var(--nb-border-color);
}

.nb-split__title {
    position: relative;
    margin: 0;
    padding-top: 1.25rem;
    font-size: clamp(var(--tc-fs-4), 1.1rem + 1vw, var(--tc-fs-2));
    line-height: 1.25;
    color: var(--nb-text);
    text-wrap: balance;
}

.nb-split__title::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 3rem;
    height: 4px;
    background: var(--nb-brand-gradient);
    border-radius: var(--nb-radius-pill);
}

.nb-split__body p {
    max-width: 44rem;
    margin: 0 0 1rem;
    font-size: 1.0625rem;
    line-height: 1.75;
    color: var(--nb-text-body);
}

.nb-split__body p:last-child {
    margin-bottom: 0;
}

@media (min-width: 992px) {
    .nb-split__body {
        padding-top: 1.25rem;
    }
}

/*
 * ==========================================================================================================
 * X23 UI residuals site-wide (owner rules of David (CEO), 2026-09-16: no bare tables, real CTA buttons, no
 * decoration over text, every UI comment applies to all similar places). Same rule as X21/X22: colours only
 * through var() of theme/brand tokens, no new --nb-* aliases. Blocks: docs/design/netbase-ui-blocks.md § X23.
 * ==========================================================================================================
 */

/* Theme call-to-action elements outside the detail templates (the mid-page CTA is now nb-cta): no shine or line
 * decoration behind the text, and the brand button instead of the theme's green one. */
.shortcode-call-to-action .flickering,
.shortcode-call-to-action img[src*="/shapes/bg-line"],
.shortcode-call-to-action .rectangle-banner3 {
    display: none;
}

.shortcode-call-to-action .btn-success {
    font-weight: var(--tc-fw-bold);
    color: var(--primary-color) !important;
    background-color: var(--nb-on-brand) !important;
    border-color: var(--nb-on-brand) !important;
    border-radius: var(--nb-radius-control);
}

.shortcode-call-to-action .btn-success:hover,
.shortcode-call-to-action .btn-success:focus-visible {
    background-color: color-mix(in srgb, var(--nb-on-brand) 86%, var(--primary-color)) !important;
    box-shadow: var(--nb-focus-ring);
}

/* Block title under an H3 inside a section (a table after "### Choosing the modernization route") */
.nb-block__title--sub {
    font-size: clamp(var(--tc-fs-5), 1rem + 0.8vw, var(--tc-fs-4));
}

/* Call-to-action links moved out of notes, card text and prose into buttons */
.nb-block__actions {
    margin: 1.25rem 0 0;
}

.nb-block__note + .nb-block__actions {
    margin-top: 1rem;
}

.nb-prose-action {
    margin: -0.25rem 0 1.75rem;
}

.nb-prose-action .nb-btn {
    white-space: normal;
}

.nb-prose-action .nb-btn::after {
    content: "\2192" / "";
}

/* Record cards: a linked first cell links the card; verdict columns ("Fits when" / "Think again when") get a mark */
.nb-record__fields + .nb-card__more {
    margin-top: auto;
    padding-top: 1rem;
}

.nb-card--link :is(.nb-card__text, .nb-checklist__text) a {
    position: relative;
    z-index: 2;
}

.nb-record__field--yes .nb-card__label,
.nb-record__field--no .nb-card__label {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.nb-record__verdict {
    display: inline-flex;
    color: color-mix(in srgb, var(--tc-system-dark-success) 70%, var(--nb-text));
}

.nb-record__field--no .nb-record__verdict {
    color: color-mix(in srgb, var(--bouncing-blob-green-color) 75%, var(--nb-text));
}

.nb-record__verdict svg {
    width: 1.125rem;
    height: 1.125rem;
}

/* Tables an Insight keeps (side-by-side comparisons, short lookup matrices): a token card in the reading column that
 * scrolls inside itself; the page never scrolls sideways. */
.nb-block.nb-table {
    padding-block: 0.5rem 0;
}

.nb-table + .section-privacy-policy .row.pt-110 {
    padding-top: 2rem;
}

.nb-table__scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--nb-surface);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-card);
    box-shadow: var(--nb-shadow-card);
}

.nb-table__scroll:focus-visible {
    outline: none;
    box-shadow: var(--nb-shadow-card), var(--nb-focus-ring);
}

.nb-table__scroll table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--nb-text-body);
}

.nb-table__scroll[data-columns="4"] table {
    min-width: 38rem;
}

.nb-table__scroll[data-columns="5"] table {
    min-width: 46rem;
}

@media (max-width: 575.98px) {
    .nb-table__scroll[data-columns="3"] table {
        min-width: 30rem;
    }
}

.nb-table__scroll :is(th, td) {
    padding: 0.875rem 1rem;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--nb-border-color);
}

.nb-table__scroll tbody tr:last-child :is(th, td) {
    border-bottom: 0;
}

.nb-table__scroll thead th {
    font-size: var(--tc-fs-7);
    font-weight: var(--tc-fw-bold);
    line-height: 1.35;
    color: var(--nb-text);
    background: var(--nb-accent-soft);
    border-bottom: 2px solid var(--nb-accent-text);
}

.nb-table__scroll tbody td:first-child {
    font-weight: var(--tc-fw-semi-bold);
    color: var(--nb-text);
}

.nb-table__scroll tbody tr:nth-child(even) {
    background: color-mix(in srgb, var(--nb-surface-muted) 60%, transparent);
}

.nb-table__scroll td a {
    color: var(--nb-accent-text);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* Shift cards: before → after rows of a {workflows} / {transformation} table (replaces the theme's compare table) */
.nb-shift__pair {
    display: grid;
    flex: 1 1 auto;
    grid-template-rows: auto 1fr;
    gap: 0.625rem;
    margin: 0;
}

.nb-shift__from,
.nb-shift__to {
    padding: 0.875rem 1rem;
    border-radius: var(--nb-radius-control);
}

.nb-shift__from {
    background: var(--nb-surface-muted);
}

.nb-shift__from .nb-card__label {
    color: var(--nb-text-muted);
}

.nb-shift__to {
    background: var(--nb-accent-soft);
    border-left: 3px solid var(--nb-accent-text);
}

.nb-shift__to .nb-card__label {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.nb-shift__pair dd {
    margin: 0;
    line-height: 1.55;
    color: var(--nb-text-body);
}

.nb-shift__to dd {
    color: var(--nb-text);
}

.nb-shift__arrow {
    display: inline-flex;
}

.nb-shift__arrow svg {
    width: 1rem;
    height: 1rem;
}

/* Division cards: the wordmark tile for a division without a logo master (monogram + name on the light logo tile) */
.nb-division__wordmark {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
}

.nb-division__wordmark .nb-division__initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    font-size: var(--tc-fs-5);
    line-height: 1;
    color: var(--nb-on-brand);
    background: var(--primary-color);
    border-radius: var(--nb-radius-control);
}

.nb-division__name {
    font-size: var(--tc-fs-5);
    font-weight: var(--tc-fw-extra-bold);
    letter-spacing: -0.01em;
    color: var(--primary-color);
}

/*
 * ==========================================================================================================
 * X24 Headings on phones, prose links, related grids with one or two cards (owner rules of David (CEO): every UI
 * comment applies to all similar places; cards with one radius and shadow; wide thumbnails; no text over images).
 * Same rule as X21-X23: colours only through var() of theme/brand tokens, no new --nb-* aliases.
 * Blocks: docs/design/netbase-ui-blocks.md § X24.
 * ==========================================================================================================
 */

/* Headings never run past their column: a long word breaks inside the heading instead of being clipped. */
:is(h1, h2, h3, h4, h5, h6, .nb-card__title) {
    overflow-wrap: anywhere;
}

/* Phones: the theme keeps desktop heading sizes below 768 px (H2 48 px, H3 38 px, H1 60 px), so one long word of a
 * prose H2 ("Recommendation limits") ran past a 390 px screen. The type scale tokens, fluid between 360 and 768 px. */
@media (max-width: 767.98px) {
    :is(h1, h2, h3, h4, h5, h6) {
        hyphens: auto;
    }

    h1,
    .h1 {
        font-size: clamp(var(--tc-fs-2), 1.25rem + 4vw, var(--tc-fs-1)) !important;
    }

    h2,
    .h2 {
        font-size: clamp(var(--tc-fs-3), 1.25rem + 2.5vw, var(--tc-fs-2));
    }

    h3,
    .h3 {
        font-size: clamp(var(--tc-fs-4), 1rem + 2.5vw, var(--tc-fs-3));
    }

    h4,
    .h4 {
        font-size: clamp(var(--tc-fs-5), 0.875rem + 2.5vw, var(--tc-fs-4));
    }

    h5,
    .h5 {
        font-size: var(--tc-fs-5);
    }

    h6,
    .h6 {
        font-size: var(--tc-fs-6);
    }
}

/* Links inside prose (detail body copy, block leads, notes and card text): accent colour and an underline, so a link
 * reads as a link; a thicker underline on hover and the focus ring on keyboard focus. Navigation, buttons, card
 * links and the table of contents keep their own treatment; the AI band keeps its on-brand text. */
.section-privacy-policy .col-lg-8 :is(p, li, dd, td, blockquote, figcaption) a:not(.nb-btn, .btn, #nb-toc + ul a),
.nb-block:not(.nb-ai-band) :is(.nb-block__lead, .nb-block__note, .nb-card__text, .nb-checklist__text, .nb-stage__body, .nb-split__body, .nb-fact__value, .nb-record__field dd, .nb-step__detail dd, .nb-shift__pair dd) a:not(.nb-btn) {
    color: var(--nb-accent-text);
    font-weight: var(--tc-fw-semi-bold);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--nb-accent-text) 55%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    border-radius: 0.125rem;
    transition: text-decoration-color 0.15s ease;
}

.section-privacy-policy .col-lg-8 :is(p, li, dd, td, blockquote, figcaption) a:not(.nb-btn, .btn, #nb-toc + ul a):hover,
.nb-block:not(.nb-ai-band) :is(.nb-block__lead, .nb-block__note, .nb-card__text, .nb-checklist__text, .nb-stage__body, .nb-split__body, .nb-fact__value, .nb-record__field dd, .nb-step__detail dd, .nb-shift__pair dd) a:not(.nb-btn):hover {
    color: var(--nb-accent-text);
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}

.section-privacy-policy .col-lg-8 :is(p, li, dd, td, blockquote, figcaption) a:not(.nb-btn, .btn, #nb-toc + ul a):focus-visible,
.nb-block:not(.nb-ai-band) :is(.nb-block__lead, .nb-block__note, .nb-card__text, .nb-checklist__text, .nb-stage__body, .nb-split__body, .nb-fact__value, .nb-record__field dd, .nb-step__detail dd, .nb-shift__pair dd) a:not(.nb-btn):focus-visible {
    outline: none;
    text-decoration-color: currentColor;
    box-shadow: var(--nb-focus-ring);
}

/* Detail H1 without a header image (named Work case studies): the theme's 64 px `.ds-1` below 768 px ran past a
 * 390 px screen; the same fluid phone size as other H1s (X19 still sets the header-image hero). */
@media (max-width: 767.98px) {
    h1.ds-1 {
        --tc-ds-1: clamp(var(--tc-fs-2), 1.25rem + 4vw, var(--tc-fs-1));
        --tc-ds-3: clamp(var(--tc-fs-2), 1.25rem + 4vw, var(--tc-fs-1));
        text-wrap: balance;
    }
}

/* Technologies directory (platforms-featured style 1): the one-line pill links (theme `text-nowrap`, spread with
 * `justify-content-lg-between`) ran past the row at every width; they wrap into centred token tiles with heading-colour
 * text (the theme's `text-500` was faint in dark mode). */
.shortcode-platforms-featured-style-1 .row.py-90 > [class*="col-"] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center !important;
    gap: 0.75rem;
}

.shortcode-platforms-featured-style-1 .row.py-90 a.text-nowrap {
    max-width: 100%;
    margin: 0 !important;
    white-space: normal !important;
    text-align: center;
    color: var(--nb-text) !important;
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-card) !important;
    box-shadow: var(--nb-shadow-card);
}

@media (max-width: 767.98px) {
    .shortcode-platforms-featured-style-1 .row.py-90 a.text-nowrap {
        width: 100%;
        font-size: var(--tc-fs-6) !important;
    }
}

/* Related grids with one or two cards (services style 2 related solutions/services, Work case cards, related
 * insights) left a wide empty area: one card becomes a wide horizontal card (thumbnail beside the text), two cards
 * share the row in two columns. Grids of three or more are unchanged. */
@media (min-width: 992px) {
    .shortcode-services-style-2 .row:has(> :nth-child(2)):not(:has(> :nth-child(3))) > [class*="col-"] {
        flex: 0 0 50%;
        max-width: 50%;
    }
}

@media (min-width: 768px) {
    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) > [class*="col-"] {
        flex: 0 0 100%;
        max-width: 100%;
    }

    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) .feature-item:has(.service-thumbnail) {
        display: grid;
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
        grid-template-rows: auto auto auto;
        column-gap: clamp(1.5rem, 1rem + 2vw, 3rem);
        align-content: center;
    }

    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) .feature-item > a:has(> .service-thumbnail) {
        grid-row: 1 / -1;
        margin: -1.5rem 0 -1.5rem -1.5rem !important;
    }

    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) .feature-item .service-thumbnail {
        height: 100%;
        min-height: 16rem;
        object-fit: cover;
    }

    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) .feature-item:has(.service-thumbnail) > :not(:first-child) {
        grid-column: 2;
    }

    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) .feature-item > a.text-primary.fs-7 {
        align-self: start;
        justify-self: start;
        margin-top: 0;
    }

    .shortcode-services-style-2 .row:not(:has(> :nth-child(2))) .feature-item:not(:has(.service-thumbnail)) {
        max-width: 48rem;
        margin-inline: auto;
    }
}

/* Work case cards (blog-posts style 2 slider): Swiper sizes each slide for three per row and locks the arrows. */
.shortcode-blog-posts-style-2 .swiper-button-lock {
    display: none !important;
}

@media (min-width: 992px) {
    .shortcode-blog-posts-style-2 .swiper-wrapper:has(> .swiper-slide:nth-child(2)):not(:has(> .swiper-slide:nth-child(3))) > .swiper-slide {
        width: calc(50% - 10px) !important;
    }
}

@media (min-width: 768px) {
    .shortcode-blog-posts-style-2 .swiper-wrapper:not(:has(> .swiper-slide:nth-child(2))) > .swiper-slide {
        width: 100% !important;
        margin-right: 0 !important;
    }

    .shortcode-blog-posts-style-2 .swiper-wrapper:not(:has(> .swiper-slide:nth-child(2))) > .swiper-slide > .card {
        flex-direction: row;
    }

    .shortcode-blog-posts-style-2 .swiper-wrapper:not(:has(> .swiper-slide:nth-child(2))) > .swiper-slide > .card > img {
        flex: 0 0 45%;
        width: 45%;
        height: auto;
        align-self: stretch;
    }

    .shortcode-blog-posts-style-2 .swiper-wrapper:not(:has(> .swiper-slide:nth-child(2))) > .swiper-slide > .card > .card-body {
        justify-content: center;
    }
}

/* Related insights (blog-posts style 5): one insight takes the whole row instead of the 7/12 column beside an empty
 * list column. */
@media (min-width: 992px) {
    .shortcode-blog-posts-style-5 .row.mt-8:not(:has(> .col-lg-5)) > .col-lg-7 {
        flex: 0 0 100%;
        max-width: 100%;
    }

    .shortcode-blog-posts-style-5 .row.mt-8:not(:has(> .col-lg-5)) .card-team > img {
        flex: 0 0 40%;
        width: 40%;
        height: 20rem;
        align-self: stretch;
        object-fit: cover;
    }
}

/* Insight cards (blog-posts style 5) from 992 to 1199 px: the 400 px portrait image left ~160 px for the text in the
 * 7/12 column, so titles and excerpts were clipped (`/insights`); the image takes 40 % of the card there. */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .shortcode-blog-posts-style-5 .card-team > img {
        flex: 0 0 40%;
        width: 40%;
        max-width: 40%;
        align-self: stretch;
        object-fit: cover;
    }

    .shortcode-blog-posts-style-5 .card-team > .bg-white {
        flex: 1 1 auto;
        min-width: 0;
    }
}

/* FAQ title: the X21 size follows the title when X24 prints it as the section H2 (DetailTemplate::outlined()). */
.shortcode-faqs h2.ds-3 {
    --tc-ds-3: clamp(var(--tc-fs-2), 1.25rem + 1.8vw, var(--tc-ds-6));
    text-wrap: balance;
}

/*
 * ==========================================================================================================
 * X25 Homepage heading order (decided by Claude (main agent) under David (CEO)'s full delegation, 2026-09-17).
 * HomepageOutline prints the Home 5 section titles as H2 (and, X25b, the cards or tabs of a section on one level below), keeping every class and
 * adding the original `.hN` class. The theme.css rules keyed on the old tags follow the same headings, with
 * the theme's own values, so spacing and the slide title size do not change. Only outlined headings carry an
 * `.hN` class on a different tag, so no other page is affected.
 * ==========================================================================================================
 */

/* theme.css `.ck-content h5` and `.ck-content h5:first-child`: section title spacing of the about, features and
 * contact titles. */
.ck-content :is(h2, h3, h4).h5 {
    margin-bottom: 1rem !important;
    margin-top: 2rem !important;
}

.ck-content :is(h2, h3, h4).h5:first-child {
    margin-top: 0 !important;
}

/* X25b: theme.css `.shortcode-partners-style-3 h5` follows `.ck-content h5` and wins on source order: the logo strip
 * title ("Platforms and cloud we build on…") keeps its 2rem bottom margin (32 px). Same specificity as the rule above,
 * later in the file. */
.shortcode-partners-style-3 :is(h2, h3, h4).h5 {
    margin-bottom: 2rem !important;
}

/* theme.css `.swiper.slider-two h3`: the slide title size set per slider (title_font_size). */
.swiper.slider-two h2.h3 {
    font-size: var(--shortcode-slider-title-font-size) !important;
}

/*
 * ==========================================================================================================
 * X26 Modules beside an image, and the "When to use it" split (owner request of David (CEO), 2026-09-17, from the
 * /solutions/ecommerce-marketplace "Capability modules" screenshot; decided by Claude (main agent) under his full
 * delegation). A long text list sat beside a small, vertically centred image with decorative dots, leaving a large
 * empty area. `nb-modules` (DetailTemplate::modules(), {modules} and {risk}): the image is top aligned and fills the
 * text column (object-fit cover around the registry focal point); five or more items are an accordion whose image
 * stays in view (sticky) on desktop. Below 992 px the image sits above the full-width list. The features style 3
 * "When to use it" split (`#nb-fit`, detail pages only) gets the same top-aligned, column-filling image.
 * Tokens only; no new --nb-* alias.
 * ==========================================================================================================
 */

.nb-modules__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
}

.nb-modules__body {
    min-width: 0;
}

.nb-modules__body > .nb-block__header {
    margin-bottom: 1.5rem;
}

.nb-modules__items {
    display: grid;
    gap: 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.nb-modules__media {
    position: relative;
    order: -1;
    margin: 0;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: var(--nb-radius-card);
    box-shadow: var(--nb-shadow-card);
    background: var(--nb-surface-muted);
}

.nb-modules__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focus-x, 50%) var(--focus-y, 50%);
}

.nb-focus-x-0 { --focus-x: 0%; }
.nb-focus-x-10 { --focus-x: 10%; }
.nb-focus-x-20 { --focus-x: 20%; }
.nb-focus-x-30 { --focus-x: 30%; }
.nb-focus-x-40 { --focus-x: 40%; }
.nb-focus-x-50 { --focus-x: 50%; }
.nb-focus-x-60 { --focus-x: 60%; }
.nb-focus-x-70 { --focus-x: 70%; }
.nb-focus-x-80 { --focus-x: 80%; }
.nb-focus-x-90 { --focus-x: 90%; }
.nb-focus-x-100 { --focus-x: 100%; }
.nb-focus-y-0 { --focus-y: 0%; }
.nb-focus-y-10 { --focus-y: 10%; }
.nb-focus-y-20 { --focus-y: 20%; }
.nb-focus-y-30 { --focus-y: 30%; }
.nb-focus-y-40 { --focus-y: 40%; }
.nb-focus-y-50 { --focus-y: 50%; }
.nb-focus-y-60 { --focus-y: 60%; }
.nb-focus-y-70 { --focus-y: 70%; }
.nb-focus-y-80 { --focus-y: 80%; }
.nb-focus-y-90 { --focus-y: 90%; }
.nb-focus-y-100 { --focus-y: 100%; }

@media (min-width: 992px) {
    .nb-modules__inner {
        grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
        align-items: stretch;
    }

    .nb-modules--no-image .nb-modules__inner {
        grid-template-columns: minmax(0, 52rem);
    }

    .nb-modules__media {
        order: 0;
        aspect-ratio: auto;
        min-height: 20rem;
    }

    /* Accordion: the media cell spans the row; the image fills it up to the viewport height and stays in view. */
    .nb-modules--accordion .nb-modules__media {
        overflow: visible;
        background: none;
        border-radius: 0;
        box-shadow: none;
    }

    .nb-modules--accordion .nb-modules__image {
        position: sticky;
        top: 7rem;
        height: min(100%, calc(100vh - 9rem));
        min-height: 20rem;
        border-radius: var(--nb-radius-card);
        box-shadow: var(--nb-shadow-card);
    }
}

/* List (up to four items): token cards in one column. */
.nb-modules--list .nb-modules__item {
    padding: 1rem 1.25rem;
    background: var(--nb-surface);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-control);
    box-shadow: var(--nb-shadow-card);
}

.nb-modules__title {
    margin: 0 0 0.25rem;
    font-size: 1.0625rem;
    font-weight: var(--tc-fw-bold);
    line-height: 1.4;
    color: var(--nb-text);
}

.nb-modules__text {
    margin: 0;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--nb-text-body);
}

/* The X24 prose-link treatment for links in module descriptions. */
.nb-modules__text a:not(.nb-btn) {
    color: var(--nb-accent-text);
    font-weight: var(--tc-fw-semi-bold);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--nb-accent-text) 55%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    border-radius: 0.125rem;
    transition: text-decoration-color 0.15s ease;
}

.nb-modules__text a:not(.nb-btn):hover {
    color: var(--nb-accent-text);
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}

.nb-modules__text a:not(.nb-btn):focus-visible {
    outline: none;
    text-decoration-color: currentColor;
    box-shadow: var(--nb-focus-ring);
}

/* Accordion (five or more items): the FAQ card treatment of X21, "+" while closed and "-" while open. */
.nb-modules--accordion .nb-modules__item {
    background: var(--nb-surface);
    border: 1px solid var(--nb-border-color);
    border-radius: var(--nb-radius-control);
    box-shadow: var(--nb-shadow-card);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.nb-modules--accordion .nb-modules__item:has(.collapse.show) {
    border-color: color-mix(in srgb, var(--nb-accent-text) 35%, var(--nb-border-color));
}

.nb-modules__heading {
    margin: 0;
    font-size: inherit;
}

.nb-modules__toggle {
    display: flex;
    align-items: center;
    gap: 1rem;
    width: 100%;
    padding: 0.875rem 1.25rem;
    color: var(--nb-text);
    text-align: left;
    background: none;
    border: 0;
    border-radius: var(--nb-radius-control);
}

.nb-modules__toggle:focus-visible {
    outline: none;
    box-shadow: var(--nb-focus-ring);
}

.nb-modules__toggle .nb-modules__title {
    margin: 0;
}

.nb-modules__sign {
    position: relative;
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    margin-left: auto;
    background: var(--nb-accent-soft);
    border-radius: 50%;
}

.nb-modules__sign::before,
.nb-modules__sign::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.75rem;
    height: 2px;
    background: var(--nb-accent-text);
    border-radius: 1px;
    transform: translate(-50%, -50%);
    transition: transform 0.2s ease;
}

.nb-modules__sign::after {
    transform: translate(-50%, -50%) rotate(90deg);
}

.nb-modules__toggle[aria-expanded="true"] .nb-modules__sign::after {
    transform: translate(-50%, -50%) rotate(0deg);
}

.nb-modules__panel > .nb-modules__text {
    padding: 0 1.25rem 1rem;
}

@media (prefers-reduced-motion: reduce) {
    .nb-modules__sign::before,
    .nb-modules__sign::after,
    .nb-modules--accordion .nb-modules__item {
        transition: none;
    }
}

/* "When to use it" (features style 3 in #nb-fit, detail pages): the image column is top aligned and filled. */
@media (min-width: 992px) {
    #nb-fit > .shortcode-features-style-3 .row.align-items-center {
        align-items: stretch !important;
    }

    #nb-fit > .shortcode-features-style-3 .row > .col-lg-6:has(> .position-relative > img) {
        display: flex;
    }

    #nb-fit > .shortcode-features-style-3 .row > .col-lg-6 > .position-relative:has(> img) {
        display: block !important;
        width: 100%;
        min-height: 20rem;
        margin-bottom: 0 !important;
    }

    #nb-fit > .shortcode-features-style-3 .row > .col-lg-6 > .position-relative > img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
}

/*
 * X27 Keyboard access: skip link and visible focus (launch QA T4-09, T4-10; decided — Claude (main agent) under
 * David (CEO)'s full delegation, 2026-09-17). Netbase\Content\Support\SkipLink prints the link before the top bar and
 * its focus target right before <main>. theme.css removes the outline from a:focus, .btn:focus and button:focus and
 * the nav link and form control focus shadows, so these rules use :focus-visible (keyboard focus, not mouse clicks)
 * with !important. Tokens only; no new --nb-* alias.
 */
.nb-skip-link {
    position: fixed;
    top: 0.75rem;
    left: 0.75rem;
    /* Above the Cloodo live chat iframe (inline z-index 2147483646, X28). */
    z-index: 2147483647;
    padding: 0.75rem 1.25rem;
    border-radius: var(--nb-radius-control);
    background-color: var(--nb-surface);
    color: var(--nb-accent-text);
    font-weight: 700;
    text-decoration: underline;
    box-shadow: var(--nb-shadow-card);
    transform: translateY(calc(-100% - 1.5rem));
    /* theme.css animates every link; the link must be in view the moment it takes focus. */
    transition: none;
}

.nb-skip-link:focus,
.nb-skip-link:focus-visible {
    transform: none;
}

.nb-skip-target:focus {
    outline: none;
}

/* Longhands: a var() inside the outline shorthand loses its width once a band rule below overrides the colour. */
a:not(.nb-card__link):focus-visible,
button:focus-visible,
.btn:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
    outline-style: solid !important;
    outline-width: 2px !important;
    outline-color: var(--nb-accent-text) !important;
    outline-offset: 2px !important;
}

/* Navy and dark bands (top bar, footer, contact section, navy panels, the AI band): a light outline. :is() keeps the
 * specificity above the rule before it. */
:is(.top-bar, footer, .shortcode-contact-form, .bg-primary, .nb-ai-band__panel) :is(a, button, input, select, textarea, summary, [role="button"], [tabindex]):focus-visible {
    outline-color: var(--nb-on-brand) !important;
}

/*
 * X28 Live chat stacking (owner request of David (CEO), 2026-09-18: the Cloodo live chat of the WordPress site moves to
 * Laravel; decided — Claude (main agent) under David (CEO)'s full delegation, 2026-09-18). chatcov2.js pins the chat
 * iframe bottom right with an inline z-index of 2147483646, the corner where the cookie banner card sits (and the
 * whole bottom edge on phones). The banner and the preferences dialog stay above the chat, so the chat never covers
 * the consent choice.
 */
.site-notice,
.cookie-consent-modal {
    z-index: 2147483647 !important;
}

/*
 * X29 Live chat layout stability (Launch L2 front-end performance; decided - Claude (main agent) under David (CEO)'s
 * full delegation, 2026-09-18). Staging round 29c: the chat cost 0.364-0.527 mobile CLS, all of it #chatco_popup.
 * ThirdPartyTags prints the frame `position: fixed` from the first byte, so the vendor moving it out of flow can no
 * longer shift anything. What is left is the vendor's own sizing: chatcov2.js writes 308 x 80 in its onload and the
 * greeting then posts 460 x 650, both seconds later and both anchored bottom right, so the frame's top left corner
 * moves and a visible frame would score each change. The frame therefore stays invisible - over the vendor's inline
 * `visibility: visible`, which needs !important - until the loader has seen its inline style quiet for 1.5 s and
 * marks it ready. Nothing about the vendor's behaviour changes: it still sizes, still postMessages, still reopens.
 */
#chatco_popup:not([data-nb-chat-ready]) {
    visibility: hidden !important;
}

/*
 * X30 Live chat launcher (Launch L2 front-end performance; decided — Claude (main agent) under David (CEO)'s full
 * delegation, 2026-09-18). chatcov2.js and its iframe cost 1.6-1.8 s of mobile blocking time on staging round 29c,
 * so the vendor is no longer requested while the page is still painting: this button is the visitor's way in, and
 * ThirdPartyTags loads the vendor on click (or by itself 15 s after load, in an idle callback). The button is
 * `hidden` in the server HTML and unhidden by that script, so it never appears without a working click. It sits one
 * stacking level below the chat and below the cookie banner (X28), and it is removed once the chat is on screen.
 *
 * X30b (owner report of David (CEO), 2026-09-18: "sua style theo kieu WhatsApp"): the pill becomes a WhatsApp-style
 * circle - 56 px, 48 px below 576 px, both above the 44 px target floor - filled with `--nb-chat-whatsapp` and
 * carrying one inline glyph in `--nb-surface`. The fill alone is about 2:1 on a light page, so the button draws its
 * own boundary with a 2 px ring mixed towards `--nb-text` (measured 5.03:1 against the white page). Behaviour,
 * position, safe-area offsets and stacking are unchanged.
 */
.nb-chat-launcher {
    position: fixed;
    right: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 2147483645;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    padding: 0;
    /* The component boundary against a light page: the fill alone is about 2:1, the ring is above 3:1. */
    border: 2px solid color-mix(in srgb, var(--nb-chat-whatsapp) 55%, var(--nb-text));
    border-radius: var(--nb-radius-pill);
    background: var(--nb-chat-whatsapp);
    color: var(--nb-surface);
    box-shadow: var(--nb-shadow-card);
    cursor: pointer;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.nb-chat-launcher[hidden] {
    display: none;
}

.nb-chat-launcher:hover {
    box-shadow: var(--nb-shadow-card-hover);
    transform: translateY(-2px);
}

.nb-chat-launcher:focus-visible {
    outline-color: var(--nb-accent-text) !important;
    outline-offset: 3px !important;
}

.nb-chat-launcher__icon {
    display: block;
    width: 1.625rem;
    height: 1.625rem;
}

/* Phones: a smaller circle, still a 48 px target, clear of the home indicator. */
@media (max-width: 575.98px) {
    .nb-chat-launcher {
        right: calc(12px + env(safe-area-inset-right, 0px));
        bottom: calc(12px + env(safe-area-inset-bottom, 0px));
        width: 3rem;
        height: 3rem;
    }

    .nb-chat-launcher__icon {
        width: 1.5rem;
        height: 1.5rem;
    }
}

/*
 * X32 Hero slide title on phones (Launch L2 front-end performance; decided - Claude
 * (main agent) under David (CEO)'s full delegation, 2026-09-18). The theme's per-slider title size
 * (`--shortcode-slider-title-font-size`, 64 px on the homepage) is carried to every width by the X25c rule
 * `.swiper.slider-two h2.h3`, while X24 lets any heading break inside a word. At 390 px the slide 2 title therefore
 * read "Comme / rce". The title keeps the fluid heading scale below 768 px and breaks between words only; the
 * `!important` is needed because the X25c rule (and theme.css behind it) is itself `!important`.
 */
@media (max-width: 767.98px) {
    .swiper.slider-two h2.h3 {
        font-size: clamp(var(--tc-fs-3), 1.25rem + 4vw, var(--tc-ds-6)) !important;
        overflow-wrap: normal;
        word-break: normal;
        hyphens: manual;
    }
}

/*
 * X34 Contact page structure (owner report of David (CEO), 2026-09-18: "contact vẫn bị double và dài"; decided —
 * Claude (main agent) under David (CEO)'s full delegation, 2026-09-18). Everything the draft said used to go into the
 * Home 5 contact band's `description`, so the lead repeated the channel rows beside it and the H2s of those sections
 * were dropped: /contact rendered as one band of running text with no H2. UtilityPagesSeeder now keeps only the lead
 * in the band and stores the other draft sections as plain page content between the band and the map, in the theme's
 * own container and grid. Only spacing and the X24 prose-link treatment are set here; the headings and body copy keep
 * the `.ck-content` treatment the other stored-markdown utility pages use, and no theme file changes.
 */
.nb-contact-notes {
    padding-block: var(--nb-space-block);
}

.nb-contact-notes :is(h2, h3) {
    color: var(--nb-text);
}

.nb-contact-notes :is(p, li) {
    color: var(--nb-text-body);
}

.nb-contact-notes :is(p, li) a:not(.nb-btn, .btn) {
    color: var(--nb-accent-text);
    font-weight: var(--tc-fw-semi-bold);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--nb-accent-text) 55%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    border-radius: 0.125rem;
    transition: text-decoration-color 0.15s ease;
}

.nb-contact-notes :is(p, li) a:not(.nb-btn, .btn):hover {
    color: var(--nb-accent-text);
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}

.nb-contact-notes :is(p, li) a:not(.nb-btn, .btn):focus-visible {
    outline: none;
    text-decoration-color: currentColor;
    box-shadow: var(--nb-focus-ring);
}

/*
 * X35 Links on the navy and dark bands (owner report of David (CEO), 2026-09-18: links on the contact band turn dark
 * and are nearly invisible; decided — Claude (main agent) under David (CEO)'s full delegation, 2026-09-18).
 * theme.css colours every link `a, button { color: var(--tc-neutral-900) }`, and that token is near-black in the
 * light theme, so any link on a dark band carrying no colour utility of its own was dark on dark. Measured on
 * staging round 31 (crawl of home, contact, a service, a solution, an insight, a work record and the two Why Netbase
 * pages, 1440 and 390 px, light and dark): the contact-band prose links 3.31:1 and the consent link inside the form
 * panel 1.52:1, on all eight page types, against the 4.5:1 floor. The exact colours are in the X35 record.
 *
 * The bands are the ones that crawl found painting a dark background behind links, the same list the X27
 * focus-outline rule already uses: the top bar, the footer, the contact band, its `.bg-primary` form panel and the
 * AI band panel. `--nb-link-on-dark` is `--nb-on-brand`, the one on-brand text token whose value does not change
 * with the theme, so the colour cannot invert when the visitor switches theme. Neither rule is `!important`, so the
 * theme's `text-*` colour utilities (Bootstrap writes them `!important`) still win and the footer, top-bar and card
 * links keep exactly the colour they have today; the rules only replace the near-black default. Keyboard focus keeps
 * the light X27 outline.
 */
/* No link on a dark band falls back to the near-black default link colour. */
:is(.top-bar, footer, .shortcode-contact-form, .bg-primary, .nb-ai-band__panel) a:not(.nb-btn, .btn, .nb-card__link) {
    color: var(--nb-link-on-dark);
}

/* Links in running text on a dark band: the X24 prose-link treatment, inverted. */
:is(.top-bar, footer, .shortcode-contact-form, .bg-primary, .nb-ai-band__panel) :is(p, li, dd, td, span, blockquote, figcaption, label) a:not(.nb-btn, .btn, .nb-card__link) {
    color: var(--nb-link-on-dark);
    font-weight: var(--tc-fw-semi-bold);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--nb-link-on-dark) 55%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    border-radius: 0.125rem;
    transition: text-decoration-color 0.15s ease;
}

:is(.top-bar, footer, .shortcode-contact-form, .bg-primary, .nb-ai-band__panel) :is(p, li, dd, td, span, blockquote, figcaption, label) a:not(.nb-btn, .btn, .nb-card__link):hover {
    color: var(--nb-link-on-dark);
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}

/* The table of contents pinned `--tc-theme-primary`, the light-theme navy, in both themes: 3.3:1 on the dark-theme
 * page background. The theme-aware alias gives it the same colour the prose links use in each theme. */
#nb-toc + ul a {
    color: var(--nb-accent-text);
}
