/*
 * Divisi Brand CSS
 * Sits on top of Bootstrap 5.3 — override only what differs from vanilla Bootstrap.
 *
 * Brand palette (per brand guide):
 *   Primary:   #00A85A · #0CEA7B
 *   Secondary: #6D6E70 · #000000
 *
 * Brand fonts (self-hosted from brand kit):
 *   Heading: Qualy   (primary font)
 *   Body:    MazzardH (secondary font)
 */

/* ── 0a. Self-hosted brand fonts ────────────────────────────────────────── */
@font-face {
    font-family: 'Qualy';
    src: url("../fonts/Qualy.7bd158242f2c.woff2") format('woff2');
    font-weight: 400 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'MazzardH';
    src: url("../fonts/MazzardH-Regular.5bc51c70507c.woff2") format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'MazzardH';
    src: url("../fonts/MazzardH-Medium.330b61616737.woff2") format('woff2');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'MazzardH';
    src: url("../fonts/MazzardH-SemiBold.fec8f79a3547.woff2") format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'MazzardH';
    src: url("../fonts/MazzardH-Bold.663f35e00d91.woff2") format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* ── 0b. Design tokens ──────────────────────────────────────────────────── */
:root {
    /* Brand fonts */
    --dv-font-heading: 'Qualy', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --dv-font-body: 'MazzardH', system-ui, -apple-system, 'Segoe UI', sans-serif;

    /* Brand palette — exact values from brand guide */
    --dv-green: #00A85A; /* Primary green */
    --dv-green-light: #0CEA7B; /* Primary accent green */
    --dv-green-dark: #007a45; /* Functional hover shade — not a structural colour */
    --dv-green-pale: #f0faf5; /* Reserved for hero & on-brand accent sections */
    /* Brand green as *text*. --dv-green is a background colour: at #00A85A it is
       only 3.1:1 on white, which fails AA for the small uppercase eyebrows it was
       being used for. No single green clears 4.5:1 in both themes, so this token
       resolves per theme — always reach for it when green is type, not fill. */
    --dv-green-accent: var(--dv-green-dark); /* 5.4:1 on white */
    --dv-tag-pill-bg: var(--dv-green-pale); /* resting fill for .dv-tag-pill */

    /* Decorative greens, light ground. The signature contours need roughly
       double the alpha and the darker brand green to register on white at all;
       the bloom needs less, because a bright wash on white reads as a stain
       rather than as light. */
    --dv-contour-stroke: rgba(0, 168, 90, 0.20);
    --dv-bloom-core: rgba(0, 168, 90, 0.09);
    --dv-bloom-mid: rgba(0, 168, 90, 0.035);
    --dv-gray: #6D6E70; /* Brand secondary gray */

    /* Text */
    --dv-text: #000000; /* Brand black */

    /* Chrome — the navbar, the CTA band and the footer. Deep forest, not the
       flat #000 all three used to carry. The dark theme's own canvas is
       already "near-black with a green heart" (#0b110d) and its surface is
       #121a15, so black chrome was the one thing on the page that belonged to
       no palette: a slab pasted onto the brand rather than part of it.

       #121a15 is that forest surface, and it is deliberately the SAME in both
       themes — chrome here is a dark anchor, not a themed surface. White on it
       is 17.7:1 and --dv-green-light is 11:1, so nothing that sat on black
       loses contrast. */
    --dv-chrome: #121a15;
    --dv-text-muted: #505153; /* Accessible secondary text — 5.8:1 on white (WCAG AA all sizes) */

    /* Surfaces */
    --dv-surface: #ffffff;
    --dv-surface-alt: #f5f5f5; /* Neutral alternating section background */

    /* Card / outline system — modern retro: crisp borders, no soft glow */
    --dv-card-border: rgba(0, 0, 0, 0.80);
    --dv-card-shadow: none;
    --dv-card-hover-shadow: 3px 3px 0 rgba(0, 0, 0, 0.85);

    /* Accessibility */
    --dv-min-touch: 48px; /* Minimum touch target height (WCAG 2.5.8) */

    /* Bootstrap token overrides */
    --bs-primary: var(--dv-green);
    --bs-primary-rgb: 0, 168, 90;
    --bs-link-color: var(--dv-green);
    --bs-link-color-rgb: 0, 168, 90;
    --bs-link-hover-color: var(--dv-green-dark);
    --bs-body-bg: #ffffff;
    --bs-body-font-family: var(--dv-font-body);
    --bs-body-font-size: 1.0625rem; /* 17px — rural readability baseline */
    --bs-body-line-height: 1.75; /* generous leading for low-literacy readers */
    --bs-body-color: var(--dv-text);
    --bs-secondary-color: var(--dv-text-muted);
    --bs-border-color: rgba(0, 0, 0, 0.2);
    --bs-border-radius: 0.5rem;
    --bs-border-radius-lg: 0.75rem;
    --bs-border-radius-xl: 1rem;
}

/* ── Dark mode token overrides ──────────────────────────────────────────── */
/* Deep forest + brand green. base.html sets data-bs-theme on <html> from the
   device's prefers-color-scheme (no in-page switcher); dark is the default. */
[data-bs-theme="dark"] {
    --dv-contour-stroke: rgba(12, 234, 123, 0.10);
    --dv-bloom-core: rgba(12, 234, 123, 0.16);
    --dv-bloom-mid: rgba(12, 234, 123, 0.06);

    --dv-green-pale: #16241b; /* Deep green-tinted panel */
    --dv-green-accent: var(--dv-green-light); /* 13:1 on the forest canvas */
    --dv-tag-pill-bg: rgba(0, 168, 90, 0.14);
    --dv-gray: #9a9b9d;

    --dv-text: #f2f4f2;
    --dv-text-muted: #b9c0bb; /* green-grey secondary text */
    --dv-surface: #121a15; /* forest surface */
    --dv-surface-alt: #0f1611; /* deeper alternating band */

    --dv-card-border: rgba(255, 255, 255, 0.14);
    --dv-card-shadow: none;
    --dv-card-hover-shadow: 3px 3px 0 rgba(12, 234, 123, 0.25);

    --bs-body-bg: #0b110d; /* brand canvas: near-black with a green heart */
    --bs-body-color: var(--dv-text);
    --bs-secondary-color: var(--dv-text-muted);
    --bs-border-color: rgba(255, 255, 255, 0.14);
    --bs-link-color: var(--dv-green-light);
    --bs-link-hover-color: var(--dv-green-light);
}

/* Deep brand-green band — the download anchor's moment. Rich, not loud:
   the app splash's forest gradient with the site's normal light text.
   Always dark, so it carries its own dark tokens for when the page is light. */
.dv-band-green {
    --dv-text: #f2f4f2;
    --dv-text-muted: #b9c0bb;
    --dv-card-border: rgba(255, 255, 255, 0.14);
    --bs-body-bg: #0b110d;
    --bs-secondary-color: var(--dv-text-muted);
    background: linear-gradient(180deg, #103322 0%, #0b2416 60%, #0a1f13 100%);
    border-top: 1px solid rgba(12, 234, 123, 0.18);
    border-bottom: 1px solid rgba(12, 234, 123, 0.18);
    color: var(--dv-text);
}

/* ── 1. Base typography ─────────────────────────────────────────────────── */
html {
    scroll-behavior: smooth;
}

body {
    font-family: var(--dv-font-body);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    /* Wide-gutter rows (.g-5) and decorative tilts overhang the viewport by a
       few px on phones; the overhang is never content, so clip it. */
    overflow-x: clip;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6,
.navbar-brand {
    font-family: var(--dv-font-heading);
    font-weight: 800;
    letter-spacing: -0.02em;
}

/* ── 2. Brand utility classes ───────────────────────────────────────────── */
.text-brand {
    color: var(--dv-green-accent) !important;
}

/* Topic / version pill — the filter chips above the insights list and the version
   marker on the changelog. Lived in a <style> block on the insights template until
   a second page needed it. */
.dv-tag-pill {
    display: inline-block;
    padding: 0.3rem 0.85rem;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
    color: var(--dv-green-accent);
    background: var(--dv-tag-pill-bg);
    border: 1px solid transparent;
    transition: background 0.15s ease, color 0.15s ease;
}

/* Dark type on the green fill, not white: white on --dv-green is 3.1:1, which
   fails AA in both themes — and the selected filter is the one chip that has to
   stay readable.
   The resting background is a token rather than a `[data-bs-theme] .dv-tag-pill`
   rule: that rule outranks this one on specificity and would take the fill back
   off the selected chip, leaving dark type on a near-black panel. */
.dv-tag-pill:hover,
.dv-tag-pill:focus-visible,
.dv-tag-pill--active {
    background: var(--dv-green);
    color: #0b110d;
}

/* ── 3. Navbar ──────────────────────────────────────────────────────────── */
.dv-navbar {
    padding-top: 1rem;
    padding-bottom: 1rem;
    background: var(--dv-chrome);
    box-shadow: 0 2px 0 rgba(0, 168, 90, 0.35); /* Green rule under pure black reads crisper */
    transition: box-shadow 0.2s ease;
}

.dv-navbar .navbar-brand {
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--dv-green-light); /* bright accent on dark bg */
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.dv-navbar .navbar-brand img {
    width: 36px;
    height: 36px;
    object-fit: contain;
}

.dv-navbar .navbar-brand:hover {
    color: #fff;
    text-decoration: none;
}

.dv-navbar .nav-link {
    font-weight: 600;
    color: rgba(255, 255, 255, 0.78) !important; /* light on dark bg */
    padding: 0.5rem 0.9rem;
    min-height: 44px;
    display: flex;
    align-items: center;
    border-radius: 0.4rem;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.dv-navbar .nav-link {
    position: relative;
}

.dv-navbar .nav-link:hover {
    color: #fff !important;
    background-color: rgba(0, 168, 90, 0.12);
}

.dv-navbar .nav-link.active {
    color: #fff !important;
}

.dv-navbar .nav-link.active::after {
    content: "";
    position: absolute;
    left: 0.9rem;
    right: 0.9rem;
    bottom: 0.35rem;
    height: 2px;
    border-radius: 2px;
    background: var(--dv-green-light);
}

/* Mobile drawer border */
.dv-navbar .dv-nav-drawer-border {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* ── 4. Buttons ─────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-primary {
    background-color: var(--dv-green);
    border-color: var(--dv-green);
    color: #04170d; /* black-on-green, like the app — and AA contrast */
    font-weight: 700;
    min-height: var(--dv-min-touch);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
    background-color: var(--dv-green-light);
    border-color: var(--dv-green-light);
    color: #04170d;
}

.btn-primary:focus-visible {
    box-shadow: 0 0 0 0.2rem rgba(0, 168, 90, 0.4);
}

/* Bootstrap's .btn-outline-primary, form focus rings, checkboxes and pagination
   bake in their own blue and ignore --bs-primary — rebrand them to Divisi green
   here so the whole site is on-brand (not just .btn-primary). */
.btn-outline-primary {
    --bs-btn-color: var(--dv-green);
    --bs-btn-border-color: var(--dv-green);
    --bs-btn-hover-bg: var(--dv-green);
    --bs-btn-hover-border-color: var(--dv-green);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--dv-green-dark);
    --bs-btn-active-border-color: var(--dv-green-dark);
    --bs-btn-disabled-color: var(--dv-green);
    --bs-btn-disabled-border-color: var(--dv-green);
    --bs-btn-focus-shadow-rgb: 0, 168, 90;
}

[data-bs-theme="dark"] .btn-outline-primary {
    --bs-btn-color: var(--dv-green-light);
    --bs-btn-border-color: var(--dv-green-light);
    --bs-btn-hover-bg: var(--dv-green-light);
    --bs-btn-hover-border-color: var(--dv-green-light);
    --bs-btn-hover-color: #06241a;
    --bs-btn-active-bg: var(--dv-green-light);
    --bs-btn-active-border-color: var(--dv-green-light);
    --bs-btn-active-color: #06241a;
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--dv-green);
    box-shadow: 0 0 0 0.2rem rgba(0, 168, 90, 0.25);
}

.form-check-input:checked {
    background-color: var(--dv-green);
    border-color: var(--dv-green);
}

/* ── 5. App store buttons ───────────────────────────────────────────────── */
/* Apple's and Google's own badge artwork. Both vendors require their supplied
   badge and forbid a lookalike, so nothing here touches a colour, a corner or
   a border of the badge — only how wide it is and how much room it gets.

   Both badges carry their own light outline, so both read on a white page and
   on --dv-chrome without a plate behind them or a second variant. Both files
   are badge-only: the generator trims the clear space Google bakes into its
   canvas, which is what lets the two share a width at all, and the padding
   here is the clear space both vendors require.

   MATCHED ON WIDTH, EVERYWHERE. The badges do not share an aspect ratio —
   Apple's is 3.00:1, Google's 3.37:1 — so one dimension has to differ, by
   about 12%, and no amount of CSS removes that without distorting a mark we
   are not allowed to distort. Width is the one to hold: these stack far more
   often than they sit in a row (the footer column at every width, and eleven
   `flex-column flex-sm-row` wrappers below `sm`), and a column with ragged
   right edges is the version that looks wrong.

   One rule, no breakpoints. An earlier attempt matched height in rows and
   width in columns, which was right in each case on its own and produced two
   pairs on one screen that plainly disagreed with each other. Consistency
   across the site beats being locally optimal twice. */
.store-btn {
    --dv-badge-w: 152px;
    display: inline-flex;
    align-items: center;
    /* Centred, because a stacking wrapper stretches these anchors to its full
       width (flex `align-items: stretch`) and the badge inside would otherwise
       sit against the left edge — under a centred heading and centred pills,
       which is what made the mobile CTA bands look misaligned. The footer sets
       `align-self: flex-start`, so its anchors stay content-width and this
       changes nothing there. */
    justify-content: center;
    /* Half the quarter-of-badge-height both vendors ask for — a twelfth of the
       width at ~3:1, so halved is a twenty-fourth — so that two adjacent
       badges contribute the full clear space between them, not twice it. */
    padding: calc(var(--dv-badge-w) / 24);
    text-decoration: none;
    transition: transform 0.15s ease, opacity 0.15s ease;
}

.store-btn:hover {
    transform: translateY(-1px);
    text-decoration: none;
}

.store-btn .store-badge {
    display: block;
    width: var(--dv-badge-w);
    height: auto;
}

/* Detected platform — bigger; the one that lost the detection fades back. */
.store-btn-featured {
    --dv-badge-w: 196px;
}

.store-btn-muted {
    opacity: 0.55;
}

.store-btn-muted:hover {
    opacity: 1;
}

/* Footer brand column and the inline CTA. A px value, never 100%: these
   anchors shrink to fit in the row variant below, so a percentage resolves
   against a box that is itself sized by its content and the two badges come
   out at different widths. That is not a subtle bug — it rendered one badge
   at twice the other in the footer's row breakpoint. */
.store-btn-compact {
    --dv-badge-w: 200px;
}

/* On a phone every wrapper but the footer's is a full-width column, so the
   badges grow — but not to the full width of it, and this is the one place
   the artwork overrules the layout.

   The two badges differ in aspect ratio by 12.7% (Apple 2.99:1, Google
   3.37:1). Held to a common width, Apple therefore renders that much taller,
   and the gap scales with size: 5.7px at 152px wide, 12.1px at a full-bleed
   322px. Small, the pair reads as a matched set; large, it reads as a
   mistake. Neither dimension can be equalised without distorting a mark we
   are not allowed to distort, so the lever is size, and 216px is where the
   difference stops being the thing you look at. */
@media (max-width: 575.98px) {
    .store-btn:not(.store-btn-compact) {
        --dv-badge-w: 216px;
    }
}

/* ── 6. Hero section ────────────────────────────────────────────────────── */
.dv-hero {
    background-color: var(--bs-body-bg);
    padding: 5rem 0 4rem;
    position: relative;
    overflow: hidden;
}

.dv-hero::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--dv-green);
}

.dv-hero-headline {
    font-size: clamp(2rem, 5vw, 3.25rem);
    line-height: 1.15;
    font-weight: 900;
    color: var(--dv-text);
}

.dv-hero-headline span {
    color: var(--dv-green);
}

/* Stat pills */
.dv-stat-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: var(--bs-body-bg);
    border: 1px solid var(--dv-card-border);
    border-radius: 2rem;
    padding: 0.4rem 0.9rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--dv-text);
    box-shadow: var(--dv-card-shadow);
}

