/* ==========================================================================
   linnerprogramming.com - site stylesheet
   --------------------------------------------------------------------------
   The 2026 redesign: warm paper ground, serif headings (Newsreader, which the
   practice video already uses), IBM Plex Sans for reading copy, a mono face
   for small labels. The brand stays the same fir green.

   Colour contrast is a build constraint, not taste - every pairing below was
   checked against 4.5:1. Notes on the traps sit next to the tokens.
   ========================================================================== */

:root {
    /* Near-black with the brand's green in it. Body text, wordmark, footer. */
    --ink: #182826;

    /* Brand green. Buttons, links, the R in the wordmark. 6.9:1 on paper. */
    --primary-color: #365B56;

    /* Lighter brand green. Kept for text accents where the old site used it;
       white on it is 4.99:1, so it may be darkened, never lightened. */
    --secondary-color: #4e7773;

    /* Deep green for the dark bands (compact hero, video band). White is
       11:1 on it, --nav-accent 7.6:1. --primary-color is ~2:1 there: never
       put it on a dark band. */
    --dark-color: #24413d;

    /* Contrast-safe red for form errors. */
    --accent-color: #c0392b;

    /* Secondary text. 5.1:1 on paper, 5.6:1 on white - do not lighten. */
    --muted: #5b6b68;

    --paper: #f6f5f0;
    --surface: #ffffff;
    --tint: #e3ece9;
    --line: #e1e4df;
    --line-strong: #c4cbc6;

    /* Light accent for text and rules on the dark bands. */
    --nav-accent: #b8ded9;

    /* Legacy aliases still referenced by a few components. */
    --text-color: var(--ink);
    --light-color: var(--paper);

    /* Cards take the surface tone of the band they sit on: white on paper,
       paper on the white bands (see .section-light). */
    --card-bg: var(--surface);

    --font-sans: 'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
    --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;
    --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;

    --header-h: 72px;
    --radius: 12px;
    --radius-sm: 6px;
}

/* ---- Fonts ----
   Self-hosted: the CSP allows font-src 'self' only, and the site's privacy
   pitch would not survive a request to fonts.gstatic.com. Files come from
   Google Fonts (OFL) and are split latin / latin-ext by unicode-range, so a
   German or English page normally downloads only the latin half. German
   umlauts and ß are in the latin block. */

