/* ===========================================================================
   Softhenge homepage — 2026 design, implemented from Figma
   (file DoVBZQnTs4WCqBR1qpzDw2, frame 1321:445 "Bundled Page").

   Loaded only by views/public/index.tpl. Deliberately standalone: it does not
   depend on site/style.css, bootstrap or the old theme's plugin bundle, so the
   two designs cannot fight over selectors. Every other page still uses
   head.tpl / header.tpl / footer.tpl / foot.tpl unchanged.

   The design is drawn at 1920px wide with a 1320px content column. Everything
   below keeps the design's exact type, colour and spacing values at desktop
   and reflows down from there.
   =========================================================================== */

:root {
    /* Surfaces */
    --c-navy-900: #061428;  /* footer                                        */
    --c-navy-850: #081b36;  /* page backdrop                                 */
    --c-navy-700: #0d243b;  /* hero gradient, left                           */
    --c-navy-600: #0e3358;  /* hero gradient right, section headings, rules  */
    --c-blue-600: #1c5488;  /* primary button, contact section               */
    --c-surface-a: #e9edf2; /* alternating section background, odd           */
    --c-surface-b: #dde6ed; /* alternating section background, even          */

    /* Ink */
    --c-ink: #0b1826;       /* headings on light                             */
    --c-ink-btn: #0a2140;   /* label on a white button                       */
    --c-body: #384c5d;
    --c-body-2: #3d5062;
    --c-body-3: #45596b;
    --c-body-4: #4e6377;
    --c-accent: #9cc8f0;    /* hero headline accent                          */

    /* Tag pill */
    --c-tag-bg: #dce7f3;
    --c-tag-border: #c3d5e8;
    --c-tag-ink: #054b88;

    /* Type */
    --f-display: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --f-text: 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --f-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

    /* Rhythm. --pad-y is the 140px section padding of the design; it shrinks
       on narrow screens through the media queries at the end of this file. */
    --pad-y: 140px;
    --hdr-h: 88px;
    --wrap: 1320px;
    --gutter: 24px;
}

/* --------------------------------------------------------------- base ---- */

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--c-navy-850);
    color: var(--c-body);
    font-family: var(--f-text);
    font-size: 18px;
    line-height: 26px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

h1, h2, h3, h4 {
    margin: 0;
    font-family: var(--f-display);
    font-weight: 500;
    color: var(--c-ink);
}

p { margin: 0; }

:focus-visible {
    outline: 2px solid var(--c-accent);
    outline-offset: 3px;
}

/* --wrap is the design's 1320px content column; the gutter sits outside it,
   so the column keeps its exact design width on wide screens. */