.dv-stat-pill .dv-stat-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--dv-green);
    flex-shrink: 0;
}

/* Trust strip */
/* ── Form controls — crisp, app-like visibility in both themes ─────────── */
.form-control,
.form-select,
.input-group-text {
    border-color: rgba(0, 0, 0, 0.45);
    background-color: var(--dv-surface);
    color: var(--dv-text);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--dv-green);
    box-shadow: 0 0 0 0.25rem rgba(0, 168, 90, 0.18);
    background-color: var(--dv-surface);
    color: var(--dv-text);
}

.form-control::placeholder {
    color: var(--dv-text-muted);
    opacity: 0.75;
}

[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select,
[data-bs-theme="dark"] .input-group-text {
    border-color: rgba(255, 255, 255, 0.35);
    background-color: #161616;
}

/* ── Article share row — labelled pills, platform-tinted on hover ──────── */
.dv-share-label {
    display: block;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--dv-text-muted);
    margin-bottom: 0.6rem;
}

.dv-share-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.dv-share-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    border: 1.5px solid var(--dv-card-border);
    background: var(--dv-surface);
    color: var(--dv-text);
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: border-color 0.15s ease, transform 0.15s ease;
    min-height: var(--dv-min-touch);
}

.dv-share-btn i {
    font-size: 1.15rem;
    color: var(--dv-green);
}

[data-bs-theme="dark"] .dv-share-btn i {
    color: var(--dv-green-light);
}

.dv-share-btn:hover {
    transform: translateY(-1px);
    border-color: var(--dv-green);
    color: var(--dv-text);
}