@font-face {
    font-family: 'Newsreader';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('/assets/fonts/newsreader-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Newsreader';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('/assets/fonts/newsreader-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 100 700;
    font-display: swap;
    src: url('/assets/fonts/plex-sans-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 100 700;
    font-display: swap;
    src: url('/assets/fonts/plex-sans-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/assets/fonts/plex-mono-500-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/assets/fonts/plex-mono-500-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ==========================================================================
   Base
   ========================================================================== */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* The browser's own `[hidden] { display: none }` loses to any author rule that
   sets `display`, so `.ref-card { display: flex }` kept filtered-out cards
   visible even though site.js had set the attribute. `!important` restores
   the intended meaning of the attribute everywhere. */
[hidden] {
    display: none !important;
}

/* NOTE: `overflow-x: hidden` here is a defensive hack, not a layout decision -
   it hides horizontal overflow rather than fixing whatever causes it, and it
   can break `position: sticky` on descendants (which is why the header is
   `fixed`, not `sticky`). Removing it needs a real browser pass across the
   breakpoints to find the actual overflowing element first, so it stays for
   now. Same for the copy on `section` below. */
html,
body {
    width: 100%;
    max-width: 100%;
    overflow-x: hidden;
}

body {
    /* On body, not on `*`: the universal selector also overrode <code> and
       <pre>, which then needed a monospace rule further down to undo it. */
    font-family: var(--font-sans);
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--ink);
    background-color: var(--paper);
    -webkit-font-smoothing: antialiased;
}

code,
pre,
kbd,
samp {
    font-family: var(--font-mono);
}

.container {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

section {
    padding: 96px 0;
    width: 100%;
    overflow-x: hidden;
}

/* ---- Headings ----
   Serif, ink, fluid. clamp() covers the whole range continuously, so there is
   one number to change and the type never jumps at a breakpoint. */
h1,
h2,
h3,
h4 {
    font-family: var(--font-serif);
    font-weight: 500;
    color: var(--ink);
    line-height: 1.12;
    letter-spacing: -0.015em;
    margin-bottom: 20px;
    text-wrap: balance;
}

h1 {
    font-size: clamp(2.2rem, 1.4rem + 3vw, 3.6rem);
}

h2 {
    font-size: clamp(1.9rem, 1.4rem + 1.8vw, 2.875rem);
    margin-bottom: 24px;
}

h3 {
    font-size: clamp(1.35rem, 1.2rem + 0.6vw, 1.75rem);
    margin-bottom: 14px;
}

h4 {
    font-size: 1.15rem;
    margin-bottom: 10px;
}

p {
    margin-bottom: 16px;
}

img {
    max-width: 100%;
    /* Required alongside the width/height attributes on <img>: lets the
       browser reserve the right space (no layout shift) while still
       scaling the image proportionally. */
    height: auto;
}

a {
    color: var(--primary-color);
}

/* ==========================================================================
   Buttons and links
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 14px 26px;
    background-color: var(--primary-color);
    color: #fff;
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
    font-weight: 500;
    font-size: 1rem;
    line-height: 1.3;
    border: 1px solid transparent;
    cursor: pointer;
    font-family: inherit;
}

.btn:hover {
    background-color: var(--dark-color);
    color: #fff;
}

.btn-primary {
    background-color: var(--primary-color);
    color: #fff;
}

/* Quiet second button: line border, ink text. */
.btn-outline {
    background-color: transparent;
    border-color: var(--line-strong);
    color: var(--ink);
}

.btn-outline:hover {
    background-color: var(--tint);
    border-color: var(--line-strong);
    color: var(--ink);
}

/* White-outlined button for the dark bands. */
.btn-secondary {
    background-color: transparent;
    color: #fff;
    border-color: rgba(255, 255, 255, 0.55);
}

.btn-secondary:hover {
    background-color: rgba(255, 255, 255, 0.1);
    border-color: #fff;
    color: #fff;
}

/* Arrow link. The lighter of the two link weights on the site: used for "go and
   look at more of this" where a full .btn would compete with the actual
   conversion CTA. A page should have few enough buttons that the filled one is
   obviously the point; everything navigational lands here instead. */
.case-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 20px;
    font-weight: 500;
    color: var(--primary-color);
    text-decoration: none;
    transition: gap 0.2s ease, color 0.2s ease;
}

.case-link:hover {
    color: var(--dark-color);
    gap: 12px;
}

/* Standing on its own under a section rather than inside a card: the card
   spacing is already provided by .stack-buttons, and the padding keeps the tap
   target at 24px (WCAG 2.5.8) now that there is no button box around it. */
.stack-buttons .case-link {
    margin-top: 0;
    padding: 6px 4px;
}

.stack-buttons {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: center;
    margin-top: 28px;
}

/* Kept for the markup that still carries it; buttons are left-aligned anyway. */
.stack-buttons-start {
    margin-bottom: 30px;
}

/* ==========================================================================
   Header
   ========================================================================== */

/* Fixed rather than sticky: the overflow-x hack on body makes sticky
   unreliable. Pages clear it with their own top padding (.hero, .case-hero). */
body > header {
    background-color: rgba(246, 245, 240, 0.92);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line);
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1000;
}

nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: var(--header-h);
}

/* Fluid so that between the hamburger breakpoint and ~1500px the wordmark,
   seven links and two actions all fit the 1160px container. */
.logo {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: clamp(1.35rem, 1.2vw + 8px, 1.7rem);
    letter-spacing: -0.01em;
    color: var(--ink);
    text-decoration: none;
    flex-shrink: 0;
    white-space: nowrap;
}

/* The highlighted R in the wordmark. */
.logo span {
    color: var(--primary-color);
}

.nav-links {
    display: flex;
    list-style: none;
    gap: clamp(12px, 3.5vw - 28px, 28px);
}

.nav-links a {
    color: var(--ink);
    text-decoration: none;
    font-weight: 500;
    font-size: clamp(0.875rem, 0.5vw + 8px, 0.95rem);
    white-space: nowrap;
    transition: color 0.2s ease;
    position: relative;
    padding: 4px 0;
}

.nav-links a:hover,
.nav-links a:focus-visible {
    color: var(--primary-color);
}

.nav-links a.active {
    color: var(--primary-color);
}

/* Current-page underline, so the state does not rest on colour alone. */
.nav-links a.active::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: var(--primary-color);
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-left: 15px;
    /* Never the part that gives when the bar runs short. */
    flex-shrink: 0;
}

.lang-switch {
    font-family: var(--font-mono);
    color: var(--muted);
    text-decoration: none;
    font-weight: 500;
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    padding: 6px 4px;
    transition: color 0.2s ease;
    white-space: nowrap;
}

.lang-switch:hover {
    color: var(--ink);
}

.hamburger {
    display: none;
    cursor: pointer;
    background: none;
    border: none;
    padding: 10px;
    margin-right: -10px;
    outline: none;
    z-index: 1100;
}

.hamburger span {
    display: block;
    width: 26px;
    height: 2px;
    background-color: var(--ink);
    margin: 6px 0;
    transition: all 0.3s ease;
    border-radius: 2px;
}

/* ==========================================================================
   Hero
   --------------------------------------------------------------------------
   .hero alone is the dark compact band the service pages open with. The home
   page adds .hero-home: paper ground, two columns, a real project image.
   ========================================================================== */

.hero {
    background-color: var(--dark-color);
    color: #fff;
    /* Clear the fixed header. */
    padding-top: calc(var(--header-h) + 88px);
    padding-bottom: 88px;
}

.hero-content {
    max-width: 780px;
}

.hero h1 {
    font-size: clamp(2.3rem, 1.4rem + 3.4vw, 4rem);
    color: #fff;
    margin-bottom: 24px;
    max-width: 18ch;
}

.hero p {
    font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.25rem);
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.8);
    margin-bottom: 32px;
    max-width: 36em;
}

/* Small label above the headline. Mono, uppercase, light accent on dark. */
.hero-tagline {
    display: block;
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--nav-accent);
    margin-bottom: 22px;
}

.hero-buttons {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-bottom: 40px;
}

/* On the dark band the filled button is white so it reads as the primary
   action; brand green on deep green is barely visible. */
.hero .btn-primary {
    background-color: #fff;
    color: var(--dark-color);
}

.hero .btn-primary:hover {
    background-color: var(--nav-accent);
    color: var(--dark-color);
}

/* Compact variant used on /automatisierung/, /r-entwicklung/, /hosting/ and /hub/. */
.hero-compact {
    padding-top: calc(var(--header-h) + 72px);
    padding-bottom: 72px;
}

/* ---- Hero proof strip ----
   Names the clients directly under the hero CTAs. */

.hero-proof {
    margin-top: 8px;
    padding-top: 26px;
    border-top: 1px solid rgba(255, 255, 255, 0.15);
}

.hero-proof-label {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: rgba(255, 255, 255, 0.62);
    margin-bottom: 12px;
}

.hero-proof-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 10px 30px;
}

.hero-proof-list li {
    font-size: 1rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.92);
}

/* Separator dots between the names, but not before the first one. */
.hero-proof-list li + li {
    position: relative;
}

.hero-proof-list li + li::before {
    content: '';
    position: absolute;
    left: -17px;
    top: 50%;
    width: 4px;
    height: 4px;
    margin-top: -2px;
    border-radius: 50%;
    background-color: var(--nav-accent);
}

/* ---- Home hero: paper, two columns ---- */

.hero-home {
    background-color: var(--paper);
    color: var(--ink);
    padding-top: calc(var(--header-h) + 96px);
    padding-bottom: 96px;
}

.hero-grid {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 56px;
    align-items: center;
}

/* Replaced content (the screenshot, the video) must not set the track's
   minimum, or the grid outgrows a phone viewport. */
.hero-grid > *,
.video-split > * {
    min-width: 0;
}

.hero-home .hero-tagline {
    color: var(--primary-color);
}

.hero-home h1 {
    color: var(--ink);
    max-width: 13ch;
}

.hero-home p {
    color: var(--muted);
}