.wrap {
    width: 100%;
    max-width: calc(var(--wrap) + var(--gutter) * 2);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* Visually hidden, still read out. */
.vh {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Section shells. Sections alternate between the two light surfaces. */
.sec {
    padding: var(--pad-y) 0;
    border-top: 1px solid rgba(255, 255, 255, .18);
}
.sec--a { background: var(--c-surface-a); }
.sec--b { background: var(--c-surface-b); }

.sec-title {
    font-size: 48px;
    line-height: 56px;
    letter-spacing: -.68px;
    color: var(--c-navy-600);
}
.sec-lead {
    font-size: 18px;
    line-height: 26px;
    color: var(--c-body-3);
}

/* Anchored sections must clear the fixed header when jumped to. */
[id] { scroll-margin-top: calc(var(--hdr-h) + 12px); }

/* ----------------------------------------------------- shared controls ---- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 16px 32px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-family: var(--f-display);
    font-weight: 600;
    font-size: 15px;
    line-height: 21.5px;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.btn--white   { background: #fff; color: var(--c-ink-btn); }
/* Hover only where there is a pointer that hovers: on touch screens a tap
   would otherwise leave the hover state stuck on until the next tap. */
@media (hover: hover) {
    .btn--white:hover   { background: var(--c-accent); }
}
.btn--outline { background: transparent; border-color: #fff; color: #fff; }
@media (hover: hover) {
    .btn--outline:hover { background: #fff; color: var(--c-ink-btn); }
}
.btn--primary { background: var(--c-blue-600); color: #fff; }
@media (hover: hover) {
    .btn--primary:hover { background: var(--c-navy-600); }
}

/* Mono technology pill, used on project cards and service cards. */
.tag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 4px 12px;
    border: 1px solid var(--c-tag-border);
    border-radius: 4px;
    background: var(--c-tag-bg);
    color: var(--c-tag-ink);
    font-family: var(--f-mono);
    font-weight: 500;
    font-size: 12px;
    line-height: 14.5px;
    white-space: nowrap;
}
.tags { display: flex; flex-wrap: wrap; gap: 14px; }

/* Outlined "View project" pill. */
.pill-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 8px 20px;
    border: 1px solid var(--c-navy-600);
    border-radius: 12px;
    color: var(--c-navy-600);
    font-family: var(--f-display);
    font-weight: 600;
    font-size: 14px;
    line-height: 21.5px;
    transition: background-color .18s ease, color .18s ease;
}
.pill-link img { width: 24px; height: 24px; transition: transform .18s ease; }
@media (hover: hover) {
    .pill-link:hover { background: var(--c-navy-600); color: #fff; }
    .pill-link:hover img { transform: translateX(3px); filter: brightness(0) invert(1); }
}

/* Round arrow button on the Applied R&D card. Two stacked arrows slide
   sideways on hover, which is how the design's Button Arrow variants read. */
.arrow-btn {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 20px;
    width: 40px;
    height: 40px;
    padding: 8px;
    border: 2px solid var(--c-blue-600);
    border-radius: 100px;
    background: #fff;
    overflow: hidden;
    transition: background-color .18s ease;
}
.arrow-btn img {
    flex: none;
    width: 24px;
    height: 24px;
    transform: rotate(-90deg);
    transition: transform .25s ease;
}

/* ------------------------------------------------------------- header ---- */

#hdr {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 50;
    height: var(--hdr-h);
    background: rgba(14, 51, 88, .1);
    -webkit-backdrop-filter: blur(12.5px);
    backdrop-filter: blur(12.5px);
    transition: background-color .25s ease;
}
/* Past the hero the translucent bar would sit on a light section, so it
   solidifies. Matches the behaviour the previous homepage already had. */
#hdr.solid { background: rgba(8, 27, 54, .92); }

#hdr .bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--hdr-h);
}
#hdr .logo img { width: 151px; height: 30px; object-fit: contain; }

#hdr nav {
    display: flex;
    align-items: center;
    gap: 29px;
}
#hdr nav a {
    font-family: var(--f-display);
    font-weight: 400;
    font-size: 14px;
    line-height: 19.5px;
    color: rgba(255, 255, 255, .9);
    transition: color .18s ease;
}
@media (hover: hover) {
    #hdr nav a:hover { color: #fff; }
}
#hdr nav .btn { padding: 10px 20px; }

/* Burger, only shown once the inline nav no longer fits. */
.nav-toggle {
    display: none;
    width: 44px; height: 44px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, .6);
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
}
.nav-toggle span,
.nav-toggle span::before,
.nav-toggle span::after {
    display: block;
    width: 18px; height: 2px;
    margin: 0 auto;
    background: #fff;
    content: '';
}
.nav-toggle span::before { transform: translateY(-6px); }
.nav-toggle span::after  { transform: translateY(4px); }

/* --------------------------------------------------------------- hero ---- */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 1022px;
    padding: 140px 0 80px;
    overflow: hidden;
    background: linear-gradient(to right, var(--c-navy-700), var(--c-navy-600));
}

.hero__bg { position: absolute; inset: 0; pointer-events: none; }
.hero__bg img {
    position: absolute;
    top: -2.81%;
    left: 11.97%;
    width: 100%;
    height: 105.63%;
    max-width: none;
    object-fit: cover;
}
.hero__bg::after {
    position: absolute;
    inset: 0;
    content: '';
    background:
        linear-gradient(180deg, rgba(4, 19, 33, 0) 0%, rgba(4, 19, 33, 0) 50%, rgb(14, 51, 88) 100%),
        linear-gradient(270deg, rgba(14, 51, 88, 0) .81%, rgb(6, 18, 33) 67.04%, rgb(6, 18, 33) 100%);
}

.hero .wrap {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-self: stretch;
    padding-top: 40px;
}

.hero__top { display: flex; flex-direction: column; gap: 24px; }

.hero h1 {
    max-width: 1087px;
    font-size: 60px;
    line-height: 68px;
    letter-spacing: -1px;
    color: #fff;
}
.hero h1 .accent { color: var(--c-accent); }

.hero__meta {
    max-width: 869px;
    font-family: var(--f-mono);
    font-weight: 500;
    font-size: 16px;
    line-height: 28px;
    letter-spacing: .25px;
    color: rgba(255, 255, 255, .85);
}
.hero__meta .accent { color: var(--c-accent); }

.hero__ctas { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 20px; }

/* Three capability strips pinned to the bottom of the hero. */
.hero__tabs {
    display: flex;
    gap: 20px;
    margin-top: 60px;
}
.hero__tab {
    display: flex;
    flex: 1 1 0;
    min-width: 0;
    align-items: center;
    gap: 20px;
    padding-top: 16px;
    border-top: 1px solid #fff;
}
.hero__tab img { width: 24px; height: 24px; flex: none; }
/* The design sets these on one line each, letting the longer subtitle run a
   few pixels into the gap rather than wrapping. */