.dv-share-btn--wa:hover { border-color: #25d366; }
.dv-share-btn--wa i { color: #25d366; }
.dv-share-btn--fb:hover { border-color: #1877f2; }
.dv-share-btn--fb i { color: #1877f2; }
.dv-share-btn--x:hover { border-color: var(--dv-text); }
.dv-share-btn--x i { color: var(--dv-text); }
.dv-share-btn--tg:hover { border-color: #229ed9; }
.dv-share-btn--tg i { color: #229ed9; }

[data-bs-theme="dark"] .dv-share-btn--fb i { color: #6ea8ff; }

/* ── Tag badge — readable green on the pale surface in either theme ────── */
.dv-tag-badge {
    background: var(--dv-green-pale);
    color: var(--dv-green-dark);
    font-weight: 600;
}

[data-bs-theme="dark"] .dv-tag-badge {
    color: var(--dv-green-light);
}

/* ── Accessibility: black-on-green buttons (matches the app) + visible
   prose links (never colour-only) ──────────────────────────────────────── */
p a:not(.btn),
.dv-faq-body a,
.dv-article-body a {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ── Brand icon (inline SVG sprite, templates/includes/_icons.html) ────── */
.dv-icon {
    width: 1.25em;
    height: 1.25em;
    vertical-align: -0.22em;
    flex-shrink: 0;
}

.dv-icon--lg {
    width: 2rem;
    height: 2rem;
}

/* ── App-UI fragments (WhatsApp-style cropped showcase pieces) ─────────── */
.dv-frag {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 0.9rem;
    border: 1.5px solid var(--dv-card-border);
    background: var(--dv-surface);
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.10);
}

[data-bs-theme="dark"] .dv-frag {
    box-shadow: 6px 6px 0 rgba(255, 255, 255, 0.06);
}

/* Phones: the collaged stacks read as clutter at 375px — show one straight
   fragment per stack, sized like an app-screenshot chip. */
@media (max-width: 767.98px) {
    .dv-frag-stack {
        max-width: 300px;
    }

    .dv-frag-stack > :nth-child(n+2) {
        display: none;
    }

    .dv-frag--tilt-l,
    .dv-frag--tilt-r {
        transform: none;
    }

    /* Below sm the float squeezes the copy into a column too narrow to read,
       so the icon goes back above it. */
    .dv-about-pillar-icon,
    .dv-teaser-mark {
        float: none;
        margin-bottom: 1rem;
    }
}

/* ── Phone widget: selected-country flag over a compact select ─────────── */
.dv-phone-widget {
    position: relative;
}

.dv-phone-widget .dv-phone-country {
    flex: 0 0 4.6rem;
    max-width: 4.6rem;
    color: transparent; /* the flag overlay is the visible value */
}

.dv-phone-widget .dv-phone-flag {
    position: absolute;
    left: 0.8rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    font-size: 1.15rem;
    line-height: 1;
    pointer-events: none;
}

/* ── Scroll FAB — the app's nudge, on the web ──────────────────────────── */
.dv-scroll-fab {
    position: fixed;
    right: 1.1rem;
    bottom: 1.1rem;
    z-index: 1040;
    width: 40px;
    height: 40px;
    border: 1px solid var(--dv-card-border);
    border-radius: 50%;
    background: rgba(18, 26, 21, 0.78);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--dv-green-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
    cursor: pointer;
    transition: background 0.15s ease, transform 0.15s ease;
}

.dv-scroll-fab:hover {
    transform: translateX(-50%) scale(1.06);
    background: rgba(18, 26, 21, 0.95);
}

.dv-scroll-fab i {
    transition: transform 0.25s ease;
}

.dv-scroll-fab.is-up i {
    transform: rotate(180deg);
}

/* ── Scroll-reveal (progressive: visible without JS; base.html observes) ── */
.dv-reveal--init {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.65s ease, transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
}

.dv-reveal--init.is-in {
    opacity: 1;
    transform: none;
}

.dv-reveal-d1 { transition-delay: 0.08s; }
.dv-reveal-d2 { transition-delay: 0.16s; }
.dv-reveal-d3 { transition-delay: 0.24s; }

/* ── 7. Section spacing ─────────────────────────────────────────────────── */
.section-py {
    padding: 5rem 0;
}

.section-py-sm {
    padding: 3.5rem 0;
}

/* ── 9. Steps (How it works) ────────────────────────────────────────────── */
.dv-steps-section {
    background: var(--dv-surface-alt);
}

.dv-steps-row {
    display: flex;
    align-items: flex-start;
}

.dv-step-item {
    flex: 1;
    min-width: 0;
}

.dv-step-num {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--dv-green);
    color: #fff;
    font-family: var(--dv-font-heading);
    font-size: 1.5rem;
    font-weight: 900;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1.25rem;
}

.dv-step-connector {
    flex: 0 0 2.5rem;
    height: 2px;
    background: linear-gradient(90deg, var(--dv-green), var(--dv-green-light));
    margin-top: 2rem; /* aligns to vertical centre of 64px circle */
    opacity: 0.35;
    align-self: flex-start;
}

@media (max-width: 767px) {
    .dv-steps-row {
        flex-direction: column;
        align-items: center;
        gap: 2rem;
    }

    .dv-step-item {
        width: 100%;
        max-width: 320px;
    }

    .dv-step-connector {
        display: none;
    }
}

/* ── 10. CTA section ────────────────────────────────────────────────────── */
.dv-cta-section {
    background: var(--dv-chrome); /* flat, no gradient */
    color: #fff;
}

.dv-cta-section h2,
.dv-cta-section h3,
.dv-cta-section h4 {
    color: #fff;
}

.dv-cta-section p {
    color: rgba(255, 255, 255, 0.88);
}

/* The white here is for .dv-cta-section's black band, and it was scoped to it
   only by sitting in this block — so the same class on a card (the crop, threat
   and market CTAs) rendered white text on a white card in light mode and the
   link vanished. Scoped properly, with a token-based default everywhere else. */
.dv-cta-section .dv-cta-tertiary,
.dv-cta-section .dv-cta-tertiary:hover {
    color: rgba(255, 255, 255, 0.65);
}

.dv-cta-tertiary,
.dv-cta-tertiary:hover {
    color: var(--dv-text-muted);
}


/* ── 10b. FAQ ───────────────────────────────────────────────────────────── */
.dv-faq-item {
    border: 1px solid var(--dv-card-border) !important;
    border-radius: var(--bs-border-radius-lg) !important;
    margin-bottom: 0.625rem;
    overflow: hidden;
    background: var(--dv-surface);
}

.dv-faq-btn {
    font-weight: 700;
    font-size: 1rem;
    color: var(--dv-text) !important;
    background: var(--dv-surface) !important;
    box-shadow: none !important;
    border: none;
    padding: 1.1rem 1.4rem;
    min-height: 52px;
    display: flex;
    align-items: center;
}

.dv-faq-btn:not(.collapsed) {
    color: var(--dv-green) !important;
    background: var(--dv-surface-alt) !important;
}

/* Override Bootstrap's accordion chevron in both light and dark mode */
.dv-faq-btn::after,
.dv-faq-btn:not(.collapsed)::after,
[data-bs-theme=dark] .dv-faq-btn::after,
[data-bs-theme=dark] .dv-faq-btn:not(.collapsed)::after {
    --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2300A85A'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c%2fsvg%3e");
    --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2300A85A'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c%2fsvg%3e");
}

.dv-faq-body {
    font-size: 1rem;
    color: var(--dv-text);
    line-height: 1.8;
    padding: 0 1.4rem 1.5rem;
    background: var(--dv-surface);
}

/* Deep links (/what-grows/ → /faq/#faq2) target the collapse panel, so the
   browser's fragment scroll parks the question itself behind the sticky navbar.
   Native scroll-margin fixes the landing without any JS scroll-offset maths:
   navbar (~52px) + the question button (~52px) + breathing room. */
.dv-faq-accordion .accordion-collapse {
    scroll-margin-top: 8rem;
}

/* ── 11. Footer ─────────────────────────────────────────────────────────── */
.dv-footer {
    background: var(--dv-chrome); /* same plane as the navbar */
    color: rgba(255, 255, 255, 0.72);
    padding: 3rem 0 1.75rem;
}

.dv-footer-brand {
    font-family: var(--dv-font-heading);
    font-size: 1.2rem;
    font-weight: 800;
    color: #fff !important;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none !important;
}

.dv-footer-brand img {
    width: 30px;
    height: 30px;
    object-fit: contain;
}

.dv-footer a {
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
}

.dv-footer a:hover {
    color: var(--dv-green-light);
}

.dv-footer .dv-footer-divider {
    border-color: rgba(255, 255, 255, 0.1);
    margin: 1.75rem 0 1.25rem;
}

.dv-footer .dv-social-btn {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.08);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.dv-footer .dv-social-btn:hover {
    background: var(--dv-green);
    color: #fff;
}

/* ── 11b. Social share buttons ─────────────────────────────────────────── */
.dv-social-btn {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .5rem 1.1rem;
    border-radius: 2rem;
    font-size: .875rem;
    font-weight: 600;
    border: none;
    color: #fff !important;
    text-decoration: none;
    transition: opacity .15s ease, transform .12s ease;
    white-space: nowrap;
}

.dv-social-btn:hover {
    opacity: .85;
    transform: translateY(-1px);
}

.dv-social-btn i {
    font-size: 1.1rem;
    flex-shrink: 0;
}

.dv-share-card {
    border: 1px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    overflow: hidden;
    box-shadow: var(--dv-card-shadow);
}

.dv-crop-badge {
    background: rgba(0, 168, 90, 0.12);
    color: var(--dv-green);
    border: 1px solid rgba(0, 168, 90, 0.2);
    border-radius: 2rem;
    padding: 0.3em 0.8em;
    font-size: 0.8rem;
    font-weight: 600;
}

[data-bs-theme="dark"] .dv-crop-badge {
    background: rgba(0, 168, 90, 0.18);
    border-color: rgba(0, 168, 90, 0.3);
}

/* ── 13. Error pages ────────────────────────────────────────────────────── */
.dv-error-code {
    font-size: clamp(5rem, 18vw, 9rem);
    font-weight: 900;
    color: var(--dv-green);
    line-height: 1;
    font-family: var(--dv-font-heading);
}

.dv-error-icon {
    font-size: 3.5rem;
    color: var(--dv-green);
    opacity: 0.6;
}

/* ── 14. Contact form ───────────────────────────────────────────────────── */
/* Phone widget: country select capped so the number input gets most space */
.dv-phone-widget .dv-phone-country {
    max-width: 52%;
    flex: 0 0 auto;
}

.dv-phone-widget .dv-phone-dial {
    font-size: 0.9rem;
    min-width: 3.2rem;
    background: var(--dv-surface, #f0f4f1);
    color: var(--dv-green);
    border-color: var(--bs-border-color);
}

.dv-phone-widget .dv-phone-local {
    min-width: 0;
    flex: 1 1 auto;
}

/* ── 15. Article body (blog detail) — mobile-first ──────────────────────── */
.dv-article-body {
    /* Mobile: comfortable 18px reading baseline for rural users */
    font-family: var(--dv-font-body);
    font-size: 1.125rem;
    line-height: 1.95;
    color: var(--dv-text);
    word-break: break-word;
    overflow-wrap: break-word;
}

/* Desktop: bump size + constrain line length for comfortable reading */
@media (min-width: 768px) {
    .dv-article-body {
        font-size: 1.1875rem;
        line-height: 1.9;
        max-width: 72ch; /* ~65–70 characters per line — optimal reading measure */
    }
}

.dv-article-body h2 {
    font-family: var(--dv-font-heading);
    font-size: 1.45rem;
    font-weight: 700;
    margin: 2.5rem 0 0.75rem;
    color: var(--dv-text);
    border-bottom: 2px solid var(--dv-card-border);
    padding-bottom: 0.4rem;
}

@media (min-width: 768px) {
    .dv-article-body h2 {
        font-size: 1.625rem;
    }
}

.dv-article-body h3 {
    font-family: var(--dv-font-heading);
    font-size: 1.2rem;
    font-weight: 600;
    margin: 2rem 0 0.6rem;
    color: var(--dv-green);
}

@media (min-width: 768px) {
    .dv-article-body h3 {
        font-size: 1.35rem;
    }
}

.dv-article-body h4 {
    font-weight: 600;
    font-size: 1.05rem;
    margin: 1.5rem 0 0.4rem;
    color: var(--dv-text);
}

.dv-article-body p {
    margin-bottom: 1.5rem;
}

.dv-article-body ul,
.dv-article-body ol {
    padding-left: 1.5rem;
    margin-bottom: 1.5rem;
}

.dv-article-body li {
    margin-bottom: 0.65rem;
    line-height: 1.8;
}

/* Images: full-width on mobile, constrained + rounded on desktop */
.dv-article-body img {
    max-width: 100%;
    height: auto;
    border-radius: 0.5rem;
    margin: 1.5rem 0;
    display: block;
}

/* Photo credit — the MCP pipeline emits "![…](…)\n*Photo: … / Pexels*" in one
   paragraph (sometimes with a hard <br>), so an <em> straight after an image
   is a caption: pull it up against the image and set it small and muted. */
.dv-article-body img + em,
.dv-article-body img + br + em {
    display: block;
    margin-top: -1.1rem;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--dv-text-muted);
}

.dv-article-body img + br {
    display: none;
}

.dv-article-body blockquote {
    padding: 0.85rem 1.25rem;
    margin: 1.5rem 0;
    background: var(--dv-green-pale);
    border-radius: 0.5rem;
    font-style: italic;
    color: var(--dv-text-muted);
}

.dv-article-body pre {
    background: var(--dv-surface-alt);
    border-radius: 0.5rem;
    padding: 1rem 1.1rem;
    overflow-x: auto;
    margin-bottom: 1.25rem;
    font-size: 0.9rem;
}

.dv-article-body code {
    background: var(--dv-surface-alt);
    padding: 0.15em 0.4em;
    border-radius: 0.25rem;
    font-size: 0.9em;
    color: var(--dv-green-dark);
}

.dv-article-body pre code {
    background: none;
    padding: 0;
    color: var(--dv-text);
}

.dv-article-body strong {
    color: var(--dv-text);
    font-weight: 700;
}

/* Links — visible brand green with accessible underline */
.dv-article-body a {
    color: var(--dv-green);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

.dv-article-body a:hover {
    color: var(--dv-green-dark);
    text-decoration-thickness: 2px;
}

.dv-article-body hr {
    border-color: var(--dv-card-border);
    margin: 2.25rem 0;
}

/* Tables: scrollable on mobile */
.dv-article-body table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1.25rem;
    font-size: 0.9375rem;
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.dv-article-body table th,
.dv-article-body table td {
    padding: 0.65rem 1rem;
    border: 1px solid var(--dv-card-border);
    text-align: left;
    white-space: nowrap;
}

.dv-article-body table th {
    background: var(--dv-surface-alt);
    color: var(--dv-text);
    font-weight: 600;
}

/* ── Dark mode article overrides ────────────────────────────────────────── */
[data-bs-theme="dark"] .dv-article-body a {
    color: var(--dv-green-light);
}

[data-bs-theme="dark"] .dv-article-body a:hover {
    color: #fff;
}

[data-bs-theme="dark"] .dv-article-body blockquote {
    color: var(--dv-text-muted);
}

[data-bs-theme="dark"] .dv-article-body code {
    color: var(--dv-green-light);
}

/* ── Article hero ────────────────────────────────────────────────────────── */
.dv-article-hero {
    min-height: 240px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    position: relative;
}

@media (min-width: 576px) {
    .dv-article-hero {
        min-height: 300px;
    }
}

@media (min-width: 768px) {
    .dv-article-hero {
        min-height: 380px;
    }
}

.dv-article-hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 20%, rgba(0, 0, 0, .55) 70%, rgba(0, 0, 0, .75) 100%);
    pointer-events: none;
}

.dv-article-hero-content {
    position: relative;
    z-index: 1;
    padding: 1.5rem 0;
}

@media (min-width: 768px) {
    .dv-article-hero-content {
        padding: 2rem 0;
    }
}

.dv-article-hero-tag {
    display: inline-block;
    background: rgba(255, 255, 255, .18);
    color: #fff;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .03em;
    padding: .25em .75em;
    border-radius: 999px;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid rgba(255, 255, 255, .22);
    transition: background .15s;
}

.dv-article-hero-tag:hover {
    background: rgba(255, 255, 255, .3);
    color: #fff;
}

.dv-article-hero-title {
    color: #fff;
    font-size: clamp(1.35rem, 4.5vw, 2.35rem);
    font-weight: 800;
    line-height: 1.22;
    text-shadow: 0 2px 10px rgba(0, 0, 0, .4);
    margin: 0;
}

/* Article meta bar icons */
.dv-article-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    font-size: 0.85rem;
    color: var(--dv-text-muted);
    margin-bottom: 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--dv-card-border);
}

/* ═══════════════════════════════════════════════════════════════════════════
   16. About page
   ═══════════════════════════════════════════════════════════════════════════ */

/* Press */
.dv-press-strip {
    background: var(--dv-surface-alt);
}

.dv-press-strip-inner {
    display: grid;
    gap: 1.5rem;
    align-items: center;
    padding: 1.5rem;
    border: 1.5px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    background: var(--dv-surface);
}

.dv-press-strip-intro {
    min-width: 11rem;
}

.dv-press-strip-link {
    color: var(--dv-green);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: .2em;
}

.dv-press-strip-items {
    display: grid;
    gap: .75rem;
}

.dv-press-strip-item {
    position: relative;
    display: block;
    overflow: hidden;
    padding: 0;
    border: 1px solid var(--dv-card-border);
    border-radius: .6rem;
    color: var(--dv-text);
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.dv-press-strip-item:hover,
.dv-press-strip-item:focus-visible {
    border-color: var(--dv-text);
    box-shadow: var(--dv-card-hover-shadow);
    color: var(--dv-text);
}

.dv-press-strip-publication,
.dv-press-strip-title {
    display: -webkit-box;
    min-height: 4.05em;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
}

.dv-press-strip-copy {
    position: relative;
    display: block;
    min-height: 7.5rem;
    padding: 1rem 2rem 1rem 1rem;
}

.dv-press-strip-image,
.dv-press-strip-mark {
    display: block;
    width: 100%;
    height: 8rem;
    border-radius: 0;
}

.dv-press-strip-image {
    object-fit: cover;
}

.dv-press-strip-image--logo {
    padding: 1rem;
    object-fit: contain;
    background: var(--dv-chrome);
}

.dv-press-strip-mark,
.dv-press-card-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--dv-chrome);
    color: var(--dv-green-light);
    font-family: var(--dv-font-heading);
    font-size: 2.5rem;
    font-weight: 900;
}

.dv-press-strip-publication {
    margin-bottom: .25rem;
    color: var(--dv-green);
    font-size: .75rem;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.dv-press-strip-title {
    font-weight: 700;
    line-height: 1.35;
}

.dv-press-strip-arrow {
    position: absolute;
    top: 1rem;
    right: .9rem;
    color: var(--dv-green);
}

.dv-press-hero {
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--dv-card-border);
}

.dv-press-card {
    display: flex;
    flex-direction: column;
    padding: 1.75rem;
    background: var(--dv-surface);
    border: 1.5px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--dv-card-shadow);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.dv-press-card-image,
.dv-press-card-mark {
    display: block;
    width: calc(100% + 3.5rem);
    aspect-ratio: 16 / 8;
    margin: -1.75rem -1.75rem 1.5rem;
    border-radius: var(--bs-border-radius-lg) var(--bs-border-radius-lg) 0 0;
}

.dv-press-card-image {
    object-fit: cover;
}

.dv-press-card-image--logo {
    padding: 2rem;
    object-fit: contain;
    background: var(--dv-chrome);
}

.dv-press-card:hover {
    border-color: var(--dv-text);
    box-shadow: var(--dv-card-hover-shadow);
}

.dv-press-publication {
    color: var(--dv-green);
    font-size: .8rem;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.dv-press-date {
    color: var(--dv-text-muted);
    font-size: .85rem;
}

.dv-press-title {
    font-size: clamp(1.15rem, 2.2vw, 1.4rem);
    line-height: 1.3;
    min-height: 3.9em;
    display: -webkit-box;
    overflow: hidden;
    margin-bottom: .75rem;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
}

.dv-press-summary {
    min-height: 5.1em;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
}

.dv-press-card > a {
    align-self: flex-start;
    margin-top: auto;
}

@media (min-width: 768px) {
    .dv-press-strip-inner {
        grid-template-columns: minmax(11rem, .7fr) minmax(0, 1.3fr);
        padding: 2rem;
    }

    .dv-press-strip-items {
        grid-template-columns: 1fr 1fr;
    }
}

/* Hero */
.dv-about-hero {
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--dv-card-border);
}

/* Problem section */
.dv-about-problem-section {
    background: var(--dv-surface);
}

/* Stat grid */
.dv-about-stat-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.dv-about-stat-card {
    background: var(--dv-surface);
    border: 1.5px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    padding: 1.5rem;
    box-shadow: var(--dv-card-shadow);
}

.dv-about-stat-card--brand {
    background: var(--dv-green);
    border-color: var(--dv-green);
    color: #fff;
}

.dv-about-stat-num {
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    font-weight: 900;
    color: var(--dv-green);
    line-height: 1;
    margin-bottom: 0.4rem;
}

.dv-about-stat-card--brand .dv-about-stat-num {
    color: #fff;
}

.dv-about-stat-label {
    font-size: .85rem;
    color: var(--dv-text-muted);
    line-height: 1.4;
}

.dv-about-stat-card--brand .dv-about-stat-label {
    color: rgba(255, 255, 255, .85);
}

/* Citation link for any figure we publish. Deliberately quiet — a reader
   skimming the claim should not be interrupted, and a reader auditing it
   should find the source attached to the number rather than in a footer
   they have to match up by hand. */
.dv-stat-source {
    display: inline-block;
    margin-top: .3rem;
    font-size: .78rem;
    font-weight: 600;
    color: var(--dv-text-muted);
    text-decoration: underline;
    text-decoration-style: dotted;
    text-underline-offset: .18em;
}

.dv-stat-source::before {
    content: "↗ ";
    text-decoration: none;
}

.dv-stat-source:hover,
.dv-stat-source:focus-visible {
    color: var(--dv-green);
}

.dv-about-stat-card--brand .dv-stat-source {
    color: rgba(255, 255, 255, .85);
}

.dv-stat-footnote {
    margin-top: 1rem;
    margin-bottom: 0;
    font-size: .85rem;
    line-height: 1.7;
    color: var(--dv-text-muted);
}

/* Pillar cards */
.dv-about-pillar-card {
    display: block;
    padding: 1.75rem;
    background: var(--dv-surface);
    border: 1.5px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--dv-card-shadow);
    height: 100%;
    transition: border-color .15s, box-shadow .15s;
}

.dv-about-pillar-card:hover {
    border-color: var(--dv-text);
    box-shadow: var(--dv-card-hover-shadow);
}

/* Contains the floated icon, so a card whose icon is taller than its copy still
   reports the right height to the grid. */
.dv-about-pillar-card::after {
    content: "";
    display: block;
    clear: both;
}

/* Brand mark inside a card — the logo carries its own colour, so it gets no
   tinted tile behind it the way .dv-about-pillar-icon glyphs do. Intrinsic
   width/height on the <img> plus auto height keeps the real aspect ratio. */
.dv-teaser-mark {
    float: left;
    width: 3.5rem;
    height: auto;
    margin: 0 1.25rem .35rem 0;
}

/* Stacked variant: icon (or image) above the text instead of beside it.
   The default row layout reserves a fixed 52px icon column for the full height
   of the card, which is fine in a two-across grid but leaves a tall empty
   gutter once cards get narrow — three-across, or any card carrying a real
   paragraph. Stack those so the text uses the whole width. */
.dv-about-pillar-card--stack {
    /* Kept as the opt-out from the float — see .dv-about-pillar-icon. */
}

.dv-about-pillar-icon {
    float: left;
    width: 52px;
    height: 52px;
    margin: 0 1rem .35rem 0;
    border-radius: .875rem;
    background: var(--dv-green-pale);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: var(--dv-green);
}

/* The stacked variant predates the float and is still right for the cards that
   carry a real image (the SDG tiles): a 320px picture must not be floated. */
.dv-about-pillar-card--stack .dv-about-pillar-icon,
.dv-about-pillar-card--stack .dv-sdg-tile {
    float: none;
    margin: 0 0 1rem;
}

.dv-about-pillar-label {
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--dv-green);
    margin-bottom: .3rem;
}

