/* ── Variables ───────────────────────────────────────────────────────────── */
:root {
    --font-family: 'Space Grotesk', sans-serif;
    --font-heading: 'Anton', sans-serif;
    --fs-badge: 0.744rem;
    --fs-300: 0.787rem;
    --fs-400: 0.95rem;
    --fs-500: 1.225rem;
    --fs-600: 2rem;
    --fs-800: 3rem;
    --clr-bg: #fff;
    --clr-page-bg: #edf2f4;
    --clr-dark: #14252e;
    --clr-default: #2c4650;
    --clr-muted: #4f6976;
    --clr-heading: #5fa1bd;
    --clr-blue-light: #8fc4d8;
    --clr-border: rgba(41, 41, 41, 0.14);
    --clr-tint: rgba(95, 161, 189, 0.2);
    --clr-accent-500: #ff5f19;
    --clr-accent-700: #cc4913;
    --clr-accent-tint: rgba(255, 95, 25, 0.16);
    --clr-error-500: hsl(12, 85%, 55%);
    --max-content-width: 1040px;
    --default-gap: 16px;
    --hero-gap: 20px;
    --card-shadow: 0 2px 4px rgba(41, 41, 41, 0.18);
    --card-shadow-hover: 0 6px 8px rgba(41, 41, 41, 0.26);
    --card-shadow-dark: 0 2px 4px rgba(0, 0, 0, 0.25);
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    background-color: var(--clr-page-bg);
    background-image: url('/site/images/grain.png');
    background-repeat: repeat;
}

body,
input,
textarea,
button {
    font-family: var(--font-family);
    font-size: var(--fs-400);
    color: var(--clr-default);
    line-height: 1.65;
}

a {
    color: var(--clr-accent-500);
    text-decoration: none;
    background-image: linear-gradient(currentColor, currentColor);
    background-repeat: no-repeat;
    background-position: right bottom;
    background-size: 0% 1px;
    transition: background-size 0.25s ease, color 0.25s ease;
}

a:hover {
    color: var(--clr-accent-700);
    background-position: left bottom;
    background-size: 100% 1px;
}

/* Inline icons inside links/buttons (external-link arrows, paper plane, ...) */
.btn svg,
button svg,
a svg,
.case-study__status svg {
    width: 13px;
    height: 13px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

ul {
    list-style: none;
}

h1,
h2,
.main-header__logo,
.related-card__label {
    font-family: var(--font-heading);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0;
}

h1 {
    color: var(--clr-heading);
    font-size: var(--fs-800);
    line-height: 0.98;
    margin-bottom: var(--hero-gap);
}

h1 .accent {
    color: var(--clr-accent-500);
}

h2,
.main-header__logo {
    font-size: var(--fs-600);
    align-items: center;
    gap: 0.35em;
}

h2 {
    display: flex;
    margin-bottom: 20px;
}

/* Small square accent mark, reused before h2 titles and the header logo. */
h2::before,
.main-header__logo::before {
    content: '';
    background: var(--clr-accent-500);
    display: inline-block;
    flex-shrink: 0;
}

/* Sized relative to font-size. */
h2::before,
.main-header__logo::before {
    width: 0.425em;
    height: 0.425em;
}

@keyframes square-jump {
    0%   { transform: translateY(0) scale(1); }
    14%  { transform: translateY(2px) scale(1.14, 0.84); }
    38%  { transform: translateY(-8px) scale(1.08, 0.92); }
    58%  { transform: translateY(0) scale(0.86, 1.14); }
    72%  { transform: translateY(-3px) scale(1.04, 0.96); }
    86%  { transform: translateY(0) scale(0.94, 1.06); }
    94%  { transform: translateY(-1px) scale(1.01, 0.99); }
    100% { transform: translateY(0) scale(1); }
}

.main-header:hover .main-header__logo::before,
h2:hover::before {
    animation: square-jump 0.72s cubic-bezier(0.33, 0, 0.67, 1);
}

h3 {
    font-weight: 600;
    font-size: 1.05rem;
    margin-bottom: 8px;
}

p {
    margin-bottom: var(--default-gap);
}

p:last-child {
    margin-bottom: 0;
}

.lead {
    font-size: var(--fs-500);
    color: var(--clr-default);
    max-width: 32em;
    margin-bottom: var(--hero-gap);
}

/* ── Page shell ──────────────────────────────────────────────────────────── */
.main-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    padding: 32px 24px;
}

/* ── Layout ──────────────────────────────────────────────────────────────── */
.content-grid {
    width: 100%;
    max-width: var(--max-content-width);
    background: var(--clr-bg);
    box-shadow: var(--card-shadow);
    padding: 36px;
    position: relative;
    overflow: hidden;
}