.hero-home .btn-primary {
    background-color: var(--primary-color);
    color: #fff;
}

/* Both hover rules share specificity with .hero .btn-primary:hover above, so
   the colour has to be restated here or the dark-band text colour leaks in. */
.hero-home .btn-primary:hover {
    background-color: var(--dark-color);
    color: #fff;
}

.hero-home .hero-buttons {
    margin-bottom: 36px;
    gap: 24px;
}

.hero-home .hero-buttons .case-link {
    margin-top: 0;
}

.hero-home .hero-proof {
    border-top-color: var(--line-strong);
}

.hero-home .hero-proof-label {
    color: var(--muted);
}

.hero-home .hero-proof-list li {
    color: var(--dark-color);
}

/* Framed screenshot with a deep-green plate behind it. */
.hero-media {
    position: relative;
    margin: 0;
    padding: 32px 0 0 32px;
}

.hero-media::before {
    content: '';
    position: absolute;
    top: 0;
    right: 32px;
    bottom: 32px;
    left: 0;
    background-color: var(--dark-color);
    border-radius: 14px;
}

.hero-media-frame {
    position: relative;
    background-color: var(--surface);
    border: 1px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 28px 64px rgba(24, 40, 38, 0.2);
}

.hero-media-frame img {
    display: block;
    width: 100%;
}

.hero-media figcaption {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
    font-size: 0.82rem;
    color: var(--muted);
}

.hero-media figcaption .mono {
    color: var(--primary-color);
    font-size: 0.68rem;
    white-space: nowrap;
}

/* ==========================================================================
   Section furniture
   ========================================================================== */

/* Sections sit on the paper ground by default. .section-light is the white
   band; the two alternate down every page (check-sections.mjs enforces it).
   Cards flip their surface so they stay visible on either. */
.section-light {
    background-color: var(--surface);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    --card-bg: var(--paper);
}

.section-light + .section-light {
    border-top: 0;
}

/* Deep-green band (the practice video). Counts as "dark" for the checker. */
.section-dark {
    background-color: var(--dark-color);
    color: #fff;
    --card-bg: rgba(255, 255, 255, 0.06);
}

.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4 {
    color: #fff;
}

.section-dark p {
    color: rgba(255, 255, 255, 0.8);
}

.section-dark .eyebrow {
    color: var(--nav-accent);
}

/* Small label above a heading. Mono, uppercase, brand green. */
.eyebrow,
.mono {
    display: block;
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--primary-color);
    margin-bottom: 16px;
}

.mono {
    display: inline-block;
    margin-bottom: 0;
}

.section-intro {
    max-width: 640px;
    margin: 0 0 44px;
    font-size: 1.125rem;
    color: var(--muted);
}

/* Gap between an eyebrow+heading+intro group and the block it introduces. */
.section-head {
    margin-bottom: 48px;
}

.section-head .section-intro {
    margin-bottom: 0;
}

.section-head h2 {
    margin-bottom: 16px;
}

/* Gap above a closing paragraph or button row that follows a card grid. */
.block-after-grid {
    margin-top: 45px;
}

/* ---- One alignment rule for the whole site ----
   Everything starts at the container's left edge: headings, intros, prose
   columns, button rows, figure captions. Narrow reading columns keep their
   max-width but are never centred, so a heading above a column and the
   column itself always share one left edge. There is deliberately no
   .text-center helper. */

.measure {
    max-width: 800px;
}

.measure-narrow {
    max-width: 700px;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   Cards
   ========================================================================== */

.services-container {
    display: grid;
    grid-template-columns: 1fr;
    gap: 28px;
}

@media (min-width: 768px) {
    .services-container {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.service-card {
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    padding: 40px;
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: border-color 0.2s ease;
}

.service-card:hover {
    border-color: var(--line-strong);
}

.service-icon {
    width: 48px;
    height: 48px;
    font-size: 1.25rem;
    color: #fff;
    background-color: var(--primary-color);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 18px;
}

.service-card h3 {
    margin-bottom: 12px;
}

/* Make content fill the available space so card CTAs line up. */
.service-card p {
    flex-grow: 1;
    margin-bottom: 16px;
}

.service-card .badge-row,
.service-card .stack-buttons {
    justify-content: flex-start;
}

.service-card .stack-buttons {
    margin-top: auto;
    padding-top: 18px;
}

.badge-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 4px;
    margin-bottom: 8px;
}

/* Small pill for technologies and topics. */
.tech-badge,
.tech-tag {
    display: inline-block;
    background-color: var(--tint);
    color: var(--dark-color);
    padding: 5px 11px;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 500;
    line-height: 1.3;
}

.tech-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 10px 0;
}

/* ---- Tech stack (R-Entwicklung) ---- */

.tech-expertise {
    /* No background here on purpose: section tone is always declared in the
       markup via .section-light. */
    padding: 96px 0;
}

.tech-stack-container {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    margin-top: 40px;
}

.tech-category {
    flex: 1 1 300px;
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    padding: 32px;
    border-radius: var(--radius);
}

.tech-category h3 {
    margin-bottom: 8px;
}

/* Context sentence under a tech category heading. */
.tech-category > p {
    font-size: 0.95rem;
    color: var(--muted);
    margin-bottom: 18px;
}

.tech-items {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* ---- Testimonials ---- */

.testimonial-quote {
    font-family: var(--font-serif);
    font-style: italic;
    font-weight: 400;
    margin-bottom: 20px;
    color: var(--ink);
    line-height: 1.55;
    font-size: 1.2rem;
}

.testimonial-quote a {
    color: var(--ink);
    text-decoration: underline;
}

.testimonial-author {
    display: flex;
    align-items: center;
}

.author-img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background-color: var(--tint);
    margin-right: 14px;
    overflow: hidden;
    flex-shrink: 0;
}

.author-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Fallback avatar for testimonials where no photo is available */
.author-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--primary-color);
    color: #fff;
    font-weight: 600;
    font-size: 0.95rem;
    letter-spacing: 0.5px;
    flex-shrink: 0;
}

.author-info .author-name {
    margin: 0;
    color: var(--ink);
    font-weight: 600;
    font-family: var(--font-sans);
    font-size: 0.95rem;
}