.dv-about-pillar-title {
    font-size: 1.0625rem;
    font-weight: 800;
    margin-bottom: .5rem;
}

/* Value cards */
.dv-about-value-card {
    padding: 2rem 1.5rem;
    background: var(--dv-surface);
    border: 1.5px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--dv-card-shadow);
    height: 100%;
}

.dv-about-value-icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--dv-green-pale);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: var(--dv-green);
    margin: 0 auto 1.25rem;
}

.dv-about-value-title {
    font-size: 1rem;
    font-weight: 800;
    margin-bottom: .5rem;
}

/* Partnership section */
.dv-about-partner-section {
    background: var(--dv-surface);
}

/* ═══════════════════════════════════════════════════════════════════════════
   17. Features section — revamped pillars layout
   ═══════════════════════════════════════════════════════════════════════════ */

.dv-features-pillar {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 2rem;
    background: var(--dv-surface);
    border: 1.5px solid var(--dv-card-border);
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--dv-card-shadow);
    height: 100%;
    transition: border-color .15s, box-shadow .15s;
}

.dv-features-pillar:hover {
    border-color: var(--dv-text);
    box-shadow: var(--dv-card-hover-shadow);
    transform: none;
}

.dv-features-pillar-icon {
    width: 56px;
    height: 56px;
    border-radius: 1rem;
    background: var(--dv-green-pale);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    color: var(--dv-green);
    flex-shrink: 0;
}