.hero__tab > span { min-width: 0; }
/* Figma sets each tile's two lines without wrapping, the longest subtitle
   running ~5px into the gap. That only fits at the full 1320px column; on a
   laptop it would run into the next tile's icon, so below this they wrap. */
@media (min-width: 1340px) {
    .hero__tab > span { white-space: nowrap; }
}
.hero__tab h2 {
    font-size: 17px;
    line-height: 24px;
    font-weight: 500;
    color: #fff;
}
.hero__tab p {
    margin-top: 2px;
    font-family: var(--f-mono);
    font-weight: 400;
    font-size: 14px;
    line-height: 16.5px;
    color: rgba(255, 255, 255, .72);
}

/* --------------------------------------------------------------- work ---- */

.work__top {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 40px;
}

.work__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
}

.work-card { display: flex; flex-direction: column; }

.work-card__media {
    position: relative;
    height: 340px;
    border-radius: 4px;
    overflow: hidden;
}
.work-card__media > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Tags sit under the image, above the title. The design shows three; the CMS
   can return more, so they wrap rather than running off the card's edge. */
.work-card__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 20px;
}
.work-card__tags + .work-card__body { padding-top: 12px; }

.work-card__body {
    display: flex;
    flex-direction: column;
    gap: 24px;
    padding: 20px 20px 0 0;
}
.work-card h3 {
    font-size: 24px;
    line-height: 32px;
    letter-spacing: -.18px;
}
.work-card__desc {
    margin-top: 8px;
    font-size: 16px;
    line-height: 24px;
    color: var(--c-body-2);
}

/* --------------------------------------------------------- industries ---- */

.ind__head { max-width: 692px; margin-bottom: 40px; }
.ind__head .sec-lead { margin-top: 12px; color: var(--c-ink); }

.ind__list { display: flex; flex-direction: column; gap: 20px; }

/* The design stacks these cards: each one sticks under the header as the next
   scrolls up over it. */
/* Stacking cards. --ind-peek is how much of each covered card stays visible:
   border 1 + padding 24 + icon 40 + gap 24 + title 36 = 125px to the bottom of
   the title; the lead paragraph's line box starts 8px below that, at 133. 132
   shows the whole title with air under it and none of the paragraph, so no
   half-cut line of text peeks out. */
.ind__list { --ind-peek: 132px; }
.ind-card:nth-child(2) { --ind-i: 1; }
.ind-card:nth-child(3) { --ind-i: 2; }
.ind-card:nth-child(4) { --ind-i: 3; }

.ind-card {
    position: sticky;
    top: calc(var(--hdr-h) + 20px + var(--ind-i, 0) * var(--ind-peek));
    display: flex;
    align-items: stretch;
    gap: 40px;
    border: 1px solid rgba(11, 24, 38, .1);
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}
.ind-card__text {
    display: flex;
    flex: 1 1 0;
    min-width: 0;
    flex-direction: column;
    gap: 16px;
    padding: 24px 0 24px 24px;
}
.ind-card__icon { width: 40px; height: 40px; }
.ind-card h3 {
    margin-top: 24px;
    font-size: 28px;
    line-height: 36px;
    letter-spacing: -.18px;
}
.ind-card__lead {
    margin-top: 8px;
    font-size: 15.5px;
    line-height: 25.575px;
    color: var(--c-ink);
}
.ind-card__rule {
    height: 1px;
    border-radius: 10000px;
    background: rgba(11, 24, 38, .2);
}
.ind-card__benefits {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}
.ind-card__benefits > div { width: 297px; max-width: 100%; }
.ind-card__benefits h4 {
    font-size: 16px;
    line-height: 20px;
}
.ind-card__benefits p {
    margin-top: 5px;
    font-size: 16px;
    line-height: 20px;
    color: var(--c-body-3);
}
/* The photo fills the height the text column sets, rather than its own
   intrinsic height setting the height of the card. */
.ind-card__media {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    align-self: stretch;
}
.ind-card__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ----------------------------------------------------------- services ---- */

.svc__head { margin-bottom: 32px; }
.svc__head .sec-lead { margin-top: 8px; }

.svc__rows { display: flex; flex-direction: column; gap: 20px; }
.svc__row { display: grid; gap: 20px; }
.svc__row--2 { grid-template-columns: repeat(2, 1fr); }
.svc__row--3 { grid-template-columns: repeat(3, 1fr); }
/* Row heights come from the design (305px and 400px). */
.svc__row--2 .svc-card { min-height: 305px; }
.svc__row--3 .svc-card { min-height: 400px; }