.author-info p {
    margin: 0;
    font-size: 0.875rem;
    color: var(--muted);
}

/* Marks a quote as translated from the original German. */
.quote-note {
    font-style: italic;
    opacity: 0.8;
}

/* ==========================================================================
   Video showcase
   ========================================================================== */

.video-section {
    padding: 96px 0;
}

.video-split {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 56px;
    align-items: center;
}

.video-copy h2 {
    margin-bottom: 18px;
}

.video-copy p {
    margin-bottom: 0;
    max-width: 26em;
}

.video-frame {
    position: relative;
    width: 100%;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 30px 70px rgba(0, 0, 0, 0.35);
    background: #000;
}

.video-frame video {
    width: 100%;
    height: auto;
    display: block;
    max-height: 600px;
}

/* ==========================================================================
   Reference grid and cards
   ========================================================================== */

/* Tabs rather than pills: one line, the active one underlined in green. */
.filter-chips {
    display: flex;
    gap: 32px;
    flex-wrap: wrap;
    justify-content: flex-start;
    border-bottom: 1px solid var(--line-strong);
    margin-bottom: 44px;
}

.filter-chip {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    margin-bottom: -1px;
    padding: 0 2px 14px;
    font-family: inherit;
    font-weight: 500;
    font-size: 0.95rem;
    color: var(--muted);
    cursor: pointer;
    transition: color 0.2s ease, border-color 0.2s ease;
}

.filter-chip:hover {
    color: var(--ink);
}

.filter-chip.active {
    color: var(--ink);
    border-bottom-color: var(--primary-color);
}

.ref-grid {
    display: grid;
    /* min() keeps the track from outgrowing the viewport on narrow phones. */
    grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr));
    gap: 28px;
}

/* Short prose after a card grid, for engagements that are real references but
   too small for a case study of their own. */
.ref-note {
    max-width: 800px;
    margin-top: 32px;
}

/* Two-up variant used on the audience pages and the home page. */
.ref-grid-2 {
    grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
}

.ref-card {
    position: relative;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    transition: border-color 0.2s ease;
}

.ref-card:hover {
    border-color: var(--line-strong);
}

/* Fixed aspect box so the grid stays tidy despite very different screenshot
   ratios (1.29:1 to 1.92:1). */
.ref-card-media {
    display: block;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background-color: var(--tint);
    border-bottom: 1px solid var(--line);
}

.ref-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
    transition: transform 0.4s ease;
}

.ref-card:hover .ref-card-media img {
    transform: scale(1.03);
}

.ref-card-body {
    padding: 26px 28px 28px;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.ref-card-tag {
    display: inline-block;
    align-self: flex-start;
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.72rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 12px;
}

.ref-card h3 {
    font-size: 1.5rem;
    margin-bottom: 10px;
}

.ref-card h3 a {
    color: var(--ink);
    text-decoration: none;
}

.ref-card h3 a:hover {
    color: var(--primary-color);
}

.ref-card p {
    font-size: 0.95rem;
    color: var(--muted);
    margin-bottom: 14px;
}

/* Client name and the arrow on one line, under a rule, pinned to the bottom. */
.ref-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.ref-card-client {
    margin: 0;
    min-width: 0;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--dark-color);
}

/* Visible affordance. Not a link itself - the stretched title link handles the
   click, so screen readers do not announce a second identical destination. */
.ref-card-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    white-space: nowrap;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--primary-color);
    transition: gap 0.2s ease, color 0.2s ease;
}

.ref-card:hover .ref-card-cta,
.ref-card:focus-within .ref-card-cta {
    color: var(--dark-color);
    gap: 12px;
}

/* On the audience pages the card keeps the client quote: this is the one place
   where a visitor needs the proof in context. */
.ref-card-quote {
    margin: 4px 0 18px;
    font-family: var(--font-serif);
    font-style: italic;
    color: var(--ink);
    font-size: 1.1rem;
    line-height: 1.5;
}

.ref-card-author {
    display: flex;
    align-items: center;
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.ref-card-author .author-img {
    width: 40px;
    height: 40px;
    margin-right: 12px;
}

.ref-card-author .author-name {
    margin: 0;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--ink);
}

.ref-card-author p:not(.author-name) {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted);
}

/* Where the card carries a client quote the CTA follows the author block. */
.ref-card-author + .ref-card-cta {
    margin-top: 16px;
}

/* ---- Whole reference card is one link target ----
   The title link is the real, keyboard-reachable link; its ::after stretches
   over the card so a tap anywhere works. */
.ref-card-link::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
}

/* Keyboard focus has to be visible on the card, not just on the title text. */
.ref-card:focus-within {
    outline: 3px solid #ffd24a;
    outline-offset: 2px;
}

.ref-card-link:focus-visible {
    outline: none;
}

@media (max-width: 520px) {
    .ref-grid-2 {
        grid-template-columns: 1fr;
    }
}

/* ==========================================================================
   Case study layout (also the intro band of About, Contact, FAQ, legal)
   ========================================================================== */

.case-hero {
    background-color: var(--surface);
    border-bottom: 1px solid var(--line);
    /* Clear the fixed header. */
    padding: calc(var(--header-h) + 80px) 0 56px;
}

.case-hero h1 {
    margin-bottom: 18px;
}

.case-hero p {
    font-size: 1.125rem;
    color: var(--muted);
}

.case-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 30px;
    margin-top: 30px;
    padding-top: 25px;
    border-top: 1px solid var(--line);
}

.case-meta div {
    flex: 1 1 180px;
}

.case-meta dt {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
    margin-bottom: 6px;
}

.case-meta dd {
    margin: 0;
    font-weight: 500;
    color: var(--ink);
}

.case-body {
    max-width: 780px;
}

.case-body h2 {
    font-size: clamp(1.6rem, 1.3rem + 1vw, 2.1rem);
    margin-top: 45px;
}

/* Sub-headings inside a case study, used for the individual "hard parts". Sized
   clearly below .case-body h2 so the section still reads as one block. */
.case-body h3 {
    font-size: 1.35rem;
    margin-top: 34px;
    margin-bottom: 12px;
}

/* The first sub-heading follows the section's own intro line, so it does not
   need the full gap. */