.dv-features-pillar-kicker {
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    /* --dv-green is a background colour (3.1:1 on white); green type always
       goes through the accent token — the same rule .text-brand follows. */
    color: var(--dv-green-accent);
    margin-bottom: .25rem;
}

/* Kicker / eyebrow — the small caps label above a heading. One class, one set
   of metrics: before this existed the same element was restated inline 43
   times in six slightly different sizes. Colour comes from the caller
   (.text-brand for the brand voice, .dv-kicker-muted for group labels). */
.dv-kicker {
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
}

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

/* Long-form prose paragraphs (about, what-is-divisi, partners) — body size with
   a touch more leading than the 1.75 default, for multi-paragraph reading. */
.dv-prose {
    font-size: 1.0625rem;
    line-height: 1.8;
}

.dv-features-pillar h3 {
    font-size: 1.1rem;
    font-weight: 800;
    margin-bottom: .4rem;
    line-height: 1.3;
}

.dv-features-pillar p {
    font-size: 1rem;
    color: var(--dv-gray);
    margin: 0;
    line-height: 1.6;
}

.dv-features-pillar-outcome {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .78rem;
    font-weight: 700;
    color: var(--dv-green);
    margin-top: .75rem;
    padding: .3em .75em;
    background: var(--dv-green-pale);
    border-radius: 999px;
}


/* ── Product showcase rows (device ⇄ copy, zig-zag) ──────────────────────────── */
.dv-showcase-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(1.5rem, 5vw, 4rem);
    align-items: center;
}

.dv-showcase-row + .dv-showcase-row {
    margin-top: clamp(2.5rem, 6vw, 4.5rem);
}

.dv-showcase-row--reverse .dv-showcase-media {
    order: 2;
}

/* Soft brand glow behind the device for depth (best-in-class app showcase look) */
.dv-showcase-media {
    position: relative;
}

.dv-showcase-media::before {
    content: "";
    position: absolute;
    inset: 6% 18%;
    z-index: 0;
    background: radial-gradient(closest-side, rgba(0, 168, 90, .22), transparent 72%);
    filter: blur(26px);
}


.dv-showcase-h {
    font-family: var(--dv-font-heading);
    font-weight: 800;
    font-size: clamp(1.3rem, 2.6vw, 1.8rem);
    margin: .3rem 0 .6rem;
}

@media (max-width: 768px) {
    .dv-showcase-row {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .dv-showcase-media {
        order: -1 !important;
    }

    .dv-showcase-copy .dv-features-pillar-outcome {
        display: inline-flex;
    }
}

/* ── Address typeahead dropdown (shared by /app/ grow form + home teaser) ─────── */
.dv-geo-suggest-wrap {
    position: relative;
}

.dv-geo-suggest {
    margin: .35rem 0 0;
    border: 1px solid var(--bs-border-color);
    border-radius: .6rem;
    overflow: hidden;
    background: var(--dv-surface);
    box-shadow: 0 4px 16px rgba(0, 0, 0, .06);
}

.dv-geo-suggest-item {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    padding: .6rem .8rem;
    font-size: .92rem;
    line-height: 1.35;
    color: var(--dv-text);
    cursor: pointer;
    border-bottom: 1px solid var(--bs-border-color);
}

.dv-geo-suggest li:last-child .dv-geo-suggest-item {
    border-bottom: 0;
}

.dv-geo-suggest-item:hover,
.dv-geo-suggest-item:focus-visible {
    background: var(--dv-green-pale);
    color: var(--dv-green-dark);
    outline: none;
}

.dv-geo-suggest-item i {
    color: var(--dv-green);
    font-size: 1.05rem;
    margin-top: .1rem;
    flex-shrink: 0;
}

[data-bs-theme="dark"] .dv-geo-suggest-item:hover,
[data-bs-theme="dark"] .dv-geo-suggest-item:focus-visible {
    color: var(--dv-green-light);
}

/* ── Focused tool wrap (the /app/ crop tool inside the website chrome) ────────── */
.dv-tool-wrap {
    max-width: 640px;
    margin: 0 auto;
}

/* ── App-download modal (includes/_app_modal.html) ───────────────────────────── */
/* Bootstrap's own modal, re-skinned through its CSS variables rather than by
   overriding its rules — so focus trap, backdrop and scroll lock stay stock. */
.dv-app-modal {
    --bs-modal-bg: var(--dv-surface);
    --bs-modal-color: var(--dv-text);
    --bs-modal-border-color: var(--dv-card-border);
    --bs-modal-border-radius: 1rem;
    --bs-modal-width: 40rem;
    --bs-modal-padding: 1.75rem;
    --bs-modal-header-padding: 1.75rem 1.75rem 0;
}

/* The audience includes farmers with limited eyesight reading on a budget phone
   in daylight, so this dialog is sized like a page, not like a tooltip. */
.dv-app-modal .modal-title {
    font-family: var(--dv-font-heading);
    font-weight: 800;
    font-size: clamp(1.35rem, 3.5vw, 1.75rem);
    line-height: 1.25;
}

.dv-app-modal-lede {
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--dv-text-muted);
    margin: 0.75rem 0 1.25rem;
}

.dv-app-modal-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 1rem;
    font-size: 1.0625rem;
    line-height: 1.55;
    color: var(--dv-text);
}

.dv-app-modal-list li {
    display: flex;
    gap: 0.8rem;
    align-items: flex-start;
}

.dv-app-modal-list i {
    color: var(--dv-green);
    font-size: 1.5rem;
    flex-shrink: 0;
    line-height: 1.3;
}

.dv-app-modal-note {
    font-size: 0.9375rem;
    color: var(--dv-text-muted);
    margin: 1.5rem 0 1rem;
    text-align: center;
}

/* The one line that says what happens next. Sits directly above the buttons so
   the ask and the action are read together. */
.dv-app-modal-action {
    font-family: var(--dv-font-heading);
    font-weight: 800;
    font-size: 1.0625rem;
    color: var(--dv-text);
    text-align: center;
    margin: 1.5rem 0 1rem;
}

.dv-app-modal .btn-close {
    min-width: 44px;
    min-height: 44px;
}

@media (max-width: 575.98px) {
    .dv-app-modal {
        --bs-modal-padding: 1.25rem;
        --bs-modal-header-padding: 1.25rem 1.25rem 0;
    }

    .dv-app-modal-list {
        gap: 0.85rem;
        font-size: 1rem;
    }
}

/* ── Landing pages ────────────────────────────────────────────────────────────
   Shared by every page rendered from website/landings.py. Three components only:
   the pain band, the honesty card, and the enterprise band that used to live in
   an inline <style> on the home page and is now used in two places. */

.dv-pain-band {
    border-top: 1px solid var(--dv-card-border);
    border-bottom: 1px solid var(--dv-card-border);
    background: var(--dv-surface-alt);
}

/* Deliberately set in the heading face at body-copy weight: this paragraph has to
   read as the page speaking rather than as a pull quote decorating it. */