/* Fallback for jumps to an in-page anchor (direct link, no-JS) so the sticky
   header doesn't cover the section top. site.js recalculates this precisely
   against the header's live height once it runs. */
section[id] {
    scroll-margin-top: 82px;
}

.full-width-tint {
    background: var(--clr-dark);
    color: #fff;
    box-shadow: var(--card-shadow-dark);
}

.full-width-tint .lead,
.full-width-tint p {
    color: inherit;
    opacity: 0.9;
}

.full-width-tint a {
    color: var(--clr-blue-light);
}

.full-width-tint a.btn {
    color: #fff;
}

.full-width-tint h2::before {
    background: var(--clr-blue-light);
}

.content--full-width {
    width: 100%;
}

.content--left {
    text-align: left;
}

/* ── Header ──────────────────────────────────────────────────────────────── */
.main-header {
    position: sticky;
    top: 0;
    z-index: 100;
    width: 100%;
    background: var(--clr-bg);
    box-shadow: var(--card-shadow);
    border-bottom: 1px solid var(--clr-border);
}

.main-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    max-width: var(--max-content-width);
    margin: 0 auto;
    padding: 20px 36px;
}

.main-header .content--left {
    display: flex;
    align-items: center;
    gap: 40px;
    flex: 1;
    flex-wrap: wrap;
}

.main-header__logo {
    display: inline-flex;
    line-height: 1;
    color: var(--clr-heading);
    /* Suppress the underline-on-hover from the base `a` rule; the logo reads as a heading, not body text. */
    background-image: none;
}

.main-header__logo:hover {
    color: var(--clr-heading);
    text-decoration: none;
}

.main-header__nav ul {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
}

.main-header__nav a {
    color: var(--clr-default);
}

.main-header__nav a:hover {
    color: var(--clr-accent-500);
}

.main-header__locale-switch {
    font-size: var(--fs-300);
    color: var(--clr-muted);
}

.main-header__locale-switch .active {
    font-weight: 600;
}

.main-header__locale-switch .sep {
    margin: 0 4px;
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
#section-hero {
    display: flex;
    align-items: flex-start;
    /* scales from 250px at 1100px viewport down to 200px at 641px, flat outside that range */
    padding-right: clamp(200px, calc(10.893vw + 130.18px), 250px);
}

#section-hero .hero-copy {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 680px;
    position: relative;
    z-index: 1;
    /* Stretch to the hero's full height so the wash pseudo can span the whole
       panel. Content still flows from the top. */
    align-self: stretch;
}

/* Legibility wash: panel-white behind the copy, fading to fully transparent
   on the right so the halftone mark still bleeds through. Negative insets
   bleed over the section's 36px padding so a disc near the panel edge fades
   out smoothly instead of being clipped at the text box; .content-grid's
   overflow:hidden trims the bleed to the panel. */
#section-hero .hero-copy::before {
    content: "";
    position: absolute;
    inset: -36px 0 -36px -36px;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(
        to right,
        rgb(255 255 255 / 80%) 0%,
        rgb(255 255 255 / 80%) 80%,
        rgb(255 255 255 / 0%) 100%
    );
}

/* Dark hero variant: wash matches the dark panel instead of white. */
#section-hero.full-width-tint .hero-copy::before {
    background: linear-gradient(
        to right,
        var(--clr-dark) 0%,
        var(--clr-dark) 80%,
        rgb(20 37 46 / 0%) 100%
    );
}

/* Keep a consistent rhythm between whatever leads the hero (the availability
   badge, or a "back to homepage" link on subpages) and the elements below it. */
#section-hero .hero-copy > p {
    margin-bottom: var(--hero-gap);
}

#hero-avatar,
#hero-shape {
    position: absolute;
    /* scales from -80px at 1040px viewport (full width) down to -200px at 640px */
    right: clamp(-200px, calc(30vw - 392px), -80px);
    bottom: 0px;
    height: 460px;
    width: 100%;
}

#hero-avatar canvas,
#hero-shape canvas {
    display: block;
    width: 100%;
    height: 100%;
}

/* Service-page hero mark: pinned to the right edge (no horizontal bleed,
   unlike the avatar) and stretched to the hero's full height so the top of
   the composition never clips. */
#hero-shape {
    right: 0;
    top: 0;
    bottom: 0;
    height: auto;
}

#section-hero:has(#hero-shape) {
    min-height: 492px;
}

#hero-avatar .hero-avatar-source {
    position: absolute;
    bottom: 0px;
    right: 0px;
    height: 460px;
    width: auto;
    opacity: 0;
    pointer-events: none;
}

.availability-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--clr-tint);
    color: var(--clr-default);
    font-weight: 600;
    font-size: var(--fs-badge);
    padding: 6px 14px;
    margin-bottom: var(--hero-gap);
}