.case-body h2 + p + h3 {
    margin-top: 24px;
}

.case-figure {
    margin: 35px 0;
}

.case-figure img {
    width: 100%;
    border-radius: 8px;
    border: 1px solid var(--line);
}

.case-figure figcaption {
    font-size: 0.875rem;
    color: var(--muted);
    margin-top: 10px;
}

/* An embedded API widget. The height attribute is the desktop fallback;
   site.js replaces it with the height the widget reports for its width. */
.live-widget-frame {
    display: block;
    width: 100%;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: #fff;
}

.result-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 20px;
    margin: 30px 0;
}

.result-tile {
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 22px 24px;
}

.result-tile strong {
    display: block;
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 2rem;
    color: var(--ink);
    line-height: 1.1;
    margin-bottom: 8px;
}

.result-tile span {
    font-size: 0.9rem;
    color: var(--muted);
}

/* ==========================================================================
   Process steps, pain points, packages, highlight card
   ========================================================================== */

.process-steps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 24px;
    margin-top: 40px;
    counter-reset: step;
}

.process-step {
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 30px 26px;
    position: relative;
}

.process-step::before {
    counter-increment: step;
    content: counter(step, decimal-leading-zero);
    display: block;
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    color: var(--primary-color);
    margin-bottom: 18px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--line);
}

.process-step h3 {
    font-size: 1.3rem;
    margin-bottom: 10px;
}

.process-step p {
    font-size: 0.95rem;
    color: var(--muted);
    margin-bottom: 8px;
}

.process-step .step-duration {
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--primary-color);
}

/* ---- Pain-point list ("Kennst du das?") ---- */

.pain-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 20px;
    margin-top: 35px;
}

.pain-item {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 24px;
}

.pain-item .icon {
    color: var(--primary-color);
    font-size: 1.2rem;
    margin-top: 4px;
}

.pain-item p {
    margin-bottom: 0;
    font-size: 0.98rem;
}

/* ---- Automation+ package grid ---- */

.package-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 24px;
    margin-top: 40px;
}

.package-card {
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 30px 26px;
}

.package-card h3 {
    font-size: 1.3rem;
    margin-bottom: 16px;
    display: flex;
    align-items: center;
    gap: 10px;
}

.package-card h3 .icon {
    color: var(--primary-color);
    font-size: 0.95rem;
}

.package-card ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.package-card li {
    position: relative;
    padding-left: 20px;
    margin-bottom: 10px;
    font-size: 0.95rem;
    color: var(--muted);
    line-height: 1.5;
}

.package-card li::before {
    content: '✓';
    position: absolute;
    left: 0;
    color: var(--primary-color);
    font-weight: 700;
}

.package-card li:last-child {
    margin-bottom: 0;
}

/* ---- Check list ---- */

.check-list {
    list-style: none;
    padding-left: 0;
    margin-bottom: 25px;
}

/* Hanging indent via absolute positioning, NOT flex. A flex <li> turns every
   inline child (<strong>, <code>, each text run) into a separate flex item,
   which shreds the line into columns. */
.check-list li {
    position: relative;
    padding-left: 26px;
    margin-bottom: 16px;
    line-height: 1.7;
}

.check-list li::before {
    content: '✓';
    position: absolute;
    left: 0;
    top: 0;
    color: var(--primary-color);
    font-weight: 700;
}

/* On the dark highlight card the green tick would vanish. */
.highlight-card .check-list li::before {
    color: var(--nav-accent);
}

/* ---- Highlight card on the deep green ---- */

.highlight-card {
    background-color: var(--dark-color);
    border-radius: var(--radius);
    padding: 28px;
    position: relative;
}

.highlight-card h3,
.highlight-card h4,
.highlight-card h5 {
    color: #fff;
}

.highlight-card h3 {
    margin-bottom: 15px;
    font-size: 1.4rem;
    display: flex;
    align-items: center;
}

.highlight-card p {
    color: rgba(255, 255, 255, 0.85);
}

.highlight-card-check {
    background-color: var(--nav-accent);
    color: var(--dark-color);
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    margin-right: 10px;
    font-size: 0.9rem;
    flex-shrink: 0;
}

.highlight-card-inset {
    background-color: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 14px;
}

.highlight-card-inset h4 {
    margin-bottom: 5px;
}

.highlight-card-inset p {
    font-size: 0.9rem;
    margin-bottom: 0;
}

.highlight-card-inset:last-child {
    margin-bottom: 0;
}

/* ---- Terminal transcript (/hub/) ----
   Same deep green as the highlight card, so white text, never --primary-color.
   The <pre> scrolls on its own: long log lines must not widen the page. */

.terminal {
    margin: 40px 0 0;
    min-width: 0;
}

.terminal pre {
    background-color: var(--dark-color);
    color: #fff;
    border-radius: var(--radius);
    padding: 22px 24px;
    overflow-x: auto;
    font-size: 0.85rem;
    line-height: 1.7;
}

.terminal pre code {
    background: none;
    padding: 0;
    border-radius: 0;
    color: inherit;
    font-size: inherit;
}

.terminal figcaption {
    margin-top: 10px;
    font-size: 0.9rem;
    color: var(--muted);
}

/* Soft plate behind the highlight card. */
.decorated {
    position: relative;
}

.decorated::before {
    content: '';
    position: absolute;
    inset: 18px -18px -18px 18px;
    background-color: var(--tint);
    border-radius: var(--radius);
    z-index: -1;
}