.dv-pain-text {
    font-family: var(--dv-font-heading);
    font-size: clamp(1.1rem, 2.4vw, 1.45rem);
    line-height: 1.5;
    font-weight: 700;
    color: var(--dv-text);
}

/* Plain panel, same border on all four sides as every other card on the site.
   The 4px green stripe down the left was the last of the accent-card family the
   de-clutter pass took out everywhere else, and it made an ordinary paragraph
   read as a warning. */
.dv-honesty-card {
    border: 1.5px solid var(--dv-card-border);
    border-radius: 1rem;
    background: var(--dv-surface);
    padding: 1.5rem 1.75rem;
}

.dv-honesty-label {
    font-family: var(--dv-font-heading);
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-weight: 800;
    color: var(--dv-green-accent);
    margin-bottom: 0.6rem;
}

.dv-enterprise-band {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    border: 1.5px solid var(--dv-card-border);
    border-radius: 1rem;
    background: var(--dv-surface);
    padding: 1.5rem 1.75rem;
}

/* Features menu. The two children (diary, ledger) are indented so the menu reads
   as the hierarchy it is, rather than as nine flat siblings where two happen to
   be about the same thing. */
.dv-nav-dropdown {
    border: 1px solid var(--dv-card-border);
    border-radius: 0.75rem;
    padding: 0.4rem;
}

.dv-nav-dropdown .dropdown-item {
    border-radius: 0.5rem;
    font-weight: 600;
    font-size: 0.94rem;
}

.dv-nav-dropdown .dv-nav-subitem {
    padding-left: 1.9rem;
    font-weight: 500;
    opacity: 0.85;
}

/* The child rows hang off a hairline that stops at the last one, so the group
   reads as belonging to the hub above it. */
.dv-nav-dropdown .dv-nav-subitem::before {
    content: "";
    position: absolute;
    left: 1.1rem;
    top: 0;
    bottom: 0;
    border-left: 1px solid var(--dv-card-border);
}

.dv-nav-dropdown li:has(.dv-nav-subitem) {
    position: relative;
}

/* ── Screenshot collage ───────────────────────────────────────────────────────
   Two or three pieces of real app UI arranged as one composition rather than
   stacked in flow. The rules, in order of how much they matter:

   1. DEPTH. The front card is bigger, sharper and casts a heavier shadow; the
      back card sits behind and away. Without a depth cue two overlapping cards
      read as a mistake.
   2. DIAGONAL. Items travel down-right, which is the direction a reader's eye
      already moves, so the second card is discovered rather than competed with.
   3. DRIFT. Each item breathes on its own long cycle (14–22s, staggered). Slow
      enough that you never catch it moving — you only notice the page is alive.

   All motion is off under prefers-reduced-motion; the composition itself is
   transform-only, so nothing reflows and nothing repaints outside its layer. */

.dv-collage {
    position: relative;
    display: grid;
    place-items: center;
    isolation: isolate;
    max-width: 100%;
}

/* A soft brand-green bloom behind the stack. Sized off the container so it never
   becomes a hard-edged circle on a wide screen. */
.dv-collage-glow {
    position: absolute;
    /* Bleeds vertically only. A negative horizontal inset made the bloom wider
       than its column and put a sliver of horizontal scroll on every landing at
       992px and 1200px — and clip-path does not help, because a clipped element
       still contributes its full box to scrollWidth. The softness comes from the
       gradient and the blur, not from being oversized. */
    inset: -14% 0;
    z-index: 0;
    background: radial-gradient(
        ellipse at 55% 40%,
        var(--dv-bloom-core) 0%,
        var(--dv-bloom-mid) 38%,
        transparent 68%
    );
    filter: blur(14px);
    animation: dv-bloom 19s ease-in-out infinite;
    pointer-events: none;
}

.dv-collage-item {
    position: relative;
    z-index: 1;
    margin: 0;
    animation: dv-drift 16s ease-in-out infinite;
    will-change: transform;
}

.dv-collage-item .dv-frag {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 1rem;
}

/* ── Two items: the classic overlap ──────────────────────────────────────── */
.dv-collage--2 {
    grid-template-columns: 1fr;
    padding: 2.5rem 1rem 3.5rem;
}

.dv-collage--2 .dv-collage-item--1 {
    grid-area: 1 / 1;
    width: 66%;
    justify-self: start;
    align-self: start;
    transform: translate(0, -4%) rotate(-2.4deg);
    z-index: 1;
    filter: saturate(0.92) brightness(0.94);
}

.dv-collage--2 .dv-collage-item--2 {
    grid-area: 1 / 1;
    width: 62%;
    justify-self: end;
    align-self: end;
    transform: translate(0, 10%) rotate(2.2deg);
    z-index: 2;
    animation-delay: -7s;
}

/* ── Three items: a fan, back to front ───────────────────────────────────── */
.dv-collage--3 {
    grid-template-columns: 1fr;
    padding: 4.5rem 1rem 5.5rem;
}

.dv-collage--3 .dv-collage-item {
    grid-area: 1 / 1;
}

.dv-collage--3 .dv-collage-item--1 {
    width: 54%;
    justify-self: start;
    align-self: start;
    transform: translate(0, -30%) rotate(-3deg);
    z-index: 1;
    filter: saturate(0.86) brightness(0.9);
}

.dv-collage--3 .dv-collage-item--2 {
    width: 62%;
    justify-self: end;
    transform: translate(0, 0) rotate(2.4deg);
    z-index: 3;
    animation-delay: -6s;
}

.dv-collage--3 .dv-collage-item--3 {
    width: 50%;
    justify-self: start;
    align-self: end;
    transform: translate(4%, 32%) rotate(-1.6deg);
    z-index: 2;
    animation-delay: -11s;
    filter: saturate(0.94);
}

/* One item needs no arrangement — just presence. */
.dv-collage--1 .dv-collage-item {
    width: 78%;
    transform: rotate(-1.5deg);
}

/* The hero gets more room and a touch more attitude than a body row. */
.dv-collage--hero {
    min-height: 420px;
}

.dv-collage--hero .dv-collage-item--1 { filter: saturate(0.95) brightness(0.96); }

/* Shadows live on the image so they follow the rounded corners, and are heavier
   for the front card — that is most of the depth cue. */
.dv-collage-item--1 .dv-frag { box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45); }
.dv-collage-item--2 .dv-frag { box-shadow: 0 26px 60px rgba(0, 0, 0, 0.55); }
.dv-collage-item--3 .dv-frag { box-shadow: 0 20px 48px rgba(0, 0, 0, 0.5); }

@keyframes dv-drift {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 -10px; }
}

@keyframes dv-bloom {
    0%, 100% { opacity: 0.75; scale: 1; }
    50%      { opacity: 1;    scale: 1.06; }
}

/* Below lg the collage stops overlapping: on a phone there is no room for depth,
   and two cards at 70% width on top of each other is unreadable. */
@media (max-width: 991.98px) {
    .dv-collage {
        display: flex;
        flex-direction: column;
        gap: 1.25rem;
        padding: 0;
    }

    .dv-collage .dv-collage-item {
        width: min(100%, 420px) !important;
        transform: none !important;
        filter: none !important;
        justify-self: center !important;
    }

    .dv-collage-glow { inset: 0; }
}

/* ── "Works with" cards ───────────────────────────────────────────────────── */
.dv-works-section { background: var(--dv-surface-alt); }

.dv-works-card {
    display: block;
    height: 100%;
    position: relative;
    padding: 1.5rem 1.6rem;
    border: 1.5px solid var(--dv-card-border);
    border-radius: 1rem;
    background: var(--dv-surface);
    text-decoration: none;
    transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

.dv-works-card:hover,
.dv-works-card:focus-visible {
    transform: translateY(-4px);
    border-color: var(--dv-green);
    box-shadow: 0 14px 32px rgba(0, 0, 0, 0.28);
}

.dv-works-arrow {
    position: absolute;
    top: 1.4rem;
    right: 1.5rem;
    color: var(--dv-green-accent);
    font-weight: 800;
    transition: transform 0.18s ease;
}

.dv-works-card:hover .dv-works-arrow { transform: translateX(4px); }

.dv-works-title {
    font-family: var(--dv-font-heading);
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--dv-text);
    margin: 0 0 0.5rem;
    padding-right: 1.5rem;
}

.dv-works-why {
    color: var(--dv-text-muted);
    font-size: 0.95rem;
    line-height: 1.55;
    margin: 0;
}

@media (prefers-reduced-motion: reduce) {
    .dv-collage-item,
    .dv-collage-glow { animation: none; }

    .dv-works-card,
    .dv-works-arrow { transition: none; }
}

/* ── Footer store buttons ─────────────────────────────────────────────────────
   Stacked under the social row in the brand column. Capped at the width of that
   column's tagline so the two pills stay button-shaped: `flex: 1 1 0` inside a
   full-width band stretched them to 1200px, which stops reading as a button. */
.dv-footer-stores {
    display: flex;
    flex-direction: column;
    /* No gap: the badges carry their own clear space, and adding a second
       spacing on top of it is what pushed the stacked pair apart. */
    gap: 0;
    max-width: 250px;
}

.dv-footer-stores .store-btn {
    flex: 0 0 auto;
    /* Stretch, so the badge inside can fill the column. The row variant below
       puts this back to content width. */
    align-self: stretch;
}

/* On a phone the brand column is the full width, so cap it a little wider and
   let the two sit side by side when there is room for them. */
@media (min-width: 576px) and (max-width: 767.98px) {
    .dv-footer-stores {
        flex-direction: row;
        max-width: 100%;
    }

    .dv-footer-stores .store-btn {
        align-self: center;
    }
}

/* ── Hero CTA pair ────────────────────────────────────────────────────────────
   The two buttons sit in a half-width column, so at btn-lg with generous padding
   their labels wrapped to two lines inside the pill at every width below xl —
   which reads as a broken button rather than a big one. Keep each label on one
   line and let the PAIR wrap instead, shrinking the type a little where the
   column is tightest. */
.dv-hero-cta .btn {
    white-space: nowrap;
}

@media (min-width: 992px) and (max-width: 1399.98px) {
    .dv-hero-cta .btn {
        font-size: 1rem;
        padding-inline: 1.35rem !important;
    }
}

/* Below sm the column is stacked and full width, so the buttons go full width
   too — a centred pill with air either side looks accidental on a phone. */