.svc-card {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 20px;
    padding: 32px;
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}
.svc-card__icon { width: 40px; height: 40px; }
.svc-card h3 {
    margin-top: 24px;
    font-size: 28px;
    line-height: 36px;
    letter-spacing: -.18px;
}
.svc-card__desc {
    margin-top: 8px;
    font-size: 18px;
    line-height: 26px;
    color: var(--c-body);
}
.svc-card .tags { margin-top: 28px; }

/* Cards that lead to a service page. "Stretched link": the title is the real
   link -- so its accessible name is just the title, not the whole card -- and
   its ::after covers the card so the whole card is clickable. The round arrow
   is the visual cue. */
.svc-card__link { color: inherit; }
.svc-card__link::after {
    position: absolute;
    inset: 0;
    z-index: 1;
    content: '';
}
.svc-card__link:focus-visible { outline: none; }
.svc-card--link:focus-within { outline: 2px solid var(--c-blue-600); outline-offset: 3px; }
/* Bottom-right, as in the design. Tag rows keep clear of it. */
.svc-card--link .tags { padding-right: 56px; }
.svc-card--link .arrow-btn {
    position: absolute;
    right: 32px;
    bottom: 32px;
}
@media (hover: hover) {
    .svc-card--link:hover .arrow-btn { background: var(--c-blue-600); }
    .svc-card--link:hover .arrow-btn img { transform: rotate(-90deg) translateY(44px); }
}

/* ------------------------------------------------------------- engage ---- */

.engage__head { margin-bottom: 40px; }
.engage__head .sec-lead { margin-top: 12px; }

.engage__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
}
.engage-card { display: flex; flex-direction: column; gap: 20px; }
.engage-card h3 {
    font-size: 28px;
    line-height: 36px;
    letter-spacing: -.18px;
}
.engage-card p {
    margin-top: 8px;
    font-size: 16px;
    line-height: 24px;
    color: var(--c-body-2);
}
.engage-card__media {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 280px;
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}
.engage-card__media img {
    width: 280px;
    height: 280px;
    max-width: 100%;
    object-fit: contain;
}

/* ------------------------------------------------------------ clients ---- */

.clients__head { max-width: 610px; margin-bottom: 40px; }
.clients__head .sec-title { color: var(--c-ink); }
.clients__head .sec-lead { margin-top: 8px; color: var(--c-body); }

/* Four across at the design width (4 x 315 + 3 x 20 = 1320). auto-fit keeps
   the card at its designed size when the CMS holds fewer than four clients,
   instead of stretching one card over the whole row or leaving it marooned
   in a four-column track. */
.clients__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 315px));
    justify-content: start;
    gap: 20px;
}
.quote-card {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 16px;
    margin: 0; /* <figure> ships with a 40px side margin */
    border-radius: 8px;
    background: #fff;
}
.quote-card blockquote {
    margin: 0;
    padding: 20px 20px 0;
    font-weight: 500;
    font-size: 18px;
    line-height: 26px;
    color: var(--c-navy-600);
}
.quote-card__by {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0 20px 20px;
}
/* A fixed 180x54 slot, as drawn. Uploaded logos vary wildly in aspect, so the
   box stays constant and the logo is fitted inside it -- that way every card's
   logo and caption sit on the same baseline whatever was uploaded. */
.quote-card__by img {
    width: 180px;
    max-width: 100%;
    height: 54px;
    object-fit: contain;
    object-position: left center;
}
/* Only rendered when the client has a url. Sized to the logo so the clickable
   area matches what is visible, rather than stretching across the card as a
   full-width flex item would. */
.quote-card__by .logo-link {
    align-self: flex-start;
    width: 180px;
    max-width: 100%;
    line-height: 0;
    transition: opacity .18s ease;
}
@media (hover: hover) {
    .quote-card__by .logo-link:hover { opacity: .65; }
}

/* Set by the controller on logos squarer than the slot: fill it by cropping
   the middle, so every logo reads at the same size instead of one of them
   shrinking to fit its own proportions. */
.quote-card__by img.is-cropped {
    object-fit: cover;
    object-position: center;
}

/* A client with a logo but no quote yet: the caption sits at the top of the
   card rather than being pushed to the bottom by an absent blockquote. */
.quote-card--logo { justify-content: flex-start; }
.quote-card--logo .quote-card__by { padding-top: 20px; }
.quote-card__by span {
    font-weight: 500;
    font-size: 16px;
    line-height: 20px;
    color: rgba(11, 24, 38, .6);
}

/* -------------------------------------------------------------- about ---- */

.about__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
}
.about__top .sec-title { width: 505px; max-width: 100%; }