/* Pull quote used for the closing statement on the About page. */
.pull-quote {
    margin-top: 25px;
    padding: 20px 24px;
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.pull-quote p {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1.2rem;
    color: var(--ink);
    margin-bottom: 0;
}

/* Opening paragraph on the About page: slightly larger, sets the tone. */
.lead {
    font-size: 1.2rem;
    line-height: 1.6;
    color: var(--ink);
}

/* ---- Two-column split with copy on one side ---- */

.split {
    display: flex;
    flex-wrap: wrap;
    gap: 40px;
    align-items: center;
    margin: 60px 0;
}

.split > * {
    flex: 1 1 400px;
    min-width: 0;
}

/* ==========================================================================
   FAQ
   ========================================================================== */

.faq-list {
    max-width: 800px;
}

.faq-item {
    border-bottom: 1px solid var(--line-strong);
}

.faq-question {
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 22px 44px 22px 0;
    font-size: 1.1rem;
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
    position: relative;
    font-family: inherit;
    line-height: 1.4;
}

.faq-question::after {
    content: '+';
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.5rem;
    font-weight: 400;
    color: var(--primary-color);
}

.faq-question[aria-expanded="true"]::after {
    content: '−';
}

.faq-question:hover {
    color: var(--primary-color);
}

.faq-answer {
    padding: 0 44px 24px 0;
    color: var(--muted);
}

.faq-answer p:last-child {
    margin-bottom: 0;
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 32px;
}

.contact-info,
.contact-form {
    background-color: var(--card-bg);
    border: 1px solid var(--line);
    padding: 36px;
    border-radius: var(--radius);
}

/* Both cards carry their own h2, sized down inside the card. */
.contact-info h2,
.contact-form h2 {
    font-size: 1.7rem;
    margin-bottom: 14px;
}

.contact-sub {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
    margin-bottom: 18px;
    padding-top: 22px;
    border-top: 1px solid var(--line);
}

.contact-info-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 20px;
}

.contact-info-icon {
    font-size: 1.2rem;
    color: var(--primary-color);
    margin-right: 15px;
    min-width: 30px;
    margin-top: 3px;
}

.contact-info-content h4 {
    font-family: var(--font-sans);
    font-weight: 600;
    font-size: 0.95rem;
    letter-spacing: 0;
    margin-bottom: 2px;
}

.contact-info-content p {
    margin-bottom: 0;
}

.form-lead {
    color: var(--muted);
    margin-bottom: 22px;
}

.form-note {
    font-size: 0.85rem;
    color: var(--muted);
    margin-bottom: 15px;
}

.form-group {
    margin-bottom: 20px;
}

.form-label {
    display: block;
    margin-bottom: 6px;
    font-weight: 500;
    font-size: 0.92rem;
    color: var(--ink);
}

/* Marks required fields. The asterisk is decorative - the <input required>
   attribute is what screen readers actually announce. */
.form-label .required-mark {
    color: var(--accent-color);
    margin-left: 2px;
}

.form-label .optional-mark {
    font-weight: 400;
    color: var(--muted);
    font-size: 0.85rem;
}

.form-control {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    font-size: 1rem;
    font-family: inherit;
    color: var(--ink);
    background-color: var(--surface);
    transition: border-color 0.2s ease;
}

.form-control:focus {
    border-color: var(--primary-color);
}

textarea.form-control {
    min-height: 150px;
    resize: vertical;
}

/* Consent checkbox. The transfer to FormSubmit (USA) rests on explicit
   consent under Art. 49(1)(a) GDPR, so it has to be an actual opt-in the
   visitor performs, not a sentence under the submit button. */
.form-consent {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 20px;
}

.form-consent input[type="checkbox"] {
    flex: 0 0 auto;
    /* 24px minimum target size (WCAG 2.5.8). */
    width: 24px;
    height: 24px;
    margin-top: 1px;
    accent-color: var(--primary-color);
}

.form-consent label {
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--muted);
}

.form-consent .required-mark {
    color: var(--accent-color);
    margin-left: 2px;
}

/* ==========================================================================
   About page
   ========================================================================== */

/* Portrait beside the text, on the white intro band. */
.about-intro {
    display: flex;
    gap: 48px;
    align-items: flex-start;
    max-width: 950px;
}

.about-img {
    flex: 0 0 280px;
    max-width: 280px;
}

.about-img img {
    border-radius: 10px;
    border: 1px solid var(--line);
}

.about-intro-text {
    flex: 1;
    min-width: 0;
}

.about-intro-text h1 {
    margin-bottom: 18px;
}

.about-intro-text .case-meta {
    margin-top: 28px;
}

/* ==========================================================================
   Legal pages (Impressum, Datenschutz, AGB)
   --------------------------------------------------------------------------
   Scoped under .legal so the box styles cannot collide with the marketing
   components above. Legal text is read in long left-aligned runs rather
   than scanned, so the typographic details differ.
   ========================================================================== */

.legal {
    max-width: 800px;
}

.legal h2 {
    font-size: clamp(1.5rem, 1.25rem + 0.9vw, 1.9rem);
    margin-top: 50px;
    margin-bottom: 18px;
}

.legal h3 {
    font-size: 1.25rem;
    margin-top: 28px;
    margin-bottom: 10px;
}

.legal p {
    margin-bottom: 14px;
}

.legal ul {
    margin: 0 0 18px 22px;
}

.legal li {
    margin-bottom: 8px;
}

/* Buttons excluded: this rule outranks .btn and would turn the filled
   "Zur Website" button green on green. */
.legal a:not(.btn) {
    color: var(--primary-color);
}

.legal .section-number {
    color: var(--primary-color);
    font-weight: 600;
}

/* Two box styles. Neutral: an aside that supports the surrounding text.
   Emphasis: something the reader must not skim past. */
.legal .highlight-box,
.legal .contact-info,
.legal .contact-box {
    background-color: var(--tint);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 22px 24px;
    margin: 24px 0;
}

.legal .warning-box,
.legal .important-note,
.legal .legal-note {
    background-color: var(--card-bg);
    border: 1px solid var(--primary-color);
    border-radius: var(--radius);
    padding: 22px 24px;
    margin: 24px 0;
}

.legal .highlight-box > :last-child,
.legal .contact-info > :last-child,
.legal .contact-box > :last-child,
.legal .warning-box > :last-child,
.legal .important-note > :last-child,
.legal .legal-note > :last-child {
    margin-bottom: 0;
}

.legal .contact-info h2 {
    margin-top: 0;
}

.legal .address-block {
    margin-bottom: 14px;
}

.legal .address-lines {
    display: block;
    margin-top: 4px;
}

.legal .table-responsive {
    overflow-x: auto;
    margin: 24px 0;
}

.legal table {
    width: 100%;
    border-collapse: collapse;
    min-width: 480px;
}

.legal th,
.legal td {
    border: 1px solid var(--line);
    padding: 12px;
    text-align: left;
}

.legal th {
    background-color: var(--tint);
    color: var(--ink);
    font-weight: 600;
}