@media (max-width: 575.98px) {
    .dv-hero-cta .btn {
        width: 100%;
    }
}

/* ── Signature: field contours ────────────────────────────────────────────────
   The one graphic the site owns (see _contours.html for why). Whisper-quiet by
   design: the lines sit behind the hero at ~10% brand green and draw themselves
   once on load. If a visitor consciously notices them, they are too loud. */

.dv-contours {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
}

/* Content above the lines. .dv-hero already has position:relative + overflow:hidden. */
.dv-hero > .container {
    position: relative;
    z-index: 1;
}

.dv-contour {
    fill: none;
    stroke: var(--dv-contour-stroke);
    stroke-width: 1.5;
    stroke-linecap: round;
    /* Longer than any path; the draw animation pulls it to zero. */
    stroke-dasharray: 2400;
    stroke-dashoffset: 2400;
    animation: dv-contour-draw 2.6s cubic-bezier(0.45, 0, 0.2, 1) forwards;
}

.dv-contour--2 { animation-delay: 0.15s; stroke-opacity: 0.9; }
.dv-contour--3 { animation-delay: 0.3s;  stroke-opacity: 0.8; }
.dv-contour--4 { animation-delay: 0.45s; stroke-opacity: 0.65; }
.dv-contour--5 { animation-delay: 0.6s;  stroke-opacity: 0.5; }

.dv-contour-pin {
    fill: var(--dv-green-accent);
    opacity: 0;
    animation: dv-pin-settle 3s ease-out 2.2s forwards;
}

.dv-contour-pin--2 { animation-delay: 2.7s; }

@keyframes dv-contour-draw {
    to { stroke-dashoffset: 0; }
}

@keyframes dv-pin-settle {
    0%   { opacity: 0; }
    30%  { opacity: 0.85; }
    100% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
    .dv-contour { animation: none; stroke-dashoffset: 0; }
    .dv-contour-pin { animation: none; opacity: 0.45; }
}

/* ── Verdict marks as page punctuation ────────────────────────────────────────
   The app speaks in three marks — ✓ grows well, ~ with care, ✕ not here — and
   the site borrows them as its own quiet system: the pain band is the ✕ (what
   farming without information costs), the honesty card is the ~ (true, with
   care), and the green dots on every promise pill are the ✓. */

.dv-pain-band {
    position: relative;
    overflow: hidden;
}

.dv-pain-band::before {
    content: "✕";
    position: absolute;
    left: 2%;
    top: 50%;
    translate: 0 -50%;
    font-family: var(--dv-font-heading);
    font-size: clamp(6rem, 14vw, 11rem);
    font-weight: 900;
    line-height: 1;
    color: var(--dv-text);
    opacity: 0.045;
    pointer-events: none;
}

/* ── The Apple-grade small stuff ──────────────────────────────────────────────
   The details nobody praises and everybody feels: what text looks like when you
   select it, what a link looks like when you tab to it, the scrollbar on the
   site's own dark ground. */

::selection {
    background: rgba(12, 234, 123, 0.85);
    color: #0b110d;
}

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

@supports (scrollbar-color: auto) {
    html {
        scrollbar-color: rgba(12, 234, 123, 0.35) transparent;
        scrollbar-width: thin;
    }
}

/* ── Footer alignment with the page language ─────────────────────────────── */
.dv-footer {
    border-top: 1px solid rgba(12, 234, 123, 0.18);
}

.dv-footer-h {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--dv-green-light);
    opacity: 0.75;
    margin-bottom: 0.6rem;
}

.dv-footer ul a {
    display: inline-block;
    transition: color 0.15s ease, translate 0.15s ease;
}

.dv-footer ul a:hover {
    translate: 2px 0;
}

/* ── Features menu, in the site's own surface language ───────────────────── */
.dv-nav-dropdown {
    background: #0d130f;
    min-width: 15rem;
    padding: 0.5rem;
    margin-top: 0.4rem;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}

.dv-nav-dropdown .dropdown-item {
    color: rgba(255, 255, 255, 0.78);
    padding-block: 0.45rem;
}

.dv-nav-dropdown .dropdown-item:hover,
.dv-nav-dropdown .dropdown-item:focus-visible {
    color: #fff;
    background: rgba(0, 168, 90, 0.16);
}

.dv-nav-dropdown .dropdown-item.active {
    color: var(--dv-green-light);
    background: transparent;
    font-weight: 700;
}

/* ── Partner pages ──────────────────────────────────────────────────────────
   The /partners/ hub and the four track pages. Everything else on those pages
   reuses the about/landing vocabulary; only these five pieces are new.       */

/* Who this is for — the hero's right-hand panel. Deliberately a plain panel
   rather than another card: it is a qualifier, and a reader who does not see
   themselves in it should be able to skip it in one glance. */
/* Who a track is for — one quiet line under the hero CTAs. It was a bordered
   panel in the hero's right column until that column, and the figure below it,
   were removed for turning the first screen into a wall. */
/* Who a track is for. It sat in the hero until the hero was cut back to the
   hook — a reader deciding whether to apply wants it beside the apply button,
   not before they know what they are applying for. */
.dv-cta-audience {
    font-size: .875rem;
    max-width: 640px;
    margin-top: 1.75rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(255, 255, 255, .22);
    opacity: .8;
}

/* The hub's four routing cards. */
.dv-partner-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--dv-card-border);
    border-radius: 16px;
    background: var(--dv-surface);
    padding: 1.75rem;
    transition: box-shadow .18s ease, transform .18s ease;
}

.dv-partner-card:hover {
    box-shadow: var(--dv-card-hover-shadow);
    transform: translate(-2px, -2px);
}

.dv-partner-card-title {
    font-family: var(--dv-font-heading);
    font-size: 1.35rem;
    font-weight: 800;
    margin-bottom: .5rem;
}

.dv-partner-card-audience {
    font-size: .875rem;
    color: var(--dv-text-muted);
    border-bottom: 1px solid var(--dv-card-border);
    padding-bottom: .875rem;
    margin-bottom: .875rem;
}

/* Pushed to the bottom so four cards of unequal copy still line their buttons up. */
.dv-partner-card-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-top: auto;
    padding-top: .5rem;
}

.dv-partner-card-pdf {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-weight: 600;
    font-size: .9rem;
    color: var(--dv-green-accent);
    text-decoration: none;
}

.dv-partner-card-pdf:hover,
.dv-partner-card-pdf:focus-visible {
    text-decoration: underline;
}

/* The resolution tier label on the access-model cards. */
.dv-partner-tier {
    font-family: var(--dv-font-heading);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--dv-green-accent);
    margin-bottom: .5rem;
}

/* Footer sub-items under Partners, matching the nav dropdown's indent. */
.dv-footer-sub {
    padding-left: .75rem;
    font-size: .9375rem;
    opacity: .85;
}

/* ── Dashboard preview ──────────────────────────────────────────────────────
   The drawn partner dashboard (website/dashboard_svg.py). Light and dark are
   both in the DOM and CSS picks one, the same way the app screenshots do — a
   light product UI in a dark page reads as something pasted on.               */
.dv-dash-figure {
    display: grid;
    gap: 1.25rem;
    max-width: 1000px;
    margin: 0 auto;
}

@media (min-width: 992px) {
    .dv-dash-figure--split {
        grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
        align-items: start;
    }
}

.dv-dash-frame {
    margin: 0;
    border: 1.5px solid var(--dv-card-border);
    border-radius: 1rem;
    overflow: hidden;
    line-height: 0;
}

.dv-dash-frame svg {
    display: block;
    width: 100%;
    height: auto;
}

.dv-dash-dark { display: none; }

[data-bs-theme="dark"] .dv-dash-light { display: none; }
[data-bs-theme="dark"] .dv-dash-dark { display: block; }

/* ── Impact cards ───────────────────────────────────────────────────────────
   Three parts in a fixed order: the pressure, the mechanism that answers it,
   and what the reader gets to do or report. The mechanism is set apart because
   it is the load-bearing sentence — it names a capability that ships.        */
/* Impact, led by the payoff.
   The first cut set mechanism-then-outcome in matched grey and read as a wall —
   correct, and dry enough that nobody finishes it. A reader wants the promise in
   large type and the proof in small type under it, in that order. */
.dv-impact-list {
    display: grid;
    gap: 3.5rem 4.5rem;
}

@media (min-width: 768px) {
    .dv-impact-list {
        grid-template-columns: 1fr 1fr;
    }
}

.dv-impact-row {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0 1.25rem;
    border-top: 2px solid var(--dv-green);
    padding-top: 1.5rem;
}

.dv-impact-n {
    font-family: var(--dv-font-heading);
    font-size: .95rem;
    font-weight: 800;
    color: var(--dv-green-accent);
    letter-spacing: .06em;
    margin: 0;
}

.dv-impact-theme {
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--dv-text-muted);
    margin-bottom: .75rem;
}

/* What they get. The largest thing in the block, because it is the reason to
   keep reading. */
.dv-impact-out {
    font-family: var(--dv-font-heading);
    font-size: 1.3125rem;
    line-height: 1.42;
    font-weight: 800;
    margin-bottom: 1.5rem;
}

/* The proof, in footnote type — it names a capability that ships. */
.dv-impact-mech {
    font-size: .9375rem;
    line-height: 1.75;
    color: var(--dv-text-muted);
    border-top: 1px solid var(--dv-card-border);
    padding-top: 1.25rem;
}

.dv-impact-mech b {
    color: var(--dv-green-accent);
}

/* The audience mark in the hero panel and on the hub cards. */
.dv-partner-mark {
    width: 40px;
    height: 40px;
    color: var(--dv-green-accent);
    margin-bottom: 1rem;
}

.dv-partner-card-head {
    display: flex;
    align-items: center;
    gap: .875rem;
    margin-bottom: .5rem;
}

.dv-partner-card-icon {
    width: 48px;
    height: 48px;
    flex-shrink: 0;
    border-radius: .875rem;
    background: var(--dv-green-pale);
    color: var(--dv-green);
    display: flex;
    align-items: center;
    justify-content: center;
}

.dv-partner-card-head .dv-partner-card-title {
    margin-bottom: 0;
}

/* ── Partner hero extras ────────────────────────────────────────────────────
   The qualifying question under the hero CTAs, and the dashboard side panel
   that sits under the audience card. */
