/* Relegia Holdings — global styles
   Token reference matches the tailwind config in includes/head.php.
   Tailwind utilities cover most styling; this file holds the bits
   utilities can't express: design tokens, buttons, header/hero/cards,
   forms, footer. See design-system.html for a live component reference.
   Brand: deep-blue headings (#1A199F), yellow accent (#F5D51A), black body text. */

:root {
    --cream:      #E3E5F4; /* blue-grey — page background (fades to white at the top) */
    --cream-soft: #FFFFFF; /* content panels / cards */
    --surface-2:  #F1F3FA; /* soft tinted surface for cards sitting on a white panel */
    --page-fade:  1100px;  /* how far the white top fade reaches down the page */
    /* Text ramp on light surfaces — ONE blue axis, three steps only, running
       from the brand blue down to the pale blue-grey. No black, no neutral grey:
       every piece of type on white is --ink, --muted or --faint.
         --ink   strong: headings, links, emphasis, labels on gold
         --muted body copy (a mid step; --faint is too pale to read at 16px)
         --faint quiet: eyebrows, field labels, captions, list titles */
    --ink:        #1A199F; /* strong text — same blue as the headings */
    --muted:      #666C7E; /* body / supporting copy — desaturated, so long
                              paragraphs read as grey rather than as blue type */
    --faint:      #98A0BA; /* pale blue-grey — quiet labels and titles */
    --accent:     #1A199F; /* deep blue — links, secondary icons */
    /* Deep-blue brand gradient (the hero .ph-brand gamma), with a soft blue glow —
       for LARGE dark blocks/bands where the radial reads as depth, not a blotch. */
    --brand-gradient:
        radial-gradient(38% 46% at 82% 28%, rgba(82,96,238,0.45) 0%, rgba(82,96,238,0) 62%),
        radial-gradient(125% 135% at 0% 0%, #3B39B0 0%, #1A1942 48%, #0E0D26 100%);
    /* Deep blue for SMALL surfaces (buttons, icon tiles) — pulled toward the
       hero .ph-brand gamma so it reads clearly blue (not grey-black), with a
       very subtle top-to-bottom gradient (no radial spots). */
    --brand-deep: linear-gradient(155deg, #322FA6 0%, #201E78 100%);
    --brand:      #1A199F; /* deep blue — display headings, primary buttons, header outline */
    --gold:       #F5D51A; /* yellow accent — icons, accent buttons, nav underline, CTAs */
    --gold-soft:  #FBE96A; /* lighter yellow — hover sweep layer */
    --heading:    var(--brand); /* deep blue — display headings on light surfaces */

    /* Inset "framed" layout: large blocks sit a small gap in from the page
       edges with a big radius, so the light background frames them. */
    --inset:        clamp(18px, 2.8vw, 34px);
    /* The header keeps a tighter gap above it than the block inset — at the full
       --inset the nav bar floats too far off the top edge. */
    --inset-top:    clamp(10px, 1.1vw, 14px);
    --block-radius: 16px;
    --header-h:     64px; /* nav bar height — matches h-16 (md:h-20 below) */
}

@media (min-width: 768px) {
    :root { --header-h: 80px; }
}

html { scroll-behavior: smooth; }
/* Body copy runs light (Archivo 300). Paired with the desaturated --muted it
   keeps long paragraphs quiet next to the serif headings. Scoped to the utility
   the pages actually use for prose, so buttons/labels keep their own weights.
   :where() keeps the specificity at zero, so .eyebrow and any font-* utility
   in the markup still win. */
:where(.text-muted,
       .legal-prose p,
       .legal-prose li,
       .hero-full__content p,
       .media-band__content p,
       .dark-band p) { font-weight: 300; }
/* Page background: a blue-grey tint that fades up into white at the top of the
   document, so the first screen reads light and the tint builds as you scroll.
   The fade ends in transparent WHITE (not the `transparent` keyword) so it
   doesn't dip through grey on the way out. */
body {
    background-color: var(--cream);
    background-image: linear-gradient(180deg, #FFFFFF 0, rgba(255,255,255,0) var(--page-fade));
    background-repeat: no-repeat;
}

/* Display heading: Archivo — a dense, high-contrast-in-weight modern grotesque.
   Set in sentence case at 800 with tight negative tracking and sub-1 leading,
   so the type itself carries the page's visual weight. */
.display {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 800;
    text-transform: none;
    letter-spacing: -0.03em;
    line-height: 0.96;
    text-wrap: balance; /* even line lengths on the big multi-line headings */
}
/* Page and section headings (h1/h2 only) run in Noto Serif — a low-contrast,
   even-colour text serif, held at 400 so the big sizes stay light rather than
   heavy. Everything below h2 stays on Archivo. */
h1.display, h2.display {
    font-family: 'Noto Serif', 'Georgia', serif;
    font-weight: 400;
    letter-spacing: -0.02em;
    line-height: 1.1;
}
/* Optical correction: the tight tracking/leading above is tuned for the large
   sizes. Small headings (card titles, list rows) need it dialled back — and at
   these sizes a heavy Archivo reads as an overweight blot, so the whole h3 tier
   runs at a medium 500 with near-normal tracking, one step up in size (1.5rem
   across the board) to carry the lighter weight. */
h3.display, h4.display, .display--sm {
    font-weight: 500;
    letter-spacing: -0.005em;
    line-height: 1.25;
    text-wrap: pretty;
}
.display em {
    font-style: normal;
    font-family: inherit;
    font-weight: inherit;
}
/* Brand deep-blue for headings on light surfaces; the element selector keeps this
   above Tailwind's text-ink utility. Headings inside dark photo blocks stay
   white (higher-specificity context override below). */
h1.display, h2.display, h3.display { color: var(--heading); }
.hero-full .display,
.card-bg .display,
.media-band .display,
.dark-band .display { color: #fff; }

/* Rounded-rectangle buttons with an inline arrow */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.9rem 1.5rem;
    border-radius: 12px;
    /* One label treatment for EVERY button — caps, no tracking, one weight.
       This used to live in .btn--mono, so buttons without that modifier came out
       sentence-case and heavier. */
    text-transform: uppercase;
    letter-spacing: 0;
    font-weight: 500;
    font-size: 0.85rem;
    line-height: 1;
    transition: transform .15s ease, background .2s ease, color .2s ease, border-color .2s ease, box-shadow .2s ease;
    white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn .arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.btn .arrow svg { display: block; }
.btn--dark    { background: var(--brand); color: #fff; }
.btn--dark:hover { box-shadow: 0 8px 22px rgba(26,25,159,0.28); }
.btn--ghost   { background: transparent; color: var(--brand); border: 1px solid rgba(26,25,159,0.30); }
.btn--ghost:hover { border-color: var(--brand); }
.btn--white   { background: #fff; color: var(--brand); transition: background .25s ease, color .25s ease; }
.btn--white:hover { background: var(--gold); color: var(--ink); }
/* Accent button: solid gold, simple hover (no sweep fill) — lightens to
   gold-soft with a soft glow. */
.btn--accent  {
    background: var(--gold);
    color: var(--ink);
    transition: background .2s ease, color .25s ease, transform .15s ease, box-shadow .2s ease;
}
.btn--accent:hover { background: var(--gold-soft); color: var(--ink); box-shadow: 0 8px 22px rgba(245,213,26,0.35); }

/* Header — a transparent bar in normal flow (NOT sticky), sitting above the
   hero. No background container: it spans the full hero-block width (same
   --inset side margins as the hero), so the logo sits flush to the block's
   left edge and the CTA to its right edge. */
.site-header {
    position: relative;
    z-index: 40;                 /* stay above the mobile menu overlay (z-30) */
    margin: var(--inset-top) var(--inset) 0;
    color: var(--ink);
}
.site-header a { color: currentColor; }
/* Header CTA: filled gold pill with ink text. The a.header-cta selector
   outranks `.site-header a` (which would otherwise force the text to ink). */
.site-header a.header-cta {
    background: var(--gold);
    color: var(--ink);
    transition: background .2s ease, color .25s ease, transform .15s ease, box-shadow .2s ease;
}
.site-header a.header-cta:hover { background: var(--gold-soft); color: var(--ink); box-shadow: 0 8px 22px rgba(245,213,26,0.35); }
/* Header nav links: gold underline grows in on hover (transparent by default
   so the link never shifts). */
.site-header .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding-bottom: 3px;
    border-bottom: 3px solid transparent;
    transition: border-color .18s ease;
}
.site-header .nav-link:hover { border-color: var(--gold); }
/* Active section in the main nav */
.site-header .nav-link.is-active { border-bottom-color: var(--gold); color: var(--ink); }
.mobile-menu a.is-active { color: var(--brand); }

/* Dropdown nav items (Services, Expertise) — a hover/focus flyout panel.
   The parent <li> reserves space below for the menu so the pointer can
   travel into it without the menu closing. */
.nav-item--has-menu { position: relative; }
.nav-item--has-menu .nav-caret { transition: transform .2s ease; }
.nav-item--has-menu:hover .nav-caret,
.nav-item--has-menu:focus-within .nav-caret { transform: rotate(180deg); }
.nav-menu {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translate(-50%, 8px);
    margin-top: 14px;
    min-width: 230px;
    background: var(--cream-soft);
    border: 1px solid rgba(0,0,0,0.07);
    border-radius: 16px;
    box-shadow: 0 18px 40px rgba(20,19,46,0.16);
    padding: 0.5rem;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease, visibility .18s;
    z-index: 50;
}
/* Bridge the 14px gap so hover doesn't drop when crossing into the menu. */
.nav-menu::before {
    content: "";
    position: absolute;
    left: 0; right: 0; top: -16px;
    height: 16px;
}
.nav-item--has-menu:hover .nav-menu,
.nav-item--has-menu:focus-within .nav-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translate(-50%, 0);
}
.nav-menu__link {
    display: block;
    padding: 0.6rem 0.85rem;
    border-radius: 12px;
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--ink);
    transition: background .15s ease, color .15s ease;
}
.nav-menu__link:hover { background: rgba(26,25,159,0.06); color: var(--brand); }
.nav-menu__link.is-active { background: rgba(26,25,159,0.08); color: var(--brand); font-weight: 600; }

/* Mobile: nested submenu links sit indented under their group label. */
.mobile-submenu { padding-left: 0.9rem; border-left: 2px solid rgba(0,0,0,0.08); margin: 0.25rem 0 0.5rem; }
.mobile-submenu a { font-size: 1.15rem; }

/* Full-viewport hero with background photo — inset from the page edges with
   a large radius so the light background frames it. */
.hero-full {
    position: relative;
    /* --inset-top above so the header sits in a symmetric band (same gap above
       and below it); the full --inset on the other three sides frames the block. */
    margin: var(--inset-top) var(--inset) var(--inset);
    /* leave room for the in-flow header above (its height + the gaps above the
       header, between header & hero, and below the hero) so the first screen fits. */
    min-height: calc(100vh - var(--header-h) - 2 * var(--inset-top) - var(--inset));
    min-height: calc(100svh - var(--header-h) - 2 * var(--inset-top) - var(--inset));
    display: flex;
    align-items: center;
    overflow: hidden;
    border-radius: var(--block-radius);
}
.hero-full__bg {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: center;
    z-index: 0;
}
.hero-full__overlay {
    position: absolute; inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        linear-gradient(180deg, rgba(15,14,40,0.62) 0%, rgba(15,14,40,0.30) 38%, rgba(15,14,40,0.72) 100%);
}
.hero-full__content { position: relative; z-index: 2; width: 100%; }

/* Home hero: keep the deep-blue .ph-brand gamma (top-right indigo glow +
   corner falloff) but as a translucent scrim over the background photo, so the
   photo stays visible while the white copy stays legible. */
.hero-full:not(.hero-full--band) .hero-full__overlay {
    background:
        radial-gradient(46% 56% at 78% 22%, rgba(82,96,238,0.32) 0%, rgba(82,96,238,0) 62%),
        radial-gradient(125% 135% at 0% 0%, rgba(59,57,176,0.38) 0%, rgba(26,25,66,0.56) 46%, rgba(14,13,38,0.66) 100%),
        linear-gradient(180deg, rgba(12,11,32,0.34) 0%, rgba(12,11,32,0.06) 42%, rgba(12,11,32,0.46) 100%);
}
/* Interior band heroes: same deep-blue .ph-brand gamma as the home hero, but a
   denser vertical scrim — the band is short, so it can't afford a light middle
   and the white heading must stay legible over the photo. */
.hero-full--band .hero-full__overlay {
    background:
        radial-gradient(55% 75% at 82% 16%, rgba(82,96,238,0.32) 0%, rgba(82,96,238,0) 60%),
        radial-gradient(135% 150% at 0% 0%, rgba(59,57,176,0.40) 0%, rgba(26,25,66,0.60) 45%, rgba(14,13,38,0.70) 100%),
        linear-gradient(180deg, rgba(12,11,32,0.40) 0%, rgba(12,11,32,0.22) 45%, rgba(12,11,32,0.54) 100%);
}
/* Home hero buttons: gold fill sweeps in left→right on hover, dark text,
   no lift/shift. */
.btn--hero-primary, .btn--hero-secondary {
    background-image: linear-gradient(var(--gold), var(--gold));
    background-repeat: no-repeat;
    background-position: left center;
    background-size: 0% 100%;
    transition: background-size .4s ease, color .2s ease, border-color .2s ease;
}
.btn--hero-primary   { background-color: #fff; color: var(--brand); }
.btn--hero-secondary { background-color: transparent; color: #fff; border: 1px solid rgba(255,255,255,0.5); }
.btn--hero-primary:hover,
.btn--hero-secondary:hover { background-size: 100% 100%; color: var(--ink); transform: none; }
.btn--hero-secondary:hover { border-color: var(--gold); }
/* No lift for any button inside the home hero (incl. .btn--accent) */
.hero-full:not(.hero-full--band) .btn:hover { transform: none; }

/* Interior page heroes run full-screen too: header + hero + all the inset gaps
   add up to exactly one viewport, so the bottom gap stays visible. */
.hero-full--band {
    min-height: clamp(420px, calc(100vh  - var(--header-h) - 2 * var(--inset-top) - var(--inset)), 100vh);
    min-height: clamp(420px, calc(100svh - var(--header-h) - 2 * var(--inset-top) - var(--inset)), 100svh);
}
/* Short band for pages with a title and nothing else to say (legal pages) —
   a full screen of empty photo would read as a mistake there. */
.hero-full--compact { min-height: clamp(320px, 44vh, 460px); }


/* Background cards (photo or gradient) with text anchored to the bottom */
.card-bg {
    position: relative;
    border-radius: 16px;
    overflow: hidden;
    min-height: 360px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 1.75rem;
    color: #fff;
    isolation: isolate;
}
.card-bg__media {
    position: absolute; inset: 0;
    z-index: 0;
    width: 100%; height: 100%;
    object-fit: cover;
}
.card-bg__overlay {
    position: absolute; inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(15,14,40,0.10) 0%, rgba(15,14,40,0.55) 58%, rgba(15,14,40,0.84) 100%);
}
.card-bg__content { position: relative; z-index: 2; }
/* Keep card headings aligned across the row: reserve a consistent
   text height so bottom-anchored content lines up regardless of copy length. */
.card-bg__content p { min-height: 4.875rem; }
@media (max-width: 767px) { .card-bg__content p { min-height: 0; } }

/* Media band (background photo + dark overlay), e.g. final CTA — inset & rounded */
.media-band {
    position: relative;
    overflow: hidden;
    margin: var(--inset);
    border-radius: var(--block-radius);
}

/* Full-width white content bands become inset, rounded white panels that read
   as "text areas on white" against the light page. Scoped to <section>
   so element-level `bg-creamSoft` cards (e.g. the contact form) are untouched. */
section.bg-creamSoft {
    margin: var(--inset);
    border-radius: var(--block-radius);
}

/* Content sheet — the light counterpart of .dark-band. A full-bleed inset white
   panel carrying its own vertical rhythm, so every top-level block (hero, panel,
   dark band, CTA) is a discrete inset rounded card. Consecutive panels stay
   separate: the tinted page background shows through the gap between them. */
.panel {
    background: var(--cream-soft);
    margin: var(--inset);
    border-radius: var(--block-radius);
    padding-block: clamp(2.75rem, 4.6vw, 4.5rem);
}

/* Soft tinted surface for cards that sit ON a white panel (they'd vanish if
   they were white too) — e.g. the contact form card. */
.surface-soft { background: var(--surface-2); }
.media-band__bg {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: center;
    z-index: 0;
}
.media-band__overlay {
    position: absolute; inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(15,14,40,0.86) 0%, rgba(15,14,40,0.60) 60%, rgba(15,14,40,0.44) 100%);
}
.media-band__content { position: relative; z-index: 2; }

/* Fact / info box */
.factbox {
    background: var(--cream-soft);
    border: 1px solid rgba(0,0,0,0.08);
    border-radius: 16px;
    padding: 1.6rem 1.8rem;
}
.factbox dl {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 0.7rem 1.4rem;
    margin: 0;
}
.factbox dt { color: var(--faint); font-size: 0.95rem; }
.factbox dd { margin: 0; color: var(--brand); font-weight: 600; }
@media (max-width: 640px) {
    .factbox dl { grid-template-columns: 1fr; gap: 0.25rem; }
    .factbox dd { margin-bottom: 0.6rem; }
}

/* FAQ accordion — native <details>/<summary>, no JS */
.faq-item { border-top: 1px solid rgba(0,0,0,0.12); }
.faq-item:last-child { border-bottom: 1px solid rgba(0,0,0,0.12); }
.faq-item > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 1.45rem 0;
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 600;
    font-size: clamp(1.05rem, 2vw, 1.25rem);
    color: var(--ink);
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item .faq-icon {
    flex-shrink: 0;
    color: var(--accent);
    transition: transform .25s ease;
}
.faq-item[open] > summary .faq-icon { transform: rotate(45deg); }
.faq-item__body {
    padding: 0 0 1.5rem;
    color: var(--muted);
    line-height: 1.7;
    max-width: 62ch;
}

/* Legal / policy prose */
.legal-prose h2 {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 700;
    color: var(--brand);
    font-size: 1.55rem;
    margin-top: 2.6rem;
    margin-bottom: 0.6rem;
}
.legal-prose h2:first-of-type { margin-top: 1.5rem; }
.legal-prose h3 {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 700;
    color: var(--brand);
    font-size: 1.25rem;
    margin-top: 2.25rem;
    margin-bottom: 0.5rem;
}
.legal-prose p { color: var(--muted); line-height: 1.75; margin-bottom: 1rem; }
.legal-prose ul { list-style: disc; padding-left: 1.3rem; margin: 0 0 1rem; color: var(--muted); }
.legal-prose li { margin-bottom: 0.5rem; line-height: 1.7; }
.legal-prose a { color: var(--accent); text-decoration: underline; }
.legal-prose a:hover { color: var(--ink); }
.legal-prose strong { color: var(--ink); font-weight: 600; }

/* Legal page: white content card + sticky in-page table of contents */
.legal-card {
    background: var(--cream-soft);
    border-radius: 16px;
    padding: 1.75rem 1.5rem;
}
@media (min-width: 1024px) {
    .legal-card { padding: 2.75rem 3rem; }
}
.legal-prose h2 { scroll-margin-top: 1.5rem; }

.legal-toc { position: sticky; top: 24px; }
.legal-toc__title {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    /* --ink, like the eyebrows: it is the same kind of small caps label, and on
       --faint it read as a second grey next to the --muted links below it. */
    color: var(--ink);
    font-weight: 600;
    margin-bottom: 0.9rem;
}
.legal-toc ul { list-style: none; margin: 0; padding: 0; border-left: 2px solid rgba(0,0,0,0.08); }
.legal-toc a {
    display: block;
    padding: 0.4rem 0 0.4rem 1rem;
    margin-left: -2px;
    border-left: 2px solid transparent;
    color: var(--muted);
    font-size: 0.92rem;
    line-height: 1.45;
    text-decoration: none;
    transition: color .15s ease, border-color .15s ease;
}
.legal-toc a:hover { color: var(--ink); }
.legal-toc a.is-active { color: var(--ink); border-left-color: var(--brand); font-weight: 600; }

/* Inline callout / note box */
.callout {
    display: flex;
    gap: 0.85rem;
    border: 1px solid rgba(0,0,0,0.12);
    background: var(--cream-soft);
    border-radius: 16px;
    padding: 1.1rem 1.25rem;
    color: var(--muted);
    line-height: 1.65;
}
.callout svg { flex-shrink: 0; color: var(--accent); margin-top: 2px; }
.callout strong { color: var(--ink); }
/* Full-width feature callout with stronger rounding */
.callout--wide { background: var(--cream-soft); border: none; border-radius: 16px; padding: 1.3rem 1.6rem; }
.callout--wide svg { color: var(--gold); }

/* Form — rounded outline fields */
.field { display: block; }
.field > label {
    display: block;
    font-size: 0.85rem;
    color: var(--faint);
    font-weight: 500;
    margin-bottom: 0.25rem;
    letter-spacing: 0.01em;
}
.input-field {
    display: block;
    width: 100%;
    /* White fill, not transparent: the form card sits on the tinted --surface-2,
       so the fields need to read as cut into it rather than painted onto it. */
    background: var(--cream-soft);
    border: 1.5px solid #C9CCD6;
    border-radius: 16px;
    padding: 0.9rem 1.1rem;
    font-size: 1rem;
    line-height: 1.4;
    color: var(--ink);
    font-family: inherit;
    outline: 0;
    appearance: none;
    -webkit-appearance: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.input-field::placeholder { color: var(--faint); }
.input-field:hover { border-color: #9A9DB0; }
.input-field:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(26,25,159,0.18);
}
textarea.input-field { resize: vertical; min-height: 140px; }

/* Phosphor outline icon at feature size (e.g. stat cards) */
.m-icon {
    font-size: 60px;
    line-height: 1;
    color: var(--brand);
}
/* Accent variant of the outline icon */
.m-icon--accent { color: var(--gold); }

/* Step / number badge chip — gold pill, dark text */
.step-chip {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    background: var(--gold);
    color: var(--ink);
    font-weight: 500;
    font-size: 0.8rem;
    letter-spacing: 0;      /* caps, but no tracking */
    text-transform: uppercase;
    line-height: 1;
    padding: 0.4rem 0.8rem;
    border-radius: 999px;
}

/* Contact icon tile */
.contact-icon {
    width: 48px; height: 48px;
    border-radius: 999px;
    background: rgba(26,25,159,0.08);
    color: var(--accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.contact-icon svg { width: 22px; height: 22px; }

/* Footer — light, blends with the page; separated from content by a hairline */
.site-footer {
    background: transparent;
    border-top: 1px solid rgba(26,25,159,0.12);
}
/* One type size for the whole footer, and one weight for everything except the
   column labels (see below). The copyright row differs by its rule and position
   alone, not by size. */
.site-footer,
.site-footer p,
.site-footer a,
.site-footer li,
.site-footer h4 {
    font-size: 0.95rem;
    font-weight: 300;
    line-height: 1.65;
    letter-spacing: 0;
    text-transform: none;
}
/* Column labels carry no weight of their own — same thin text as everything
   else, set apart by colour and caps. No tracking, per the site-wide rule.
   The gap below comes from the variable the alignment maths uses, so the links
   and the brand blurb move together. */
.site-footer h4 {
    color: var(--ink);
    text-transform: uppercase;
    margin-bottom: var(--footer-label-gap);
}

/* Footer.
   The brand column opens with the logo and the nav columns with a text label,
   so the two have to be lined up by hand. Both offsets below are derived from
   these three numbers — change the logo height here, not in the markup, and the
   alignment follows. */
.site-footer {
    --footer-logo-h:    3rem;                /* .footer-logo height          */
    --footer-label-h:   calc(0.95rem * 1.65); /* label font-size x line-height */
    --footer-label-gap: 1.6rem;              /* label to first link          */
}
/* The logo link is block, not inline-block: as an inline-block it sits on the
   line's baseline and the strut adds a few pixels of descender space under it,
   which pushed the blurb below the first nav link. width: fit-content keeps the
   clickable area on the logo itself. */
.footer-logo-link { display: block; width: fit-content; }
.footer-logo { height: var(--footer-logo-h); }
.footer-grid {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: 3rem;
    align-items: start;
}
/* Column labels sit on the logo's centre line. */
.footer-grid > :not(:first-child) {
    padding-top: calc((var(--footer-logo-h) - var(--footer-label-h)) / 2);
}
@media (max-width: 1023px) {
    .footer-grid > :not(:first-child) { padding-top: 0; }
}
@media (min-width: 1024px) {
    /* ...and the blurb starts level with the first link in those columns: the
       label's offset above, plus its own line box and margin, less the height
       of the logo the blurb hangs from. */
    .site-footer .footer-blurb {
        margin-top: calc(
            ((var(--footer-logo-h) - var(--footer-label-h)) / 2)
            + var(--footer-label-h)
            + var(--footer-label-gap)
            - var(--footer-logo-h)
        );
    }
}
@media (max-width: 1023px) {
    .footer-grid { grid-template-columns: 1fr 1fr; gap: 2.5rem; }
}
@media (max-width: 520px) {
    .footer-grid { grid-template-columns: 1fr; gap: 2rem; }
}

/* ============================================================
   IMAGE PLACEHOLDERS — neutral gradients standing in for
   not-yet-generated imagery. Drop onto a __bg / __media layer
   or a band background. Swap for a real <img> when ready.
   ============================================================ */
.ph-dark {
    background: linear-gradient(140deg, #2A2A3C 0%, #1B1B2A 55%, #121120 100%);
}
.ph-brand {
    background:
        radial-gradient(38% 46% at 82% 28%, rgba(82,96,238,0.45) 0%, rgba(82,96,238,0) 62%),
        radial-gradient(125% 135% at 0% 0%, #3B39B0 0%, #1A1942 48%, #0E0D26 100%);
}
/* Deep-blue brand gradient as a utility (dark blocks / bands / demo surfaces) */
.bg-brand-gradient { background: var(--brand-gradient); }
.ph-soft {
    background: linear-gradient(140deg, #ECEEF6 0%, #DFE2EE 100%);
}
/* Faint dotted texture overlay so flat placeholders read as intentional */
.ph-dots::after {
    content: "";
    position: absolute; inset: 0;
    background-image: radial-gradient(rgba(245,213,26,0.18) 1.4px, transparent 1.6px);
    background-size: 26px 26px;
    opacity: 0.5;
    pointer-events: none;
}

/* ============================================================
   HOMEPAGE COMPONENTS (Upmind-style layout, yellow accent)
   ============================================================ */

/* Eyebrow — "• SECTION" small uppercase tracked label with a gold dot */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.8rem;
    font-weight: 500;
    /* Caps stay, the 0.16em tracking does not — Archivo is wide enough that the
       spaced-out version read as stretched. */
    letter-spacing: 0;
    text-transform: uppercase;
    line-height: 1.5;   /* pinned: .align-to-heading computes its offset from it */
    /* Brand blue, not --faint: sitting a few lines above --muted body copy, the
       quiet grey read as a second, unrelated grey rather than as a quieter step
       of the same one. Blue puts the label back on the page's one colour axis. */
    color: var(--ink);
}
.eyebrow::before {
    content: "";
    width: 0.5rem; height: 0.5rem;
    border-radius: 999px;
    background: var(--gold);
    flex-shrink: 0;
}
.eyebrow--on-dark { color: rgba(255,255,255,0.85); }
/* In the hero the gold dot is alive: it pulses between a dim and a lit state,
   carrying a soft glow with it. Everywhere else the dot stays static. */
@keyframes eyebrow-dot-blink {
    0%, 100% { opacity: 0.45; box-shadow: 0 0 0 0 rgba(245,213,26,0); }
    50%      { opacity: 1;    box-shadow: 0 0 12px 3px rgba(245,213,26,0.65); }
}
.hero-full .eyebrow::before {
    animation: eyebrow-dot-blink 1.9s ease-in-out infinite;
}

/* Typewriter reveal on the hero heading (see assets/js/animations.js). The JS
   splits the heading into a typed span and a `.tw-rest` remainder that keeps its
   space but stays invisible, so the line breaks never move while the text runs
   out. The caret is a thin gold bar that blinks on the typed span. */
.tw-rest { visibility: hidden; }
/* The caret is the typed span's right border, not an inline-block ::after. An
   atomic inline box would open a line-break opportunity on either side of it,
   and whenever the caret passed a wrap point the browser took that break: the
   invisible remainder dropped to the next line and the whole heading re-flowed
   mid-type. A border adds no break opportunity, and the negative margin cancels
   its advance width so the reserved layout stays put. Blinking is on
   border-color, never opacity, which would fade the typed text with it. */
.is-typing {
    border-right: 0.055em solid var(--gold);
    margin-right: -0.055em;
    animation: type-caret 0.6s steps(1) infinite;
}
@keyframes type-caret {
    0%, 49%   { border-right-color: var(--gold); }
    50%, 100% { border-right-color: transparent; }
}
@media (prefers-reduced-motion: reduce) {
    .hero-full .eyebrow::before { animation: none; }
    .is-typing { border-right-color: transparent; animation: none; }
}

/* Lead paragraph: the opening line under a section heading. Brand blue and a
   step larger than the body copy, held at 300 so the size carries it instead of
   the weight — it bridges the serif heading and the grey copy that follows. */
.lead {
    color: var(--brand);
    font-weight: 300;
    font-size: clamp(1.3rem, 1.9vw, 1.7rem);
    line-height: 1.45;
    letter-spacing: -0.005em;
}

/* Two-column text sections put the eyebrow + heading in the left column and the
   body copy in the right one. By default the right column starts level with the
   eyebrow chip; .align-to-heading drops it to the top of the <h2> instead.
   The offset is the eyebrow's own line box plus the heading's mt-5 (1.25rem),
   so it stays correct if the eyebrow font-size changes. Single-column below lg,
   where the two blocks simply stack. */
@media (min-width: 1024px) {
    .align-to-heading { padding-top: calc(0.8rem * 1.5 + 1.25rem); }
}

/* Roomier padding for the primary calls to action. The label treatment itself
   now lives on .btn, so this modifier only changes the box. */
.btn--mono {
    padding: 1rem 1.7rem;
}
/* Deep-blue gradient pill with white label (GET STARTED / LEARN MORE / VIEW SERVICES) */
.btn--ink {
    background: var(--brand-deep);
    color: #fff;
    transition: filter .2s ease, box-shadow .2s ease, transform .15s ease;
}
.btn--ink:hover { filter: brightness(1.12); box-shadow: 0 12px 28px rgba(26,25,159,0.38); }
/* Translucent outline pill on dark photo (OUR SERVICES). At rest it is quiet;
   hovering lights a soft gold glow, matching the hero's yellow accents. */
.btn--glass {
    background: rgba(20,19,46,0.45);
    color: #fff;
    border: 1px solid rgba(255,255,255,0.28);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.btn--glass:hover {
    background: rgba(20,19,46,0.62);
    border-color: rgba(245,213,26,0.55);
    box-shadow: 0 0 18px 3px rgba(245,213,26,0.26);
}

/* Floating "glassy" badge pills scattered over the hero photo */
.pill-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    /* Even padding all round: the old cramped left edge was sized for the disc
       that used to sit there, not for the bead. */
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    background: rgba(20,19,46,0.42);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255,255,255,0.18);
    color: #fff;
    font-size: 0.9rem;
    font-weight: 400;
    letter-spacing: -0.012em;
    white-space: nowrap;
    box-shadow: 0 10px 30px rgba(0,0,0,0.20);
}
/* A small gold bead, no icon inside. It breathes on its own — dimming and
   lighting with a soft glow — which is what makes the pills feel alive. */
.pill-badge__dot {
    width: 0.75rem; height: 0.75rem;
    border-radius: 999px;
    background: var(--gold);
    display: inline-block;
    flex-shrink: 0;
    animation: dot-glow-pulse 2.4s ease-in-out infinite;
    /* --delay is set per pill for the float and inherits down to the dot, so no
       two beads pulse in step. */
    animation-delay: var(--delay, 0s);
}
@keyframes dot-glow-pulse {
    0%, 100% { opacity: 0.5; box-shadow: 0 0 4px 0 rgba(245,213,26,0.35); }
    50%      { opacity: 1;   box-shadow: 0 0 14px 4px rgba(245,213,26,0.75); }
}
/* Hover just holds it at the lit end of the cycle. */
.pill-badge:hover .pill-badge__dot {
    animation: none;
    opacity: 1;
    box-shadow: 0 0 16px 5px rgba(245,213,26,0.85);
}
/* Above .hero-full__content (z-2) so every pill — not just those outside the
   centred content band — receives hover. Container stays pointer-events:none,
   so only the pills themselves intercept and the centred CTA stays clickable. */
.hero-pills { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.hero-pills .pill-badge {
    position: absolute;
    pointer-events: auto;         /* re-enable hover (container is none) */
    animation: pill-float var(--dur, 4.5s) ease-in-out infinite;
    animation-delay: var(--delay, 0s);
    will-change: transform;
}
/* Pronounced straight up/down bob (no tilt) so the pills clearly float.
   Amplitude is per-pill via --amp so they don't all rise the same distance. */
@keyframes pill-float {
    0%   { transform: translateY(0); }
    50%  { transform: translateY(calc(-1 * var(--amp, 40px))); }
    100% { transform: translateY(0); }
}
/* Desync each pill — varied amplitude, speed and negative delay (already
   mid-cycle at load) so they never move in lockstep. */
.hero-pills .pill-badge:nth-child(1) { --amp: 44px; --dur: 4.0s; --delay: -0.2s; }
.hero-pills .pill-badge:nth-child(2) { --amp: 32px; --dur: 5.3s; --delay: -1.9s; }
.hero-pills .pill-badge:nth-child(3) { --amp: 56px; --dur: 4.6s; --delay: -0.9s; }
.hero-pills .pill-badge:nth-child(4) { --amp: 38px; --dur: 5.7s; --delay: -3.2s; }
.hero-pills .pill-badge:nth-child(5) { --amp: 62px; --dur: 4.3s; --delay: -1.3s; }
@media (prefers-reduced-motion: reduce) {
    .hero-pills .pill-badge { animation: none; }
    /* Beads hold lit instead of breathing. */
    .pill-badge__dot {
        animation: none;
        opacity: 1;
        box-shadow: 0 0 12px 3px rgba(245,213,26,0.7);
    }
}
/* The pills live in the gutters either side of the centred hero column, which
   is 896px wide (max-w-4xl). Below ~1280px those gutters are narrower than a
   pill, so the badges sit on top of the h1 instead of beside it — hide them
   and let the hero run clean on tablets and phones. */
@media (max-width: 1279px) { .hero-pills { display: none; } }

/* Service / feature cards (light indigo-tinted) */
.svc-card {
    background: #ECEEF8;
    border-radius: 16px;
    padding: 2rem 1.75rem;
    display: flex;
    flex-direction: column;
    min-height: 300px;
    transition: background 0.2s ease;
}
.svc-card:hover {
    background: #E6E9F6;
}
/* Card icon: a large hairline Phosphor glyph, no backing tile — the icon itself
   is the graphic. Brand blue, like every other feature icon in the system
   (.m-icon): the hairline weight keeps it from shouting at that size, and the
   grey-violet it used to run in read as a disabled state. */
.svc-card__icon {
    display: inline-flex;
    align-items: center;
    color: var(--brand);
}
.svc-card__icon i {
    font-size: 4.5rem;
    line-height: 1;
}
/* Card titles run light, like the .xp-card titles — the section heading carries
   the weight on these panels, the cards stay quiet.
   The title reserves two lines whether it needs them or not, so across a row of
   cards the icons, the titles and the first line of body copy all sit on the
   same baselines regardless of how long each title and blurb runs. */
.svc-card h3 {
    color: var(--brand);
    font-weight: 300;
    letter-spacing: -0.005em;
    line-height: 1.25;
    min-height: 2.5em;
}
/* Body copy is the only part left free to run to different lengths, and it is
   pinned to the bottom of the card so the ragged edge is the card's, not the
   grid's. */
.svc-card > p:last-child { margin-bottom: auto; }

/* "What it includes" list under an expanded service block. No rules between the
   rows — each line is marked by a hairline outline arrow instead. */
.svc-points { list-style: none; margin: 0; padding: 0; }
.svc-points li {
    display: flex;
    align-items: baseline;
    gap: 0.7rem;
    padding: 0.45rem 0;
    color: var(--muted);
}
.svc-points svg {
    flex-shrink: 0;
    color: var(--brand);
    transform: translateY(0.15em); /* optical: align the shaft with the x-height */
}

/* Stat / "performance" card (dark, gold figure) */
/* Trust block (About section). No fill and no gold — just a hairline frame, so
   the block is bounded without becoming another coloured card on the panel. */
.trust-block {
    border: 1px solid rgba(26, 25, 159, 0.12);
    border-radius: var(--block-radius);
    padding: clamp(1.75rem, 3vw, 2.5rem);
}
/* The figure carries this block, so its title stays as light as the card titles. */
.trust-block h3 { font-weight: 300; }
/* The figure is set in the heading serif at 700 — it reads as a headline number
   rather than as data. Tracking is looser than the Archivo version: a bold serif
   at this size closes up on its own. */
.stat-figure {
    font-family: 'Noto Serif', 'Georgia', serif;
    font-weight: 700;
    font-size: clamp(4.5rem, 10vw, 7.5rem);
    line-height: 0.95;
    color: var(--brand);
    letter-spacing: -0.02em;
    display: block;
}
.stat-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid rgba(26, 25, 159, 0.10);
    color: var(--ink);
    font-size: 0.85rem;
    /* Archivo sets wide by default; chips are small and short, so they need the
       tracking pulled back in or the labels look stretched. */
    letter-spacing: -0.012em;
    white-space: nowrap;
}

/* Inset rounded dark band (Vision & Values). The deep-blue base is painted on
   the element; the lighter blue spot that used to be the first radial-gradient
   layer now lives in ::before so it can drift. Gradient stop positions can't be
   animated smoothly, a transform on a separate layer can. */
.dark-band {
    position: relative;
    margin: var(--inset);
    border-radius: var(--block-radius);
    background: radial-gradient(120% 130% at 0% 0%, #3B39B0 0%, #1A1942 52%, #0E0D26 100%);
    color: #fff;
    overflow: hidden; /* clips the drifting spot to the rounded corners */
}
/* The same drifting spot rides on the CTA band, mirrored to the other corner and
   on a different clock so the two dark blocks don't move in step. */
.dark-band::before,
.media-band.bg-brand-gradient::before {
    content: "";
    position: absolute;
    z-index: 0;
    top: -45%;
    right: -10%;
    width: clamp(520px, 70vw, 1100px);
    aspect-ratio: 1;
    background: radial-gradient(circle, rgba(96,110,255,0.62) 0%, rgba(82,96,238,0.22) 38%, rgba(82,96,238,0) 66%);
    pointer-events: none;
    animation: band-glow-drift 13s ease-in-out infinite alternate;
    will-change: transform;
}
/* Uneven wander so the light never looks like it is on a loop. The travel is
   deliberately large — at a smaller amplitude the drift is invisible against a
   gradient this soft. */
@keyframes band-glow-drift {
    0%   { transform: translate3d(0, 0, 0)         scale(1); }
    35%  { transform: translate3d(-46%, 16%, 0)    scale(1.18); }
    70%  { transform: translate3d(-18%, 34%, 0)    scale(0.9); }
    100% { transform: translate3d(-62%, 10%, 0)    scale(1.12); }
}
/* The CTA band gets exactly the dark band's treatment: the flat base without the
   static radial spot baked into --brand-gradient (which would sit on top of the
   drifting one and hide the movement), then the same drifting spot above it. */
.media-band.bg-brand-gradient {
    background: radial-gradient(120% 130% at 0% 0%, #3B39B0 0%, #1A1942 52%, #0E0D26 100%);
}
@media (prefers-reduced-motion: reduce) {
    .dark-band::before,
    .media-band.bg-brand-gradient::before { animation: none; }
}
/* Content sits above the drifting spot. */
.dark-band > * { position: relative; z-index: 1; }

/* Numbered value cards on the dark band */
.value-card {
    border-top: 1px solid rgba(255,255,255,0.16);
    padding-top: 1.4rem;
}
.value-card__num {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 500;
    font-size: 0.9rem;
    letter-spacing: 0.1em;
    color: var(--gold);
}
/* Light like the other card titles — the number and the section heading carry
   the weight here. */
.value-card h3 { color: #fff; font-weight: 300; }

/* Card rail: below `sm` a card grid becomes a horizontal scroller — one card in
   view, the next one peeking, snapping into place. The class is doubled in the
   selector on purpose: it has to outrank Tailwind's `grid` utility no matter
   which stylesheet the CDN injects first. */
@media (max-width: 639px) {
    .card-rail.card-rail {
        display: flex;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x mandatory;
        /* The rail stays inside the section's own padding, so the first card
           keeps the page margin on its left and the next one peeks on the
           right. (Bleeding to the viewport edges put the first card flush
           against the screen.) */
        padding-bottom: 0.25rem;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    .card-rail.card-rail::-webkit-scrollbar { display: none; }
    .card-rail.card-rail > * {
        flex: 0 0 88%;
        scroll-snap-align: start;
    }
}

/* Expertise cards. Outline rather than filled, so they read as a lighter tier
   than the tinted .svc-card grid, with the step number carrying the sequence.
   Same type treatment as the service cards, so both grids read as one system. */
.xp-card {
    display: flex;
    flex-direction: column;
    border: 1px solid rgba(26, 25, 159, 0.14);
    border-radius: 16px;
    padding: 1.75rem;
    min-height: 240px;
    transition: border-color 0.2s ease, background 0.2s ease;
}
.xp-card:hover {
    border-color: rgba(26, 25, 159, 0.34);
    background: var(--surface-2);
}
.xp-card__num {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 500;
    font-size: 0.9rem;
    color: var(--faint);
}
.xp-card h3 {
    color: var(--brand);
    font-weight: 300;
    letter-spacing: -0.005em;
    line-height: 1.25;
}
/* Bare outline arrow — no disc, no fill. Pinned to the bottom of the card so it
   sits on one line across the row whatever length the blurbs run to. Brand blue
   at rest, like every other icon: it used to lift from grey to blue on hover,
   but the card already answers with its border and its fill, so the arrow just
   holds its colour and nothing shifts. */
.xp-card__arrow {
    color: var(--brand);
    display: inline-flex;
    margin-top: auto;
    padding-top: 1.5rem;
}