/* Cross-links between the three legal documents. */
.legal-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 25px;
}

/* ==========================================================================
   Carousel (platform page)
   ========================================================================== */

.carousel {
    margin-top: 60px;
    position: relative;
    overflow: hidden;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background-color: var(--card-bg);
}

#carousel-container {
    white-space: nowrap;
    overflow-x: hidden;
    padding: 20px 0;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    text-align: center;
    position: relative;
    /* browser chrome (~41px) + image box (420px) + padding (40px) */
    min-height: 500px;
}

/* Slides are absolutely positioned so they do NOT contribute to the
   container's height. Combined with the fixed .image-container box below,
   the carousel keeps exactly one height no matter which slide is showing. */
.carousel-slide {
    position: absolute;
    left: 0;
    right: 0;
    margin: 0 auto;
    width: 80%;
    max-width: 800px;
    background-color: var(--surface);
    border-radius: 8px;
    border: 1px solid var(--line);
    overflow: hidden;
    transition: opacity 0.5s ease;
}

/* Initial state: only the first slide shows. site.js sets `display` inline on
   every slide from its first transition onwards, so it takes over from here. */
.carousel-slide + .carousel-slide {
    display: none;
}

.image-container {
    width: 100%;
    height: 420px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Scale to fit the fixed box without cropping or distorting. */
.image-container img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    margin: 0 auto;
    display: block;
}

.browser-chrome {
    background-color: var(--paper);
    padding: 10px;
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--line);
}

.browser-dots {
    display: flex;
}

.browser-dots span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 7px;
    background-color: var(--line-strong);
}

.browser-dots span:nth-child(3) {
    margin-right: 0;
}

.browser-title {
    margin: 0 auto;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--muted);
}

.carousel-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background-color: var(--dark-color);
    color: white;
    border: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    cursor: pointer;
    z-index: 10;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: background-color 0.2s ease;
}

.carousel-nav:hover {
    background-color: var(--primary-color);
}

#prev-btn { left: 10px; }
#next-btn { right: 10px; }

#carousel-toggle {
    position: absolute;
    top: 10px;
    right: 10px;
    background-color: var(--dark-color);
    color: white;
    border: none;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    cursor: pointer;
    z-index: 10;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: background-color 0.2s ease;
}

#carousel-toggle:hover {
    background-color: var(--primary-color);
}

#carousel-dots {
    position: absolute;
    bottom: 20px;
    left: 0;
    right: 0;
    text-align: center;
}

.carousel-dot {
    display: inline-block;
    /* 24px hit area (WCAG 2.5.8) with a 14px dot painted inside it. */
    width: 24px;
    height: 24px;
    padding: 0;
    border: 5px solid transparent;
    background-color: rgba(54, 91, 86, 0.3);
    background-clip: content-box;
    border-radius: 50%;
    margin: 0;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.carousel-dot.active {
    background-color: var(--primary-color);
}

/* ==========================================================================
   Footer
   ========================================================================== */

footer {
    background-color: var(--ink);
    color: #fff;
    padding: 72px 0 40px;
}

.footer-grid {
    display: grid;
    grid-template-columns: 5fr 2fr 2fr 3fr;
    gap: 40px;
    margin-bottom: 56px;
}

.footer-brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
}

footer .logo {
    color: #fff;
    font-size: 1.6rem;
}

footer .logo span {
    color: var(--nav-accent);
}

/* Privacy-first line, with the lock icon. */
.privacy-footer {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 0.875rem;
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.62);
    max-width: 30em;
    margin: 0;
}

.privacy-footer .icon {
    flex-shrink: 0;
    margin-top: 4px;
    color: var(--nav-accent);
}

.privacy-footer a {
    color: var(--nav-accent);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.privacy-footer a:hover {
    color: #fff;
}

.footer-nav-col {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
}

.footer-nav-col h3 {
    font-family: var(--font-mono);
    font-weight: 500;
    color: var(--nav-accent);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    margin-bottom: 4px;
}

.footer-nav-col a {
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
    font-size: 0.95rem;
    transition: color 0.2s ease;
}

.footer-nav-col a:hover {
    color: #fff;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 32px;
    padding-top: 28px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    font-size: 0.875rem;
    color: rgba(255, 255, 255, 0.55);
}

.social-links,
.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
}

/* Padded to clear the 24px minimum target size (WCAG 2.5.8). */
.social-links a,
.footer-links a {
    padding: 3px 0;
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
    font-size: 0.875rem;
    transition: color 0.2s ease;
}

.social-links a:hover,
.footer-links a:hover {
    color: #fff;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.footer-copy {
    margin: 0;
}

.footer-legal-note {
    font-size: 0.82rem;
    color: rgba(255, 255, 255, 0.55);
    max-width: 480px;
    margin: -24px 0 40px;
}

/* ==========================================================================
   Icons, accessibility, motion
   ========================================================================== */

/* build.mjs replaces every `<i class="fa-… fa-…">` in the source with an inline
   <svg class="icon"> carrying that glyph's path data, so there is no icon
   webfont. Size comes from the width/height attributes the build writes (1em
   tall); colour and baseline alignment come from here. */
.icon {
    fill: currentColor;
    /* Matches the optical baseline Font Awesome's own inline SVGs use. */
    vertical-align: -0.125em;
    flex-shrink: 0;
}

code {
    font-size: 0.9em;
    background-color: var(--tint);
    padding: 2px 6px;
    border-radius: 4px;
    color: var(--dark-color);
}

/* Every interactive element needs a visible keyboard focus ring.
   :focus-visible keeps it off for mouse users. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid #ffd24a;
    outline-offset: 2px;
    border-radius: 3px;
}

/* Skip link so keyboard users can jump past the nav */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 1200;
    background: #fff;
    color: var(--primary-color);
    padding: 12px 20px;
    font-weight: 600;
    text-decoration: none;
}

.skip-link:focus {
    left: 10px;
    top: 10px;
}

/* Respect users who have asked their OS to reduce motion. */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* Two-column layouts collapse before the hamburger breakpoint. */
@media (max-width: 960px) {
    .hero-grid,
    .video-split,
    .footer-grid {
        grid-template-columns: 1fr;
    }

    .hero-grid {
        gap: 48px;
    }

    .hero-media {
        max-width: 640px;
    }

    .footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 36px 28px;
    }

    .footer-brand {
        grid-column: 1 / -1;
    }
}