.dv-partner-hook {
    font-size: .9375rem;
    font-weight: 600;
    color: var(--dv-text);
    max-width: 560px;
}

.dv-partner-hook a {
    color: var(--dv-green-accent);
    text-decoration: none;
    white-space: nowrap;
}

.dv-partner-hook a:hover,
.dv-partner-hook a:focus-visible {
    text-decoration: underline;
}


/* ── Partner hero map ───────────────────────────────────────────────────────
   The cohort assembles on landing: each shape fades and settles in turn, keyed
   off --i so the stagger costs one custom property rather than one rule per
   shape. Same restraint as the hero contours — it runs once, it is cheap, and
   under reduced motion every shape is simply already there.                  */
.dv-hero-map {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

.dv-hero-map .dv-map-poly {
    opacity: 0;
    transform: scale(.9);
    transform-origin: center;
    transform-box: fill-box;
    animation: dv-map-settle .5s cubic-bezier(.16, 1, .3, 1) forwards;
    animation-delay: calc(var(--i) * 45ms + 150ms);
}

@keyframes dv-map-settle {
    to {
        opacity: 1;
        transform: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .dv-hero-map .dv-map-poly {
        opacity: 1;
        transform: none;
        animation: none;
    }
}

/* ── Terms ──────────────────────────────────────────────────────────────────
   Pricing, set so it can be scanned: the fact in the heading face, the
   reasoning beneath it. It used to be three paragraphs of body prose, which is
   how the block a prospect most needs to read became the one they skipped.   */
.dv-terms {
    display: grid;
    gap: 2.25rem;
}

.dv-term {
    border-top: 1px solid var(--dv-card-border);
    padding-top: 1.5rem;
}

.dv-term-head {
    font-family: var(--dv-font-heading);
    font-size: 1.1875rem;
    font-weight: 800;
    color: var(--dv-text);
    margin-bottom: .6rem;
}

.dv-term p:last-child {
    font-size: 1rem;
    line-height: 1.75;
}

/* ── Compact download nudge ─────────────────────────────────────────────────
   For pages whose subject is not the app. The full green band is the farmer
   conversion anchor and is far too loud on a partner page, where the reader is
   buying a dashboard rather than installing anything.                        */
.dv-get-line {
    margin: 1.25rem 0 0;
    padding-top: 1rem;
    border-top: 1px solid var(--dv-card-border);
    font-size: .9375rem;
    line-height: 1.7;
}

.dv-get-line a {
    font-weight: 700;
    color: var(--dv-green-accent);
    text-decoration: none;
    margin-right: .5rem;
}

.dv-get-line a:hover,
.dv-get-line a:focus-visible { text-decoration: underline; }

.dv-get-line span { color: var(--dv-text-muted); }

/* Mid-page download nudge, between showcase rows on a feature page. Quiet by
   design: it interrupts an argument the reader is still following, so it reads
   as an offer rather than as the end of the page. */
.dv-inline-cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .75rem 1.5rem;
    /* Generous vertical margin, not decoration: the next showcase row opens with
       a dark rounded screenshot, and with only the section gap between them the
       two cards sat edge to edge — the CTA lost its boundary and its bottom
       button read as clipped. */
    margin: 2.5rem auto 3.5rem;
    padding: 1.25rem 1.5rem;
    max-width: 780px;
    border: 1px solid var(--dv-card-border);
    border-radius: 18px;
    text-align: center;
}

.dv-inline-cta-text {
    margin: 0;
    font-weight: 600;
    color: var(--dv-text-muted);
}

/* The named mechanism. Set like a statement of fact rather than a headline —
   it is doing work with the reader's sceptical half, which distrusts emphasis. */
.dv-mechanism {
    margin: 0;
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--dv-text-muted);
    border-top: 1px solid var(--dv-card-border);
    border-bottom: 1px solid var(--dv-card-border);
    padding: 1.25rem 0;
}

/* Phone-sized hero art. The desktop collage is three overlapping cards in a
   column that does not exist below lg; this is the same idea at the size a
   thumb actually holds — two cards, slight offset, no drift animation. */
/* The hero's 4rem bottom padding plus the next section's 5rem top left 144px of
   nothing between the app cards and the first heading — a fifth of a phone
   screen. Shared by four templates, so the tightening is scoped to the hero that
   actually has cards in it. */
.dv-hero:has(.dv-hero-phone) {
    padding-bottom: 1.5rem;
}

.dv-hero-phone {
    margin-top: 2rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .75rem;
}

.dv-hero-phone-item {
    margin: 0;
    width: min(100%, 340px);
}

.dv-hero-phone-item--offset {
    align-self: flex-end;
    width: min(84%, 290px);
    /* Overlaps enough to read as layered app UI, not enough to cover the yield
       figure on the card behind it — which is the number doing the persuading. */
    margin-top: -1rem;
}

.dv-hero-phone .dv-frag {
    width: 100%;
    height: auto;
    border-radius: 14px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
}

.dv-inline-cta-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: center;
}

/* The compact store buttons are `white-space: nowrap` and flex-shrink to fit,
   so on a phone the two of them sit side by side at 147px each and their labels
   run straight out of the pills. Stack them instead — this is the download,
   on the device the download is for. */
@media (max-width: 480px) {
    .dv-inline-cta-buttons {
        flex-direction: column;
        width: 100%;
    }

    /* Badges have intrinsic width, so they stack rather than stretch. */
    .dv-inline-cta-buttons .store-btn {
        flex: 0 0 auto;
    }
}

/* ── Subscribe card — the PDF gate page and the inline newsletter/calendar
   card share one look. Modern Retro Ink: crisp border, no glow, no lift —
   the same rule dv-kb-cta and the inline-cta card already follow.        */
.dv-subscribe-card input[type="email"],
.dv-subscribe-card input[type="text"] {
    min-height: var(--dv-min-touch);
}

.dv-subscribe-card {
    max-width: 480px;
    margin: 0 auto;
    border: 1.5px solid var(--dv-card-border);
    border-radius: 1rem;
    background: var(--dv-surface);
    padding: 1.75rem;
}

.dv-subscribe-card h1 {
    font-family: var(--dv-font-heading);
    font-weight: 900;
    font-size: 1.75rem;
    margin-bottom: .5rem;
}

.dv-subscribe-sub {
    color: var(--dv-text-muted);
    margin-bottom: 1.5rem;
}

.dv-subscribe-fineprint {
    text-align: center;
    font-size: .82rem;
    color: var(--dv-text-muted);
    margin: .85rem 0 0;
}

/* A checkbox row is the tap target, not just the 1em box inside it — the
   label wraps the input so the whole line is clickable and clears the
   48px minimum without the box itself needing to grow. */
.dv-subscribe-check {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    min-height: var(--dv-min-touch);
    padding: .55rem 0;
    cursor: pointer;
    font-size: .9375rem;
    color: var(--dv-text);
}

/* Plain <input type=checkbox>, not Bootstrap's .form-check-input — that
   class floats itself -1.5em left assuming a .form-check parent's
   padding-left compensates, which this flex layout never provides.
   accent-color is enough on its own for the brand-green checked state on
   every browser these checkboxes need to run on. */
.dv-subscribe-check input {
    width: 1.15em;
    height: 1.15em;
    margin-top: .15rem;
    flex-shrink: 0;
    accent-color: var(--dv-green);
}

.dv-subscribe-check input:focus-visible {
    outline: 2px solid var(--dv-green);
    outline-offset: 2px;
}

/* Inline card — a compact strip a reader who just finished the content
   meets, not the full-page gate. Side by side on desktop; the email field
   grows, the button keeps its own width. */
.dv-subscribe-card--inline {
    max-width: 640px;
    padding: 1.5rem;
    text-align: center;
    /* The card lands directly after prose/chip rows with margin:0 of their
       own — without its own gap it visually collides with them. */
    margin-top: 2.5rem;
    margin-bottom: 2.5rem;
}

/* Two classes, not one — this card lands inside .dv-kb on every place and
   knowledge page (`.dv-kb h2` is a class+type selector, specificity 0-1-1,
   and would otherwise win over a bare single-class rule here and paste the
   prose h2 size onto a card heading half its width). */
.dv-subscribe-card .dv-subscribe-inline-heading {
    font-family: var(--dv-font-heading);
    font-weight: 800;
    font-size: 1.25rem;
    margin: 0 0 .4rem;
}

.dv-subscribe-inline-form {
    max-width: 480px;
    margin: 1rem auto 0;
    text-align: left;
}

.dv-subscribe-inline-row {
    display: flex;
    gap: .6rem;
}

.dv-subscribe-inline-row .form-control {
    flex: 1 1 auto;
    min-width: 0;
}

.dv-subscribe-inline-submit {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Below 480px the button no longer has room beside the email field —
   stack instead of letting the label clip, the same call the compact
   store-button row makes. */
@media (max-width: 480px) {
    .dv-subscribe-inline-row {
        flex-direction: column;
    }

    .dv-subscribe-inline-submit {
        width: 100%;
    }
}

/* The refusal sits above the field it is about, in the card's own voice —
   red-on-surface rather than a full alert block, which at this size reads as
   an error page rather than a correction. */
.dv-subscribe-name-form { margin-top: .25rem; text-align: left; }
.dv-subscribe-name-form label { display: block; margin-bottom: .35rem; }

.dv-subscribe-error {
    margin: 0 0 .75rem;
    font-size: .9375rem;
    line-height: 1.5;
    color: #b3261e;
    text-align: left;
}
[data-bs-theme="dark"] .dv-subscribe-error { color: #ff8a80; }
.dv-subscribe-error i { vertical-align: -2px; margin-right: .15rem; }

.dv-subscribe-card--done {
    text-align: center;
    padding: 1.5rem;
}

/* Two classes: this <p> sits inside .dv-kb on the place/knowledge pages,
   and `.dv-kb p` (specificity 0-1-1) would otherwise beat a bare
   `.dv-subscribe-done` (0-1-0) and paste the prose's muted grey over the
   success colour. */
.dv-subscribe-card .dv-subscribe-done {
    margin: 0;
    font-weight: 700;
    color: var(--dv-green-accent);
}

.dv-subscribe-done i {
    margin-right: .4rem;
    vertical-align: -2px;
}