.about__stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    width: 640px;
    max-width: 100%;
}
.about__stat {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 24px;
    border-radius: 8px;
    background: #fff;
}
.about__stat b {
    font-family: var(--f-display);
    font-weight: 500;
    font-size: 48px;
    line-height: 56px;
    letter-spacing: -.68px;
    color: var(--c-ink);
    white-space: nowrap;
}
.about__stat span {
    font-size: 18px;
    line-height: 26px;
    color: var(--c-body-4);
}

.about__cols {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 40px;
    margin-top: 40px;
    font-size: 18px;
    line-height: 26px;
    color: var(--c-ink);
}

/* Disclosure. The design shows the same section in a collapsed and an
   expanded state; the chevron is one asset, rotated for each. */
.about__toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 40px;
    padding: 0;
    border: 0;
    background: none;
    font-family: var(--f-text);
    font-weight: 600;
    font-size: 18px;
    line-height: 26px;
    color: var(--c-ink);
    cursor: pointer;
}
.about__toggle img {
    width: 24px;
    height: 24px;
    transform: rotate(-90deg);
    transition: transform .25s ease;
}
.about__toggle[aria-expanded='true'] img { transform: rotate(90deg); }

.about__more { display: none; margin-top: 40px; }
.about__more.open { display: block; }
.about__more-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
}
.about__more-grid .card {
    padding: 32px;
    border-radius: 8px;
    background: #fff;
}
.about__more-grid img { width: 40px; height: 40px; }
.about__more-grid h3 {
    margin-top: 24px;
    font-size: 24px;
    line-height: 32px;
    letter-spacing: -.18px;
}
.about__more-grid p {
    margin-top: 8px;
    font-size: 18px;
    line-height: 26px;
    color: var(--c-body);
}

/* --------------------------------------------------------------- team ---- */

.team__head { margin-bottom: 40px; }
.team__head .sec-title { color: var(--c-ink); }
.team__head .sec-lead { margin-top: 12px; color: var(--c-body); }

.team__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
}
.member {
    display: flex;
    flex-direction: column;
    min-height: 482px;
    border-radius: 20px;
    background: #fff;
    overflow: hidden;
}
/* As on the industry cards, the portrait fills the space the card leaves it
   instead of its own aspect ratio setting the card height. */
.member__photo {
    position: relative;
    flex: 1 1 auto;
    min-height: 240px;
}
.member__photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.member__body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
}
.member__name {
    display: flex;
    align-items: center;
    gap: 10px;
}
.member__name h3 {
    flex: 1 1 0;
    min-width: 0;
    font-size: 24px;
    line-height: 32px;
    letter-spacing: -.18px;
}
.member__name img { width: 24px; height: 24px; flex: none; }
.member__role {
    font-size: 18px;
    line-height: 26px;
    color: var(--c-body);
}
.member__bio {
    font-size: 14px;
    line-height: 23.1px;
    color: var(--c-body);
}

/* ------------------------------------------------------------ contact ---- */

.contact {
    padding: 120px 0;
    border-top: 1px solid rgba(255, 255, 255, .18);
    background: var(--c-blue-600);
    overflow: hidden;
}
.contact .wrap {
    display: flex;
    align-items: flex-start;
    gap: 76px;
}
.contact__copy { width: 612px; max-width: 100%; }
.contact__copy h2 {
    font-size: 48px;
    line-height: 56px;
    letter-spacing: -.68px;
    color: #fff;
}
.contact__copy p {
    margin-top: 8px;
    font-size: 18px;
    line-height: 26px;
    color: rgba(255, 255, 255, .9);
}