.availability-badge::before {
    content: '';
    background: var(--clr-heading);
    display: inline-block;
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    animation: badge-dot-pulse 2s ease-out infinite;
}

@keyframes badge-dot-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(95, 161, 189, 0.5); }
    70%  { box-shadow: 0 0 0 4px rgba(95, 161, 189, 0); }
    100% { box-shadow: 0 0 0 0 rgba(95, 161, 189, 0); }
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
/* Shared "sweep fill" mechanics for .btn/button/.link-list a: an inset ::before
   that scales in from the right on hover. Only the fill color differs. */
.btn,
button,
.link-list a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    position: relative;
    z-index: 0;
    overflow: hidden;
    font-weight: 600;
    background-image: none;
}

.btn,
button {
    cursor: pointer;
    background: var(--clr-accent-500);
    color: #fff;
    border: none;
    padding: 9px 18px;
    font-size: var(--fs-300);
}

.btn::before,
button::before,
.link-list a::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 0.25s ease;
}

.btn::before,
button::before {
    background: var(--clr-accent-700);
}

.btn:hover::before,
button:hover::before,
.link-list a:hover::before {
    transform: scaleX(1);
    transform-origin: left;
}

.btn:hover,
button:hover {
    color: #fff;
    text-decoration: none;
}

.link-list a:hover {
    text-decoration: none;
}

/* ── Service cards ───────────────────────────────────────────────────────── */
/* Fixed column counts (rather than auto-fit) so a leftover card in an
   incomplete row keeps its normal width instead of stretching to fill it. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
    counter-reset: service;
    position: relative;
}

.card-grid:has(> :nth-child(2):last-child) {
    grid-template-columns: repeat(2, 1fr);
}

.card-grid:has(> :nth-child(4):last-child) {
    grid-template-columns: repeat(2, 1fr);
}

.card-grid:has(> :only-child) {
    grid-template-columns: minmax(0, 400px);
    justify-content: center;
}

.card {
    min-height: 200px;
    padding: 28px;
    position: relative;
    counter-increment: service;
}

.card h3,
.card p {
    position: relative;
    z-index: 1;
}

/* Big faded index number, bottom-right. On the homepage service cards it's
   replaced by the halftone .card-shape mark, so suppress it there. */
.card::before {
    content: counter(service, decimal-leading-zero);
    position: absolute;
    bottom: -60px;
    right: -10px;
    color: var(--clr-muted);
    opacity: 0.11;
    font-family: var(--font-heading);
    font-size: 260px;
    line-height: 1;
    z-index: 0;
    pointer-events: none;
}

.card:has(.card-shape)::before {
    content: none;
}

/* Faint halftone "service mark" in the bottom-right, drawn by site.js from the
   same disc arrangement as the matching service page's hero (data-shape). Sits
   behind the copy like the big index number it replaces. */
.card-shape {
    position: absolute;
    inset: 0;
    z-index: 0;
    opacity: 0.08;
    pointer-events: none;
}

.card-shape canvas {
    display: block;
    width: 100%;
    height: 100%;
}

/* ── Case studies ────────────────────────────────────────────────────────── */
/* .card and .case-study share the same panel look; .related-card joins them
   for the lift-on-hover behavior below. Both .card and .case-study set their
   own text color so they stay readable when placed on a .full-width-tint
   (dark) section, instead of inheriting its white text. */
.card,
.case-study {
    background: var(--clr-bg);
    color: var(--clr-default);
    border: 1px solid var(--clr-border);
    overflow: hidden;
    transition: transform 0.15s, box-shadow 0.15s;
}

.card:hover,
.case-study:hover,
.related-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--card-shadow-hover);
}

.case-study-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 28px;
}

/* Placeholder fills the empty slot left by an odd number of case studies; it
   only needs to render when its own position (case studies + itself) is
   even, i.e. the case study count ahead of it is odd. No top accent bar and
   no hover lift, so it reads as empty space rather than an actual card. */
.case-study-placeholder {
    display: none;
}

.case-study-list > .case-study-placeholder:nth-child(even) {
    display: block;
    min-height: 200px;
    border: 1px dashed var(--clr-border);
}

.case-study-note {
    margin-top: 24px;
    padding-left: 14px;
    border-left: 2px solid var(--clr-border);
    font-size: var(--fs-300);
    color: var(--clr-muted);
}

.case-study__top {
    height: 8px;
    background: var(--clr-accent-500);
}

.case-study__body {
    padding: 28px;
}

.case-study__tagline {
    color: var(--clr-muted);
    font-size: var(--fs-300);
    margin-bottom: 12px;
}

.case-study__stack {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 16px;
}

.case-study__stack span {
    background: var(--clr-tint);
    color: var(--clr-default);
    font-size: 0.7rem;
    padding: 4px 10px;
}

