/*
Theme Name: Channel-Markers
Author: Forcefield Web Development
Author URI: https://forcefieldnc.com
Version: 1.0
Description: Custom theme for GenVisc 850 / TriVisc — Channel-Markers Medical
*/

/* ── Tokens ── */
:root {
    --brand-green: #78ba31;
    --brand-cyan:  #1cbcd4;
    --brand-blue:  #2c9ed8;
    --brand-grad:  linear-gradient(127deg, #78ba31 0%, #1cbcd4 100%);

    --rule:        #c0bfbf;   /* every hairline in the header/footer */
    --nav-ink:     #a7a9ac;
    --nav-ink-sm:  #999494;
    --drawer-bg:   #1d4354;

    --header-h:          120px;  /* two-row, at top of page */
    --header-h-scrolled:  56px;  /* one-row, after scroll */
    --header-h-mobile:    45px;

    /* Content width and gutters. The header uses these too, so its rules line
       up with the edges of the content below it. */
    --content-max: 1300px;
    --gutter:       30px;
    --section-y:    70px;   /* default vertical rhythm between sections */

    --icon-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h10.5M8.5 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

@media (max-width: 768px) {
    :root { --gutter: 24px; --section-y: 50px; }
}
@media (max-width: 480px) {
    :root { --gutter: 18px; --section-y: 40px; }
}

/* ── Font ──
   Raleway ships as one variable woff2 (100–900), so a single 44KB request
   covers 400/600/700 instead of three statics. `optional` + the preload in
   functions.php: used when it arrives in time, otherwise the fallback is kept
   for that load with no mid-load swap. */
@font-face {
    font-family: 'Raleway';
    src: url('fonts/raleway-var.woff2') format('woff2-variations');
    font-weight: 100 900;
    font-style: normal;
    font-display: optional;
}

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, h4, h5, h6, p, ul, ol, figure, blockquote { margin: 0; padding: 0; }
img, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
ul, ol { list-style: none; }
button, input, select, textarea { font: inherit; }

/* ── Base ── */
html {
    /* No elastic overscroll bounce — it exposes empty space above a fixed
       header. Tradeoff: also disables Chrome-Android pull-to-refresh, which
       is fine for brand/marketing sites; DROP this line for a content/app
       site where users pull to refresh. The background is a fallback for
       browsers that ignore overscroll-behavior — set it to the site's
       header/hero color so any exposed gap blends instead of flashing white. */
    overscroll-behavior-y: none;
    background: #fff;
}

body {
    font-family: 'Raleway', Helvetica, Arial, sans-serif;
    font-size: 16px;
    font-weight: 300;
    line-height: 1.75;
    color: #333;
    background: #fff;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    line-height: 1.2;
    font-weight: 700;
}

h1 { font-size: 2.5rem; }
h2 { font-size: 28px; }
h3 { font-size: 18px; }
h4 { font-size: 1.25rem; }

p + p { margin-top: 1em; }

/* ── Container ── */
.ff-container {
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* Default vertical rhythm for plain (non-flex) page content. */
.entry-content,
.error-404 { padding: var(--section-y) 0; }

/* ══ HEADER ══════════════════════════════════════════════════
   One header element in two states. The two-row → one-row collapse is a
   grid-template-areas swap, not a second markup block — the old Divi build
   shipped three separate fixed headers to do this.

   Top of page:   [trivisc][genvisc]      [channel]
                  [nav ...............................]
   Scrolled:      [trivisc][genvisc][nav ][channel]

   Hero pages sit under a transparent header; non-hero pages get body
   padding-top instead and a white bar. Both go gray once scrolled.
   ═══════════════════════════════════════════════════════════ */

/* The gutter lives on .site-header, not .header-inner, so the background still
   bleeds full width while both horizontal rules span the identical 1300px box
   and line up with each other. */
.site-header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 1000;
    height: var(--header-h);
    padding: 0 var(--gutter);
    background: #fff;
    /* Transparent until scrolled, when the rule moves off .header-inner and
       out to here so it spans the full viewport. */
    border-bottom: 1px solid transparent;
    transition: height .18s ease, background-color .18s ease, border-color .18s ease;
}

/* Transparent over the hero — the background drops out, but both rules stay. */
body.has-hero .site-header { background: transparent; }

/* Opaque, not translucent-with-blur: backdrop-filter forces a compositing
   layer and repaints every scroll frame, and at 95% opacity the blur buys
   nothing visually.
   `body.has-hero` is included so this outranks the transparent rule above —
   without it that selector is more specific and the hero pages' scrolled bar
   stays see-through. */
.site-header.is-scrolled,
body.has-hero .site-header.is-scrolled {
    height: var(--header-h-scrolled);
    background: #f0f0f0;
    border-bottom-color: var(--rule);
}
/* Collapsed state runs its rule edge-to-edge, so the contained one is off. */
.site-header.is-scrolled .header-inner,
body.has-hero .site-header.is-scrolled .header-inner {
    border-bottom-color: transparent;
}

/* align-items: stretch (not center) so the column rules run the full height of
   the row — the divider between the two product logos has to meet the top of
   the viewport and the horizontal rule above the nav, boxing the logos in.
   Each cell centres its own content instead. */
.header-inner {
    height: 100%;
    max-width: 1300px;
    margin: 0 auto;
    border-bottom: 1px solid var(--rule);
    transition: border-color .18s ease;
    display: grid;
    align-items: stretch;
    grid-template-columns: 140px 300px 1fr auto;
    grid-template-rows: 1fr auto;
    grid-template-areas:
        "trivisc genvisc .   channel"
        "nav     nav     nav nav";
}

.site-header.is-scrolled .header-inner {
    grid-template-columns: 110px 145px 1fr auto;
    grid-template-rows: 1fr;
    grid-template-areas: "trivisc genvisc nav channel";
}

/* ── Brand marks ── */
.brand { display: flex; align-items: center; }
.brand img {
    width: auto;
    max-height: 23px;
    transition: max-height .18s ease, opacity .15s ease;
}
.brand:hover img,
.brand:focus-visible img { opacity: .5; }

.brand-trivisc {
    grid-area: trivisc;
    justify-content: flex-end;
    padding-right: 20px;
    border-right: 1px solid var(--rule);
}
.brand-genvisc {
    grid-area: genvisc;
    padding-left: 20px;
}
.brand-channel {
    grid-area: channel;
    justify-content: flex-end;
}
.brand-channel img { max-height: 45px; }

.site-header.is-scrolled .brand img         { max-height: 16px; }
.site-header.is-scrolled .brand-channel img { max-height: 26px; }
.site-header.is-scrolled .brand-genvisc {
    padding-right: 20px;
    border-right: 1px solid var(--rule);
}
.site-header.is-scrolled .brand-channel {
    padding-left: 20px;
    border-left: 1px solid var(--rule);
}

/* ── Nav ── */
.header-nav {
    grid-area: nav;
    display: flex;
    align-items: center;
}

/* This border-top is the horizontal bar the logo divider has to meet — it
   spans all four columns, so the two rules join at the corner. */
/* The lower 12px lives on the items rather than the nav, so each item's box
   reaches the bottom of the header and the dropdown can hang off it directly. */
.site-header:not(.is-scrolled) .header-nav {
    border-top: 1px solid var(--rule);
    padding: 12px 0 0 20px;   /* left indent aligns the nav with the logos */
}
.site-header:not(.is-scrolled) .main-nav > li { padding-bottom: 12px; }
.site-header.is-scrolled .header-nav { padding-left: 30px; }

/* Items stretch to the full nav height so a dropdown opening at top:100% sits
   flush against the header's lower edge with no dead gap for the pointer to
   cross — the usual cause of a submenu closing on the way to it. */
.main-nav {
    display: flex;
    align-items: stretch;
    height: 100%;
    gap: 0 32px;
}
.main-nav > li { display: flex; align-items: center; }

.main-nav a {
    display: block;
    font-weight: 600;
    font-size: 16px;
    line-height: 1.4;
    color: var(--nav-ink);
    text-decoration: none;
    transition: color .15s ease;
}
.main-nav a:hover,
.main-nav a:focus-visible { color: #000; }
/* Active/ancestor state. WordPress puts current-menu-ancestor on the parent
   <li> from the menu hierarchy, so a "#" custom-link parent lights up while a
   child page is open. */
.main-nav .current-menu-item > a,
.main-nav .current-menu-ancestor > a { color: #000; }

.site-header.is-scrolled .main-nav        { gap: 0 24px; }
.site-header.is-scrolled .main-nav a      { font-size: 13px; color: var(--nav-ink-sm); }
.site-header.is-scrolled .main-nav a:hover { color: #000; }
/* Restated for the collapsed state — the rule above is more specific than the
   active-state rule and would otherwise win. */
.site-header.is-scrolled .main-nav .current-menu-item > a,
.site-header.is-scrolled .main-nav .current-menu-ancestor > a { color: #000; }

/* ── Dropdowns ──
   Rebuilt from the old sub-bar.png (240x500) rather than reusing it: a 3px
   accent bar over a 1px rule over a white panel. As CSS it costs no request
   and stays sharp on any display. Measured off the original — grey to 7px,
   cyan 7–15, green 15–23, grey out to 163 of the 240 width. */
.main-nav li { position: relative; }

.main-nav .sub-menu {
    position: absolute;
    top: 100%;
    left: 10px;
    z-index: 10;
    width: 240px;
    padding: 20px 0;
    background: #fff;
    border: 1px solid var(--rule);
    box-shadow: 0 2px 5px rgba(0,0,0,.1);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s ease-in-out, visibility .2s ease-in-out;
}

.main-nav .sub-menu::before {
    content: "";
    position: absolute;
    top: -4px;          /* clears the panel's own 1px top border */
    left: -1px;
    width: 163px;
    height: 3px;
    background: linear-gradient(90deg,
        #6c6e71 0 7px,
        #00bcd5 7px 15px,
        #78ba31 15px 23px,
        #6c6e71 23px 100%);
}

.main-nav li:hover > .sub-menu,
.main-nav li:focus-within > .sub-menu {
    opacity: 1;
    visibility: visible;
}

.main-nav .sub-menu li { display: block; }
.main-nav .sub-menu a {
    padding: 6px 20px;
    font-size: 14px;
    font-weight: 500;
    line-height: 18px;
    color: #3f3f3f;
}
.main-nav .sub-menu a:hover { color: #000; background: #f4f4f4; }

/* Parent items with children are not links in this menu — show intent. */
.main-nav .menu-item-has-children > a { cursor: default; }

/* ── Hamburger ── */
.hamburger {
    grid-area: channel;
    display: none;
    justify-self: end;
    align-self: center;
    width: 28px;
    height: 22px;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
}
.hamburger span {
    display: block;
    height: 2px;
    background: #fff;
    border-radius: 2px;
    transition: transform .2s ease, opacity .2s ease;
}
.hamburger span + span { margin-top: 6px; }
.hamburger.is-active span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.hamburger.is-active span:nth-child(2) { opacity: 0; }
.hamburger.is-active span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* ── Drawer ── */
.mobile-drawer {
    position: fixed;
    top: 0; left: 0;
    z-index: 1200;
    width: 78%;
    max-width: 350px;
    min-width: 300px;
    height: 100%;
    padding: 70px 0 30px;
    background: var(--drawer-bg);
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform .25s ease;
}
.mobile-drawer.is-open { transform: translateX(0); }

.drawer-close {
    position: absolute;
    top: 18px; right: 18px;
    width: 36px; height: 36px;
    background: none;
    border: 0;
    color: #fff;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.drawer-nav a {
    display: block;
    padding: 11px 26px;
    font-size: 15px;
    font-weight: 600;
    color: #fff;
    text-decoration: none;
    border-bottom: 1px solid rgba(255,255,255,.12);
}
.drawer-nav .sub-menu a {
    padding-left: 44px;
    font-size: 13px;
    font-weight: 400;
    color: rgba(255,255,255,.75);
}
.drawer-nav a:hover { background: rgba(255,255,255,.08); }

.drawer-overlay {
    position: fixed;
    inset: 0;
    z-index: 1100;
    background: rgba(0,0,0,.5);
    opacity: 0;
    visibility: hidden;
    transition: opacity .25s ease, visibility .25s ease;
}
.drawer-overlay.is-open { opacity: 1; visibility: visible; }

/* ── Content offset ──
   Hero pages slide under the header; everything else starts below it. */
body.no-hero { padding-top: var(--header-h); }

/* ══ HEADER — mobile ══
   Swaps at 980px, not the usual 768: the full nav runs out of room well
   before tablet width. */
@media (max-width: 980px) {
    /* Logos sit on white; the gradient starts where they end and runs to the
       right edge — same split the Divi build used. */
    .site-header,
    .site-header.is-scrolled,
    body.has-hero .site-header {
        height: var(--header-h-mobile);
        background: #fff;
        border-bottom-color: transparent;
        box-shadow: 0 6px 14px -6px rgba(0,0,0,.35);
    }

    /* The bar carries its own shadow — no rule underneath. */
    .header-inner,
    .site-header.is-scrolled .header-inner,
    body.has-hero .header-inner,
    body.has-hero .site-header.is-scrolled .header-inner {
        border-bottom: 0;
        grid-template-columns: auto auto 1fr;
        grid-template-rows: 1fr;
        grid-template-areas: "trivisc genvisc channel";
    }

    /* Shares the `channel` cell with the hamburger and bleeds past the
       header's right gutter to the viewport edge. */
    .header-inner::after {
        content: "";
        grid-area: channel;
        margin-right: calc(var(--gutter) * -1);
        background: var(--brand-grad);
    }

    .brand img,
    .site-header.is-scrolled .brand img { max-height: 15px; }

    .brand-trivisc,
    .site-header.is-scrolled .brand-trivisc { padding-right: 14px; border-right: 1px solid var(--rule); }
    .brand-genvisc,
    .site-header.is-scrolled .brand-genvisc { padding-left: 14px; padding-right: 14px; border-right: 0; }

    .header-nav,
    .brand-channel { display: none; }

    .hamburger { display: block; position: relative; z-index: 1; }

    body.no-hero { padding-top: var(--header-h-mobile); }
}

/* ══ HERO — video ══════════════════════════════════════════
   Full viewport, header sits transparent on top of it. The copy is pushed
   down by the header height rather than the section starting below it.
   ═══════════════════════════════════════════════════════════ */

.hero-video {
    position: relative;
    display: flex;
    align-items: flex-start;
    height: 100vh;
    height: 100svh;      /* svh: no jump when mobile browser chrome hides */
    min-height: 520px;
    padding-top: var(--header-h);
    overflow: hidden;
    background: #1d4354; /* covers the gap before the poster paints */
}

.hero-video__poster,
.hero-video__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}

/* Video sits over the poster once it has frames to show. */
.hero-video__media {
    z-index: 1;
    opacity: 0;
    transition: opacity .4s ease;
}
.hero-video__media.is-playing { opacity: 1; }

/* No scrim — the video plays at full brightness. Legibility of the white copy
   rests on the text-shadow below. */

/* Section already carries padding-top: var(--header-h); the 80px here lands
   the copy ~200px from the top of the viewport, matching the original. */
.hero-video__inner {
    position: relative;
    z-index: 3;
    width: 100%;
    max-width: calc(1100px + 110px);
    margin: 0 auto;
    padding: 80px var(--gutter) 0 110px;
}

.hero-video__title {
    margin: 0;
    font-weight: 300;
    font-size: clamp(30px, 4.6vw, 60px);
    line-height: 1.1;
    color: #fff;
    text-shadow: 0 1px 12px rgba(0,0,0,.35);
}

/* 980, matching the header swap — above this the header is still the tall
   two-row version and the hero has to pad for it. */
@media (max-width: 980px) {
    .hero-video {
        min-height: 420px;
        padding-top: var(--header-h-mobile);
        align-items: center;
    }
    .hero-video__inner { padding: 0 var(--gutter); }
    /* Scales off viewport width rather than the desktop clamp, whose 30px
       floor left the copy tiny on a phone. */
    .hero-video__title { font-size: clamp(38px, 11vw, 62px); }
}

/* No autoplaying background motion for anyone who asked not to see it. The
   poster carries the hero instead; main.js also skips attaching the source. */
@media (prefers-reduced-motion: reduce) {
    .hero-video__media { display: none; }
}

/* ══ WP ADMIN BAR ══════════════════════════════════════════
   WordPress pushes the document down with html { margin-top }, which handles
   normal flow — but anything fixed or sized to the viewport still needs the
   offset applied by hand. Body padding is unaffected: it's measured from the
   top of <body>, which has already moved.
   ═══════════════════════════════════════════════════════════ */

body.admin-bar .site-header    { top: 32px; }
body.admin-bar .mobile-drawer  { top: 32px; height: calc(100% - 32px); }
body.admin-bar .hero-video {
    height: calc(100vh - 32px);
    height: calc(100svh - 32px);
}

@media screen and (max-width: 782px) {
    body.admin-bar .site-header   { top: 46px; }
    body.admin-bar .mobile-drawer { top: 46px; height: calc(100% - 46px); }
    body.admin-bar .hero-video {
        height: calc(100vh - 46px);
        height: calc(100svh - 46px);
    }
}

/* Under 600px the admin bar switches to position: absolute and scrolls away
   with the page, so a fixed offset would leave a permanent gap. */
@media screen and (max-width: 600px) {
    body.admin-bar .site-header   { top: 0; }
    body.admin-bar .mobile-drawer { top: 0; height: 100%; }
}

/* ══ ACF SECTIONS ══════════════════════════════════════════
   Every layout carries the same two selectors. They resolve to custom
   properties rather than concrete values, so a new colour or size is a token
   here — no per-layout CSS and no template change.
   ═══════════════════════════════════════════════════════════ */

.ff-section {
    --emphasis:     var(--brand-green);
    --body-size:    16px;
    --body-weight:  300;
    --body-leading: 1.75;
    padding: var(--section-y) 0;
    font-size: var(--body-size);
    font-weight: var(--body-weight);
    line-height: var(--body-leading);
}

.ff-section.emph-green     { --emphasis: var(--brand-green); }
.ff-section.emph-turquoise { --emphasis: var(--brand-cyan); }
.ff-section.emph-blue      { --emphasis: var(--brand-blue); }

/* Tighter leading — the bigger the type, the less space lines need between
   them to stay grouped. */
.ff-section.text-lg { --body-size: 24px; --body-leading: 1.45; }
/* 400 at this size — 300 goes thin and washed out at 16px in a long column. */
.ff-section.text-md { --body-size: 16px; --body-weight: 400; }
.ff-section.text-sm { --body-size: 14px; }

/* Consecutive sections shouldn't double their gap. */
.ff-section + .ff-section { padding-top: 0; }

/* `header-only` — a section carrying just a heading that introduces the one
   below it. It needs the normal rhythm above (the rule overhead would
   otherwise leave it touching the previous section) and much less below, so it
   reads as attached to what it introduces rather than floating between the
   two. The compound selector outranks the adjacent-sibling rule above. */
.ff-section.header-only,
.ff-section + .ff-section.header-only {
    padding-top: var(--section-y);
    padding-bottom: 18px;
}

/* Without a hero, body padding already clears the fixed header — the section's
   own full rhythm on top of that leaves too big a gap, so halve it. */
body.no-hero #main > .ff-section:first-child,
body.no-hero .entry-content { padding-top: calc(var(--section-y) / 2); }

/* ── Hero section ──
   Full viewport, copy in the right half of a notional 50/50. Below 980 the
   copy moves onto a translucent card centred in the frame — matching where the
   header switches to its mobile bar.
   ═══════════════════════════════════════════════════════════ */
.ff-section--hero,
.ff-section + .ff-section--hero {
    position: relative;
    display: flex;
    align-items: center;
    height: 100vh;
    height: 100svh;
    min-height: 520px;
    padding: 0;
    overflow: hidden;
}

/* Only pad for the header when the hero is what sits under it. */
#main > .ff-section--hero:first-child { padding-top: var(--header-h); }

.ff-hero__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}

.ff-hero__inner {
    position: relative;
    z-index: 1;
}

.ff-hero__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 50px;
}
.ff-hero__body { grid-column: 2; }

@media (max-width: 980px) {
    #main > .ff-section--hero:first-child { padding-top: var(--header-h-mobile); }

    .ff-hero__grid { grid-template-columns: 1fr; }
    .ff-hero__body {
        grid-column: 1;
        max-width: 520px;
        margin: 0 auto;
        padding: 28px;
        background: rgba(255, 255, 255, .85);
        border-radius: 4px;
    }
}

/* ── Accordion / FAQ ──
   Closed: brand gradient. Open: the whole box goes flat #2c9ed8.
   ═══════════════════════════════════════════════════════════ */
.ff-accordion__item {
    margin-bottom: 8px;
    background-image: var(--brand-grad);
    color: #fff;
}
.ff-accordion__item[open] {
    background-image: none;
    background-color: var(--brand-blue);
}

.ff-accordion__title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 14px 20px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.35;
    cursor: pointer;
    list-style: none;   /* Firefox's default triangle */
}
.ff-accordion__title::-webkit-details-marker { display: none; }
.ff-accordion__title:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

/* Plus in a circle, drawn from two gradient bars so it inherits currentColor.
   Open state drops the vertical bar, leaving a minus. */
.ff-accordion__title::after {
    content: "";
    flex: none;
    width: 22px;
    height: 22px;
    border: 1px solid currentColor;
    border-radius: 50%;
    background:
        linear-gradient(currentColor, currentColor) center / 10px 2px no-repeat,
        linear-gradient(currentColor, currentColor) center / 2px 10px no-repeat;
}
.ff-accordion__item[open] .ff-accordion__title::after {
    background: linear-gradient(currentColor, currentColor) center / 10px 2px no-repeat;
}

.ff-accordion__body { padding: 0 20px 18px; }

/* Everything inside an accordion is white, full stop. The gradient and the
   open blue both need it, and pasted editor content arrives with its own inline
   colours — hence the blanket selector and !important. Scoped to .ff-accordion,
   so it can't reach anything else. */
.ff-accordion,
.ff-accordion * { color: #fff !important; }

.ff-accordion__body a { text-decoration: underline; }

/* ── Banner ──
   Full-bleed gradient with the dot motif sitting behind copy that stays
   contained. The padding is restated for the adjacent-sibling case so a banner
   following another section still gets its full band height. */
.ff-section--banner,
.ff-section + .ff-section--banner {
    padding: 45px 0;
    /* Two layers, dots over gradient — both on the full-bleed section so the
       motif sits against the viewport edge, not the 1300px container edge. */
    background-image: url('img/footer-dots.webp'), var(--brand-grad);
    background-size: initial, cover;
    background-position: left center, center;
    background-repeat: no-repeat, no-repeat;
}

.ff-banner__text {
    color: #fff;
    font-size: 41px;
    font-weight: 600;
    line-height: 1.2;
    text-align: right;
}
/* wp_autop wraps the editor output — strip the stray outer margins. */
.ff-banner__text p { margin: 0; }
.ff-banner__text p + p { margin-top: .3em; }
.ff-banner__text sup { font-size: .45em; vertical-align: super; line-height: 0; }

@media (max-width: 768px) {
    .ff-section--banner,
    .ff-section + .ff-section--banner { padding: 32px 0; }
    .ff-banner__text { font-size: 28px; }
    /* 355px of dots behind 28px type leaves the copy unreadable on a phone. */
    .ff-section--banner,
    .ff-section + .ff-section--banner { background-image: var(--brand-grad); }
}

/* ── Two column (50/50) ── */
.ff-cols {
    --col-gap: 50px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--col-gap);
    align-items: start;
}

/* The image runs to the centre line and the right column starts half a gap
   past it, so the visible space between artwork and copy is --col-gap / 2.
   80 here gives 40px of daylight. */
.ff-cols--bleed { --col-gap: 80px; }

.ff-col { position: relative; }

/* Fills the column like a cover background, but as a real <img> so it gets
   srcset and lazy loading. */
.ff-col__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* The reset's img { max-width: 100% } is relative to the column, so it
       clamps the bleed back to the column width. */
    max-width: none;
    object-fit: cover;
    z-index: 0;
}
.ff-col__body { position: relative; z-index: 1; }

/* A column that's only an image has no content to give it height. */
.ff-col--has-bg {
    align-self: stretch;
    min-height: 340px;
}
.ff-col--has-bg .ff-col__body { padding: 32px; }

/* Bleed the image out to the viewport's left edge while its right edge stays
   on the grid line and the copy stays contained. The offset is the distance
   from the container's content edge back to the viewport: half the leftover
   space either side, plus the gutter. Below --content-max that resolves to
   just the gutter, which is exactly right. */
.ff-col--bleed .ff-col__bg {
    /* Distance from the column's left edge out to the viewport's. */
    --bleed: calc((100vw - min(100vw, var(--content-max))) / 2 + var(--gutter));

    left: calc(-1 * var(--bleed));
    right: auto;
    /* Explicit width, not auto: on a replaced element width:auto resolves to
       the image's intrinsic size, so a left/right pair can't size an <img>.
       100% is the column; + half the gap lands it on the true 50/50 line. */
    width: calc(100% + var(--bleed) + var(--col-gap) / 2);
}

/* 100vw counts the scrollbar, so the bleed would otherwise push the page a few
   pixels wide on Windows. `clip` rather than `hidden` — it doesn't create a
   scroll container. */
.ff-section--two-col {
    overflow-x: hidden;
    overflow-x: clip;
}

@media (max-width: 768px) {
    .ff-cols { --col-gap: 32px; grid-template-columns: 1fr; }
    .ff-col--has-bg { min-height: 240px; }
    /* Stacked — nothing sits beside it, so it bleeds both edges. */
    .ff-col--bleed .ff-col__bg {
        width: calc(100% + var(--bleed) * 2);
    }
}

/* ── Rich text ──
   The global reset strips list markers and margins, which is right for chrome
   and wrong for editor output — restored here, scoped to WYSIWYG content. */
.ff-rte h1,
.ff-rte h2,
.ff-rte h3,
.ff-rte h4 { color: var(--emphasis); }

.ff-rte h1 { font-size: 50px; font-weight: 300; }

/* Eyebrow — works on a heading itself (<h1 class="eyebrow">) or on a span
   inside one, so the H1 can stay the page's real subject while the small
   kicker sits above it. display:block gives it its own line either way. */
/* block + fit-content: takes its own line like a heading would, but the pill
   only ever wraps the text rather than stretching the full column. */
.ff-rte .eyebrow {
    display: block;
    width: fit-content;
    margin: 0 0 .8em;
    padding: 6px 16px;
    background: var(--emphasis);
    border-radius: 999px;
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: .1em;
    text-transform: uppercase;
}
.ff-rte .eyebrow:last-child { margin-bottom: 0; }

.ff-rte h2 { margin: 1.4em 0 .5em; }
.ff-rte h3 { margin: 1.3em 0 .4em; }
.ff-rte h2:first-child,
.ff-rte h3:first-child { margin-top: 0; }

.ff-rte p { margin-bottom: 1em; }
.ff-rte p:last-child { margin-bottom: 0; }

.ff-rte ul,
.ff-rte ol {
    list-style: revert;
    margin: 1em 0;
    padding-left: 1.4em;
}
.ff-rte li { margin-bottom: .4em; }

.ff-rte a {
    color: var(--emphasis);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.ff-rte a:hover { text-decoration: none; }

/* ── Arrow link ──
   Replaces the ETmodules "$" glyph the Divi build used as a download marker.
   Drawn with a mask rather than an <img> so the arrow takes currentColor and
   follows the section's emphasis colour for free. */
a.arrow,
.ff-rte a.arrow {
    display: inline-flex;
    align-items: center;
    gap: .45em;
    font-weight: 600;
    text-decoration: none;
}
a.arrow::before,
.ff-rte a.arrow::before {
    content: "";
    flex: none;
    width: .9em;
    height: .9em;
    background: currentColor;
    transition: transform .15s ease;
    -webkit-mask: var(--icon-arrow) center / contain no-repeat;
            mask: var(--icon-arrow) center / contain no-repeat;
}
a.arrow:hover::before,
.ff-rte a.arrow:hover::before { transform: translateX(3px); }

a.arrow:hover,
.ff-rte a.arrow:hover { text-decoration: none; }

/* Footnote markers run all through this content — one size, not the five the
   old child theme ended up with. */
.ff-rte sup {
    font-size: .65em;
    vertical-align: super;
    line-height: 0;
}

.ff-rte img { margin: 1em 0; }

.ff-rte table { width: 100%; border-collapse: collapse; margin: 1em 0; }
.ff-rte td,
.ff-rte th { padding: 8px 10px; border-top: 1px solid #eee; text-align: left; }

/* ══ FOOTER ════════════════════════════════════════════════
   Stacked bands, each separated by the same hairline used in the header.
   Every rule is contained to --content-max rather than bleeding.
   ═══════════════════════════════════════════════════════════ */

.site-footer {
    /* Lighter than --rule: the footer carries far more hairlines than the
       header, and at #c0bfbf the logo grid reads as a heavy table. */
    --footer-rule: #dcdcdc;
    /* Own token rather than --rule: the copy needs more contrast than a
       hairline does, and the two shouldn't move together. */
    --footer-ink: #8f8e8e;

    margin-top: var(--section-y);
    color: var(--footer-ink);
    font-size: 12px;
    line-height: 1.6;
}

/* ── Logo row: 1/5 · 1/5 · 3/5, matching the original ── */
/* stretch, not center — otherwise each cell is only as tall as its logo and the
   vertical rules stop short of the horizontal ones instead of meeting them. */
.footer-brands {
    display: grid;
    grid-template-columns: 1fr 1fr 3fr;
    align-items: stretch;
    border-top: 1px solid var(--footer-rule);
    border-bottom: 1px solid var(--footer-rule);
}
.footer-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px 15px;
}
.footer-brand:not(:last-child) { border-right: 1px solid var(--footer-rule); }
.footer-brand img {
    width: auto;
    max-height: 10px;
    transition: opacity .15s ease;
}
/* Two lines of type at 10px would be unreadable — this mark gets its own size. */
.footer-brand--channel {
    justify-content: flex-end;
    padding-right: 0;
}
.footer-brand--channel img { max-height: 26px; }
.footer-brand:hover img { opacity: .5; }

/* ── Contact / disclaimer bands ── */
.footer-contact,
.footer-disclaimer {
    padding: 18px 0;
    border-bottom: 1px solid var(--footer-rule);
}
/* Logo grid already draws its own lower rule. */
.footer-brands + .footer-contact { border-top: 0; }
.footer-contact p,
.footer-disclaimer p { margin: 0 0 4px; }
.footer-contact p:last-child,
.footer-disclaimer p:last-child { margin-bottom: 0; }

.footer-disclaimer { font-size: 11px; line-height: 1.4; }
.footer-copyright { margin-top: 10px; }

.footer-contact a { color: var(--brand-blue); text-decoration: none; }
.footer-contact a:hover { text-decoration: underline; }

/* ── Legal links ── */
.footer-legal { padding: 16px 0 40px; }
.legal-menu {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 0;
    font-size: 12px;
}
.legal-menu li:not(:last-child)::after {
    content: "|";
    margin: 0 8px;
    color: var(--rule);
}
.legal-menu li { display: flex; }
.legal-menu a {
    color: var(--brand-blue);
    text-decoration: none;
}
.legal-menu a:hover { text-decoration: underline; }

/* Sits outside .ff-container, so it repeats the container's own sizing. */
.ff-credit {
    display: block;
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 0 var(--gutter) 12px;
    text-align: right;
    font-size: 9px;
    color: #ccc;
    text-decoration: none;
    letter-spacing: .5px;
}

@media (max-width: 768px) {
    .footer-brands {
        grid-template-columns: 1fr 1fr;
    }
    .footer-brand--channel {
        grid-column: 1 / -1;
        border-top: 1px solid var(--footer-rule);
        border-right: 0;
    }

}

/* ── Buttons ── */
.ff-btn {
    display: inline-block;
    padding: 12px 28px;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
}

.ff-btn-primary {
    background: #333;
    color: #fff;
}

.ff-btn-primary:hover {
    background: #111;
}

.ff-btn-outline {
    background: transparent;
    border: 2px solid #333;
    color: #333;
}

.ff-btn-outline:hover {
    background: #333;
    color: #fff;
}

/* ── Gradient pill ──
   Applied to links from the editor's Formats menu, so the .ff-rte selector is
   included to beat that block's underline and emphasis colour.
   Note the 123deg here vs 127deg on --brand-grad elsewhere — as specified. */
a.grad-pill,
.ff-rte a.grad-pill {
    display: inline-block;
    padding: 12px 34px;
    border: 1px solid #fff;
    border-radius: 36px;
    background-image: linear-gradient(123deg, #78ba31 0%, #1cbcd4 100%);
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    line-height: 1.3;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: opacity .15s ease;
}
a.grad-pill:hover,
.ff-rte a.grad-pill:hover {
    color: #fff;
    text-decoration: none;
    opacity: .85;
}

/* ── Skip Link ── */
.ff-skip-link {
    clip: rect(1px, 1px, 1px, 1px);
    position: absolute;
    height: 1px;
    width: 1px;
    overflow: hidden;
    word-wrap: normal;
}
.ff-skip-link:focus {
    clip: auto;
    display: block;
    height: auto;
    width: auto;
    position: fixed;
    top: 10px;
    left: 10px;
    z-index: 100000;
    padding: 15px 23px;
    background: #fff;
    color: #000;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 0 2px 2px rgba(0,0,0,.6);
}

/* ── Accessibility ── */
.screen-reader-text {
    clip: rect(1px, 1px, 1px, 1px);
    position: absolute;
    height: 1px;
    width: 1px;
    overflow: hidden;
    word-wrap: normal;
}

/* Self-hosted font template. Use font-display: optional (NOT swap) together
   with a <link rel="preload"> in functions.php: the preloaded font is used
   when it's ready in time, otherwise the fallback is kept for that load with
   no swap — so the web font never reflows big headings (hero CLS). */
/*@font-face {
    font-family: 'YourFont';
    src: url('fonts/yourfont.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: optional;
}*/

/* ── Responsive ── */
@media (max-width: 1200px) {
}

@media (max-width: 768px) {
    h1 { font-size: 2rem; }
    h2 { font-size: 24px; }
    /* h3 stays 18px — it's already small enough to be a run-in label. */

    /* .ff-rte h1 outranks the bare h1 above, so it needs its own steps. */
    .ff-rte h1 { font-size: 36px; }
}

@media (max-width: 480px) {
    h1 { font-size: 1.75rem; }
    h2 { font-size: 22px; }
    .ff-rte h1 { font-size: 30px; }
}