.contact__form {
    display: flex;
    flex-direction: column;
    gap: 20px;
    width: 632px;
    max-width: 100%;
}
.contact__row {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
}
.field { display: flex; flex-direction: column; gap: 7px; }
.field label {
    font-size: 13px;
    line-height: 18.5px;
    color: #fff;
}
.field input,
.field textarea {
    width: 100%;
    padding: 13px 15px;
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 4px;
    background: rgba(255, 255, 255, .4);
    font-family: var(--f-text);
    font-size: 15px;
    line-height: 21.5px;
    color: var(--c-ink);
}
.field textarea { height: 138px; resize: vertical; }
.field input::placeholder,
.field textarea::placeholder { color: rgba(11, 24, 38, .7); }
.field input:focus,
.field textarea:focus {
    outline: none;
    border-color: #fff;
    background: rgba(255, 255, 255, .62);
}
.contact__form .btn { align-self: flex-start; }
/* Off-screen rather than display:none, which some bots know to skip. */
.contact__trap {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}
.form-note { font-size: 15px; line-height: 22px; color: #fff; }

/* ------------------------------------------------------------- footer ---- */

footer {
    padding: 80px 0;
    border-top: 1px solid rgba(255, 255, 255, .18);
    background: var(--c-navy-900);
}
.f-grid {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 40px;
}
.f-grid > div { min-width: 0; }
.f-brand { width: 362px; max-width: 100%; }
.f-brand img { width: 141px; height: 28px; object-fit: contain; }
.f-brand p {
    margin-top: 14px;
    font-size: 18px;
    line-height: 26px;
    color: rgba(255, 255, 255, .6);
}
.f-col h2 {
    font-family: var(--f-display);
    font-weight: 500;
    font-size: 14px;
    line-height: 19.5px;
    color: #fff;
}
.f-col ul {
    margin: 15px 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.f-col li,
.f-col a,
.f-col span {
    font-size: 18px;
    line-height: 26px;
    color: rgba(255, 255, 255, .6);
}
@media (hover: hover) {
    .f-col a:hover { color: #fff; }
}

.f-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    height: 63px;
    margin-top: 42px;
    border-top: 1px solid rgba(255, 255, 255, .1);
    font-size: 18px;
    line-height: 26px;
    color: rgba(255, 255, 255, .6);
}

/* ------------------------------------------------------------ subpages ---- */

/* Service landing pages (/computer-vision, /machine-learning,
   /cpp-qt-development): the homepage hero, shorter, over the page's own banner
   photo. The banners are dark navy with the subject on the right, so a light
   left-side gradient is enough to keep the text readable. */
.hero--page {
    min-height: 620px;
    padding: calc(var(--hdr-h) + 80px) 0 80px;
}
.hero--page .wrap { justify-content: center; padding-top: 0; }
.hero--page .hero__bg img {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: right center;
}
.hero--page .hero__bg::after {
    background:
        linear-gradient(180deg, rgba(4, 19, 33, 0) 55%, rgb(14, 51, 88) 100%),
        linear-gradient(90deg, rgba(6, 18, 33, .85) 0%, rgba(6, 18, 33, .55) 45%, rgba(6, 18, 33, 0) 75%);
}
.hero--page h1 { max-width: 860px; font-size: 52px; line-height: 60px; }

/* Pages without a hero photo (/portfolio and project pages): the same navy
   band, compact. Still a .hero, so the header goes solid below it. */
.hero--compact {
    min-height: 0;
    padding: calc(var(--hdr-h) + 72px) 0 72px;
}
.hero--compact .wrap { padding-top: 0; }
.hero--compact h1 { max-width: 980px; font-size: 48px; line-height: 56px; }
.hero--compact .tags { margin-top: 4px; }

.hero__lead {
    max-width: 760px;
    font-size: 20px;
    line-height: 30px;
    color: rgba(255, 255, 255, .85);
}

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    font-family: var(--f-display);
    font-weight: 600;
    font-size: 14px;
    line-height: 21.5px;
    color: rgba(255, 255, 255, .8);
}
.back-link img { width: 20px; height: 20px; transform: rotate(180deg); filter: brightness(0) invert(1); opacity: .8; }
@media (hover: hover) {
    .back-link:hover { color: #fff; }
}

/* Rich text written in the admin editor (service intros, project
   descriptions). Most of it was pasted from Google Docs and every span carries
   inline font, size and colour (Arial 11pt, black); those are neutralised here
   rather than edited out of the stored content. */
.page-lead {
    max-width: 820px;
    margin-bottom: 24px;
    font-family: var(--f-display);
    font-weight: 500;
    font-size: 24px;
    line-height: 32px;
    color: var(--c-navy-600);
}
.rich {
    max-width: 820px;
    font-size: 18px;
    line-height: 28px;
    color: var(--c-ink);
}
.rich [style] {
    font-family: inherit !important;
    font-size: inherit !important;
    line-height: inherit !important;
    color: inherit !important;
    background: none !important;
}
.rich h2, .rich h3, .rich h4 {
    margin: 40px 0 12px;
    font-family: var(--f-display);
    font-weight: 500;
    font-size: 24px;
    line-height: 32px;
    letter-spacing: -.18px;
    color: var(--c-navy-600);
}
.rich > :first-child { margin-top: 0; }
.rich p { margin: 0 0 16px; }
.rich ul, .rich ol { margin: 0 0 16px; padding-left: 1.3em; }
.rich li { margin-bottom: 6px; }
.rich li p { margin: 0; }
.rich a { color: var(--c-blue-600); text-decoration: underline; }
.rich strong, .rich b { font-weight: 600; }

/* /portfolio: the homepage work grid, wrapping onto many rows. The cards have
   no background -- the text sits under the photo -- so rows need more air
   between them than the 20px column gap. */
.work__grid--all { row-gap: 48px; }

/* Technology filter. Needs JavaScript, so it only appears once html.js is set
   -- without it there is nothing to hide and every project simply shows. */
.filters { display: none; }
.js .filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 40px;
}
/* Same shape and type as the site's .btn (4px corners, 15px semibold), at the
   compact padding of the header's Contact button; the selected filter takes
   the primary button's colour ("View all projects"). */
.filter {
    padding: 10px 20px;
    border: 1px solid var(--c-blue-600);
    border-radius: 4px;
    background: transparent;
    font-family: var(--f-display);
    font-weight: 600;
    font-size: 15px;
    line-height: 21.5px;
    color: var(--c-blue-600);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .18s ease, color .18s ease;
}
.filter[aria-pressed='true'] { background: var(--c-blue-600); color: #fff; }
@media (hover: hover) {
    .filter[aria-pressed='false']:hover { background: var(--c-surface-b); }
}
/* .work-card is display:flex, which beats the browser's own [hidden] rule. */
.work-card[hidden] { display: none; }

/* Project page. */
.project__video {
    max-width: 960px;
    margin-top: 48px;
    aspect-ratio: 16 / 9;
    border-radius: 8px;
    background: var(--c-navy-850);
    overflow: hidden;
}
.project__video iframe { display: block; width: 100%; height: 100%; border: 0; }
.project__gallery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    align-items: start;
    gap: 20px;
    margin-top: 48px;
}
.project__gallery a { display: block; border-radius: 8px; background: #fff; overflow: hidden; }
.project__gallery img { width: 100%; height: auto; }
.project__more { margin-top: 48px; }

@media (max-width: 1024px) {
    .hero--page, .hero--compact { padding: calc(var(--hdr-h) + 56px) 0 56px; }
    .hero--page { min-height: 0; }
    .hero--page .hero__bg::after {
        background:
            linear-gradient(180deg, rgba(4, 19, 33, 0) 55%, rgb(14, 51, 88) 100%),
            linear-gradient(90deg, rgba(6, 18, 33, .9) 0%, rgba(6, 18, 33, .7) 60%, rgba(6, 18, 33, .4) 100%);
    }
    .hero--compact h1 { font-size: 36px; line-height: 44px; }
}

@media (max-width: 680px) {
    .hero__lead { font-size: 17px; line-height: 26px; }
    .hero--compact h1 { font-size: 30px; line-height: 38px; }
    .page-lead { font-size: 20px; line-height: 28px; }
    .rich { font-size: 17px; line-height: 27px; }
    .project__gallery { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------- responsive ---- */

/* The nav loses room before the content column does. */
@media (max-width: 1080px) {
    #hdr nav {
        position: absolute;
        top: var(--hdr-h);
        left: 0; right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: 8px var(--gutter) 20px;
        background: rgba(8, 27, 54, .97);
        -webkit-backdrop-filter: blur(12.5px);
        backdrop-filter: blur(12.5px);
    }
    #hdr nav:not(.open) { display: none; }
    #hdr nav a { padding: 12px 0; font-size: 16px; }
    /* The menu is a stretching flex column; keep Contact at its own size. */
    #hdr nav .btn { margin-top: 12px; align-self: flex-start; }
    .nav-toggle { display: block; }
}

@media (max-width: 1024px) {
    :root { --pad-y: 96px; }

    .hero { min-height: 0; padding: calc(var(--hdr-h) + 72px) 0 72px; }
    .hero h1 { font-size: 44px; line-height: 52px; letter-spacing: -.6px; }
    .hero__bg img { left: 0; }
    .hero__tabs { flex-direction: column; gap: 16px; margin-top: 56px; }

    .sec-title { font-size: 36px; line-height: 44px; letter-spacing: -.4px; }
    /* The designed line break only makes sense at full width; on narrow
       screens it strands a single word. */
    .ind__head .sec-title br { display: none; }

    .work__grid { grid-template-columns: repeat(2, 1fr); }
    .clients__grid,
    .team__grid,
    .about__more-grid { grid-template-columns: repeat(2, 1fr); }

    /* Stacking cards need a tall viewport to be legible; below this they
       simply flow. */
    .ind-card { position: static; flex-direction: column; gap: 0; }
    .ind-card__text { padding: 24px; }
    .ind-card__media { order: -1; height: 260px; flex: none; align-self: auto; }

    .svc__row--2,
    .svc__row--3 { grid-template-columns: 1fr; }
    .svc__row--2 .svc-card,
    .svc__row--3 .svc-card { min-height: 0; }

    .engage__grid { grid-template-columns: 1fr; }

    .about__top { flex-direction: column; align-items: flex-start; gap: 32px; }
    .about__stats { width: 100%; }
    .about__cols { grid-template-columns: 1fr; gap: 20px; }

    .contact { padding: 96px 0; }
    .contact .wrap { flex-direction: column; gap: 40px; }
    .contact__copy h2 { font-size: 36px; line-height: 44px; }

    .f-grid { flex-wrap: wrap; gap: 32px 40px; }
    .f-brand { width: 100%; }
}

@media (max-width: 680px) {
    :root { --pad-y: 72px; --gutter: 20px; }

    .hero h1 { font-size: 34px; line-height: 42px; }
    .hero__meta { font-size: 14px; line-height: 24px; }

    .sec-title { font-size: 30px; line-height: 38px; }

    .work__top { flex-direction: column; align-items: flex-start; }
    .work__grid { grid-template-columns: 1fr; }

    .ind-card h3,
    .svc-card h3,
    .engage-card h3 { font-size: 24px; line-height: 32px; }
    .ind-card__benefits { gap: 16px; }
    .ind-card__benefits > div { width: 100%; }

    .clients__grid,
    .team__grid,
    .about__more-grid { grid-template-columns: 1fr; }
    .about__stats { grid-template-columns: 1fr; }
    .about__stat b { font-size: 36px; line-height: 44px; }

    .contact__row { grid-template-columns: 1fr; }
    .contact__copy h2 { font-size: 28px; line-height: 36px; }

    .f-bottom {
        flex-direction: column;
        align-items: flex-start;
        height: auto;
        padding: 20px 0;
        gap: 10px;
    }
    .member { min-height: 0; }
}

/* ------------------------------------------------- phone carousels ---- */

/* Any list of three or more cards becomes a horizontal, swipeable strip on
   phones, with prev/next arrows -- the same pattern the previous site built
   with Owl Carousel, done here with native scroll-snap instead: touch swipe,
   momentum and snapping come from the browser, and nothing needs jQuery.

   Lists are marked data-carousel in the template. The arrows (data-carousel-
   nav) need JavaScript, so they show only once html.js is set; without it
   the strip still swipes. */
.carousel-nav { display: none; }

.carousel-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;               /* minimum comfortable touch target */
    height: 44px;
    padding: 0;
    border: 2px solid var(--c-blue-600);
    border-radius: 100px;
    background: #fff;
    cursor: pointer;
    transition: background-color .18s ease, opacity .18s ease, transform .12s ease;
}
/* One arrow asset (the design's arrow-down), rotated per direction. */
.carousel-btn img { width: 24px; height: 24px; transform: rotate(90deg); }
.carousel-btn--next img { transform: rotate(-90deg); }
.carousel-btn:disabled { opacity: .35; cursor: default; }
.carousel-btn:active:not(:disabled) { transform: scale(.94); }
@media (hover: hover) {
    .carousel-btn:hover:not(:disabled) { background: var(--c-surface-b); }
}

@media (max-width: 680px) {
    [data-carousel] {
        display: flex;
        flex-direction: row;
        align-items: stretch;
        /* gap = gutter: with the strip bled to the screen edges, the next
           card then starts exactly at the right edge -- one card in view,
           none of its neighbours. */
        gap: var(--gutter);
        /* Bleed to the screen edges so a card can slide fully out of view,
           while the snapped card still lines up with the page gutter. */
        margin-inline: calc(var(--gutter) * -1);
        padding: 0 var(--gutter) 4px;
        scroll-padding-inline: var(--gutter);
        overflow-x: auto;
        overscroll-behavior-x: contain;   /* no accidental back-navigation */
        scroll-snap-type: x mandatory;
        scrollbar-width: none;
    }
    [data-carousel]::-webkit-scrollbar { display: none; }

    /* One full-width card at a time; the arrows are what say there's more.
       snap-stop keeps a hard fling from skipping past cards. */
    [data-carousel] > *,
    [data-carousel] .svc-card {
        flex: 0 0 100%;
        min-width: 0;
        scroll-snap-align: start;
        scroll-snap-stop: always;
    }

    /* Services are drawn as a row of two plus a row of three; on a phone they
       are one strip of five, so the row wrappers step out of the way. */
    .svc__rows[data-carousel] > .svc__row { display: contents; }

    .js .carousel-nav {
        display: flex;
        justify-content: flex-end;
        gap: 12px;
        margin-top: 20px;
    }

    /* Three tiny stat tiles: a carousel would show one number at a time and
       stacking them costs a screen of scrolling, so they sit three-up. */
    .about__stats { grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .about__stat { gap: 6px; padding: 14px 10px; }
    .about__stat b {
        font-size: clamp(18px, 5.6vw, 24px);
        line-height: 1.2;
        letter-spacing: -.2px;
        white-space: normal;
    }
    .about__stat span { font-size: 14px; line-height: 18px; }

    /* Touch targets: the pill and the footer links were sized for a mouse. */
    .pill-link { min-height: 44px; }
    .f-col ul { gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
}