/* Hamburger menu. This breakpoint is the single definition of the mobile nav. */
@media (max-width: 1150px) {

    .nav-links {
        position: fixed;
        top: var(--header-h);
        left: 0;
        width: 100%;
        /* dvh so the last entry does not sit under mobile Safari's chrome.
           vh first as the fallback for browsers without dvh. */
        height: calc(100vh - var(--header-h));
        height: calc(100dvh - var(--header-h));
        background-color: var(--paper);
        border-top: 1px solid var(--line);
        flex-direction: column;
        align-items: center;
        justify-content: flex-start;
        padding-top: 24px;
        /* transform rather than `left`: animating a layout property janks on
           exactly the devices this breakpoint targets. The reduced-motion block
           above collapses the duration for users who ask for that. */
        transform: translateX(-100%);
        /* Closed menu is off-canvas, so it must also be out of the tab order;
           visibility flips instantly on open and after the slide on close. */
        visibility: hidden;
        transition: transform 0.35s ease, visibility 0s linear 0.35s;
        z-index: 1000;
        overflow-y: auto;
        /* Off the desktop row, so the fluid inter-link gap no longer applies -
           the column spaces itself with the li margins below. */
        gap: 0;
    }

    .nav-links.active {
        transform: translateX(0);
        visibility: visible;
        transition: transform 0.35s ease, visibility 0s;
    }

    .nav-links li {
        margin: 6px 0;
    }

    .nav-links a {
        font-family: var(--font-serif);
        font-size: 1.6rem;
        font-weight: 500;
        display: block;
        padding: 10px 20px;
        width: 100%;
        text-align: center;
    }

    .nav-links a.active::after {
        display: none;
    }

    .hamburger {
        display: block;
        position: relative;
    }

    .hamburger.active span:nth-child(1) {
        transform: rotate(45deg) translate(5px, 6px);
    }

    .hamburger.active span:nth-child(2) {
        opacity: 0;
        transform: translateX(20px);
    }

    .hamburger.active span:nth-child(3) {
        transform: rotate(-45deg) translate(5px, -6px);
    }

    body > header .container {
        padding: 0 15px;
    }

    /* Once .nav-links is off-canvas, the nav has three visible children and
       space-between would strand the language switch in the middle of the bar.
       Push it over so it sits next to the hamburger it belongs beside. */
    .nav-actions {
        margin-left: auto;
        margin-right: 18px;
    }

}

@media (max-width: 768px) {

    /* Nav, hamburger and header padding are defined once, in the 1150px block
       above. Heading and body sizes are fluid via clamp(), so they need no
       override here either. */
    section {
        padding: 64px 0;
    }

    .hero {
        padding-top: calc(var(--header-h) + 56px);
        padding-bottom: 56px;
    }

    .hero-home {
        padding-top: calc(var(--header-h) + 48px);
        padding-bottom: 56px;
    }

    .hero-compact {
        padding-top: calc(var(--header-h) + 48px);
        padding-bottom: 48px;
    }

    .hero-buttons {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    .hero-home .hero-buttons {
        gap: 12px;
    }

    .hero-home .hero-buttons .case-link {
        padding: 10px 0;
    }

    .btn {
        width: 100%;
    }

    .hero-media {
        padding: 20px 0 0 20px;
    }

    .hero-media::before {
        right: 20px;
        bottom: 20px;
    }

    /* Stacked: the inline dots would float in empty space. */
    .hero-proof-list {
        flex-direction: column;
        gap: 8px;
    }

    .hero-proof-list li + li::before {
        display: none;
    }

    .case-hero {
        padding-top: calc(var(--header-h) + 48px);
    }

    .service-card {
        padding: 28px 24px;
    }

    .contact-info,
    .contact-form {
        padding: 28px 24px;
    }

    .testimonial-quote {
        font-size: 1.1rem;
    }

    .video-section {
        padding: 64px 0;
    }

    .video-split {
        gap: 32px;
    }

    .filter-chips {
        gap: 20px;
    }

    /* Keep the fixed-height behaviour, just smaller. */
    .image-container {
        height: 260px;
    }

    #carousel-container {
        min-height: 340px;
    }

    .carousel-slide {
        width: 95%;
    }

    .testimonial-author {
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
    }

    .author-img {
        min-width: 40px;
        width: 40px;
        height: 40px;
        margin-right: 10px;
        flex-shrink: 0;
    }

    .author-info {
        flex-grow: 1;
        min-width: 0;
    }

    .about-intro {
        flex-direction: column;
        align-items: flex-start;
        gap: 28px;
    }

    .about-img {
        flex: 0 0 auto;
        max-width: 200px;
    }

    .footer-grid {
        grid-template-columns: 1fr;
        gap: 32px;
    }

    .footer-bottom {
        flex-direction: column;
        align-items: flex-start;
    }

    .footer-legal-note {
        margin-top: -8px;
    }

    /* On a phone the bar carries the logo, the switch and the hamburger, which
       together outgrow a 390px viewport at the desktop logo size. */
    body > header .logo {
        font-size: 1.35rem;
    }

    .nav-actions {
        gap: 10px;
        margin-left: auto;
        margin-right: 14px;
    }

    /* Spacing between stacked buttons on the platform page. */
    .platform .btn {
        margin-bottom: 15px;
        display: inline-flex;
        width: auto;
    }
}

/* Narrowest phones. */
@media (max-width: 400px) {

    .btn {
        padding: 12px 20px;
        font-size: 0.95rem;
    }

    .container {
        width: 95%;
        padding: 0 8px;
    }

    body > header .container {
        padding: 0 8px;
    }

    .hamburger {
        margin-right: 0;
    }

    #carousel-container,
    .carousel-slide {
        width: 100% !important;
        max-width: 100% !important;
    }
}

/* Below ~360px the wordmark alone eats the room the hamburger needs. */
@media (max-width: 360px) {
    body > header .logo {
        font-size: 1.15rem;
    }

    .nav-actions {
        margin-right: 8px;
    }
}