.full-width-tint .case-study__stack span {
    color: #fff;
}

.case-study__link,
.case-study__status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    font-size: var(--fs-300);
    margin-top: 16px;
}

.case-study__status {
    color: var(--clr-default);
    cursor: not-allowed;
}

/* ── Link list ───────────────────────────────────────────────────────────── */
.link-list {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 8px;
    position: relative;
}

.link-list a {
    background: var(--clr-bg);
    color: #000;
    padding: 8px 18px;
}

.link-list a::before {
    background: var(--clr-blue-light);
}

/* ── Related pages ───────────────────────────────────────────────────────── */
.related-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 24px;
    margin-top: 28px;
}

.related-card {
    display: grid;
    grid-template-columns: 1fr auto;
    align-content: start;
    column-gap: 16px;
    row-gap: 10px;
    padding: 24px;
    background: var(--clr-bg);
    color: var(--clr-default);
    border: 1px solid var(--clr-border);
    background-image: none;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}

.related-card:hover {
    border-color: var(--clr-accent-500);
    color: var(--clr-default);
    text-decoration: none;
}

.related-card__label {
    font-size: var(--fs-500);
    line-height: 1.05;
    color: var(--clr-heading);
}

.related-card__arrow {
    display: inline-flex;
    color: var(--clr-accent-500);
    transition: transform 0.15s;
}

.related-card__arrow svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.related-card:hover .related-card__arrow {
    transform: translateX(4px);
}

.related-card__blurb {
    grid-column: 1 / -1;
    font-size: var(--fs-300);
    color: var(--clr-muted);
}

/* ── Contact form ────────────────────────────────────────────────────────── */
#contact-form {
    position: relative;
    overflow: hidden;
    background: var(--clr-page-bg);
    box-shadow: 0 3px 5px rgba(41, 41, 41, 0.28);
    padding: 32px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    max-width: 640px;
    margin-top: 24px;
    transform: rotate(-0.5deg);
}

#contact-form::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: url('/site/images/contact-texture.png');
    background-size: cover;
    background-repeat: no-repeat;
    opacity: 0.5;
    mix-blend-mode: multiply;
    pointer-events: none;
}

#contact-form label {
    font-weight: 600;
    font-size: var(--fs-300);
    margin-bottom: 4px;
    display: block;
    color: var(--clr-muted);
}

#contact-form input,
#contact-form textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--clr-border);
    outline: none;
    background: var(--clr-bg);
    font-family: inherit;
    font-size: inherit;
    transition: border-color 0.28s cubic-bezier(0.4, 0, 0.2, 1),
        background-color 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}

#contact-form input:focus,
#contact-form textarea:focus {
    border-color: rgba(41, 41, 41, 0.55);
}

#contact-form textarea {
    resize: vertical;
}

#contact-form .form-footer {
    grid-column: 1 / -1;
    display: flex;
    justify-content: flex-end;
}

#contact-form input.error,
#contact-form textarea.error {
    border-color: var(--clr-error-500);
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.main-footer {
    width: 100%;
    background: var(--clr-dark);
    color: #fff;
    font-size: var(--fs-300);
}

.main-footer .dim {
    opacity: 0.75;
}

.main-footer__inner {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 16px;
    max-width: var(--max-content-width);
    margin: 0 auto;
    padding: 28px 36px;
}

.main-footer__inner p {
    margin-bottom: 0;
}

.main-footer a {
    color: var(--clr-blue-light);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
    section[id] {
        scroll-margin-top: 120px;
    }

    .card-grid,
    .card-grid:has(> :nth-child(2):last-child),
    .card-grid:has(> :nth-child(4):last-child),
    .case-study-list {
        grid-template-columns: 1fr;
    }

    .content-grid {
        padding: 28px 24px;
    }

    .main-header__inner {
        padding: 16px 24px;
    }

    /* Unwrap content--left so the logo gets its own full-width row, and nav +
       locale-switch share the row underneath (nav left, switch right). */
    .main-header .content--left {
        display: contents;
    }

    .main-header__logo {
        order: 1;
        flex: 1 1 100%;
    }

    .main-header__nav {
        order: 2;
    }

    .main-header__nav ul {
        gap: 14px;
        flex-wrap: wrap;
    }

    .main-header__locale-switch {
        order: 3;
    }

    #section-hero {
        padding: 28px 24px;
        min-height: 0;
    }

    #section-hero .hero-copy {
        max-width: 100%;
    }

    #hero-avatar,
    #hero-shape {
        display: none;
    }

    #section-hero:has(#hero-shape) {
        min-height: 0;
    }

    #contact-form {
        grid-template-columns: 1fr;
    }

    #contact-form .field-spacer {
        display: none;
    }

    .main-footer__inner {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
        padding: 24px;
    }
}
