:root {
    --bg: #f7f9fa;
    --surface: #ecf0f2;
    --ink: #1f3038;
    --muted: #4c5a61;
    --accent: #b8451c;
    --accent-ink: #ffffff;
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    scrollbar-gutter: stable;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: 'Source Serif 4', Georgia, serif;
    font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
    line-height: 1.55;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

a {
    color: inherit;
}

.wrap {
    max-width: 1280px;
    margin: 0 auto;
    padding-left: clamp(20px, 4vw, 32px);
    padding-right: clamp(20px, 4vw, 32px);
}

h1,
h2 {
    font-family: 'Libre Franklin', system-ui, sans-serif;
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 0.95;
    margin: 0;
}

/* The app's own brand wordmark font (client/src/styles.css's `.font-brand`,
   client/src/app/shared/components/logo.component.html) — always rendered
   in capitals, matching the app exactly rather than the direction's own
   display face. */
.brand-font {
    font-family: 'Mountains of Christmas', cursive;
    font-weight: 700;
}

.nav-logo .brand-font {
    font-size: 1.3rem;
}

.hero h1.brand-font {
    letter-spacing: 0;
    text-transform: none;
}

.footer-menu .brand-font {
    font-size: 1.3rem;
}

.section-title {
    font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
    margin-bottom: clamp(32px, 5vw, 64px);
}

/* Fancy, cartoonish buttons: a pill with a solid candy-shell edge along the
   bottom (a flat strip, not a blurred shadow) standing in for the toy
   button's own "side" — it lifts on hover and the edge disappears on
   click. The edge is a decorative ::after, not a real border: a border's
   width is part of the box model, so shrinking it on press changes the
   button's actual layout height, which — inside any vertically centred
   parent (the hero, a centred chapter) — made the *parent* re-centre and
   amplified a small, deliberate 2px press into a much bigger, jumpy one.
   The ::after is absolutely positioned, so hiding it never resizes the
   button's own box and never reaches the parent at all. --btn-edge is the
   darker tone each variant sets for itself. */
.btn {
    --btn-edge: #7a2d12;
    --btn-edge-w: 5px;
    position: relative;
    -webkit-tap-highlight-color: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 999px;
    overflow: hidden;
    padding: 15px 34px 16px;
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 800;
    font-size: 0.95rem;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    background: var(--accent);
    color: var(--accent-ink);
    transform: translateY(0);
    transition: transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1), filter 0.15s ease;
}

.btn::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--btn-edge-w);
    background: var(--btn-edge);
    pointer-events: none;
    transition: opacity 0.1s ease;
}

.btn:hover {
    filter: brightness(1.08);
}

.btn:active {
    transform: translateY(2px);
}

.btn:active::after {
    opacity: 0.35;
}

.btn:focus-visible {
    outline: 3px solid var(--ink);
    outline-offset: 3px;
}

/* same "can't be clicked again" cue the native `disabled` attribute gave
   the live demo's "Run it" button, without actually disabling it — see
   the comment in script.js for why that attribute was the problem. */
.btn.is-running {
    opacity: 0.85;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-outline {
    --btn-edge: #d8dde0;
    background: var(--surface);
    color: var(--ink);
}

.btn-on-light {
    --btn-edge: #ecd3c4;
    background: #fff;
    color: var(--accent);
}

.placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 32px;
    border: 2px dashed var(--muted);
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.95rem;
    color: var(--ink);
    line-height: 1.5;
    background: var(--surface);
}

.placeholder b {
    display: block;
    font-weight: 800;
    margin-bottom: 8px;
    font-size: 1.05rem;
}

/* -------- nav --------
   Stays off the first screen entirely (not just transparent) so the hero
   gets the full viewport; it only appears, fixed, once the visitor scrolls
   past the hero far enough to want the nav links (script.js toggles
   `.nav-visible` on scroll). Hidden state uses transform+opacity (not
   display:none) so the appearance is a transition, not a jump cut, and
   pointer-events:none keeps it from intercepting clicks while invisible. */
.nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 18px clamp(20px, 4vw, 32px);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2000;
    /* above bpmn-js's own chrome (its "powered by" badge sits at z-index: 1000), so the diagram's watermark can't paint over the fixed nav while scrolling past it */
    background: var(--bg);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
    /* taste-skill-ignore: a real sticky bar, the house rules' own stated exception */
    transform: translateY(-100%);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.25s ease, opacity 0.25s ease;
}

.nav.nav-visible {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
    .nav {
        transition: none;
    }
}

.nav-logo {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: inherit;
}

.nav-logo img {
    width: 36px;
    height: 36px;
    border-radius: 50%;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 24px;
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 600;
    font-size: 0.9rem;
}

.nav-links a {
    text-decoration: none;
}

.nav-links a:hover {
    text-decoration: underline;
}

.nav-links a.btn:hover {
    text-decoration: none;
}

.btn-nav {
    --btn-edge-w: 4px;
    gap: 8px;
    padding: 11px 22px 12px;
    font-size: 0.92rem;
    margin-left: 20px;
}

.btn-icon {
    width: 1rem;
    height: 1rem;
    flex: none;
}

@media (max-width: 700px) {
    .nav-links {
        display: none;
    }
}

/* -------- hero: the object, large --------
   Full-height first screen (no nav in flow to share it with). The copy
   column is centered as one block within its half, not flush to the grid
   edge — a bigger logo, a smaller wordmark. */
.hero {
    position: relative;
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    align-items: center;
    min-height: 100svh;
    gap: 24px;
    overflow: hidden;
}

.hero-copy {
    padding: 0 clamp(20px, 4vw, 48px);
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: 560px;
    margin: 0 auto;
}

.hero-logo {
    width: clamp(120px, 14vw, 200px);
    height: clamp(120px, 14vw, 200px);
    border-radius: 50%;
    margin-bottom: 24px;
}

.hero h1 {
    font-size: clamp(2rem, 1.4rem + 2.2vw, 3.4rem);
    margin-bottom: 14px;
}

.hero-tagline {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--accent);
    margin: 0 0 14px;
}

.hero-lead {
    font-size: 1.2rem;
    max-width: 34ch;
    margin: 0 0 32px;
}

.hero-object {
    position: relative;
    height: 100svh;
    overflow: hidden;
}

.hero-object img {
    position: absolute;
    top: 0;
    right: -10%;
    width: 110%;
    height: 100%;
    object-fit: cover;
    object-position: 35% 20%;
}

@media (max-width: 900px) {
    .hero {
        grid-template-columns: 1fr;
        min-height: auto;
    }

    .hero-object {
        height: 48vh;
        order: -1;
    }

    .hero-object img {
        right: 0;
        width: 100%;
        object-position: 50% 15%;
    }

    .hero-copy {
        padding-top: 24px;
        padding-bottom: 40px;
    }

    .hero-logo {
        margin-bottom: 16px;
    }

    .hero-lead {
        margin-bottom: 20px;
    }
}

/* -------- sections -------- */
.section {
    padding-top: clamp(64px, 9vw, 140px);
    padding-bottom: clamp(64px, 9vw, 140px);
}

/* how it works: modeled / started / running, as real fragments, not plain
   colored rectangles */
.grow-heading {
    font-size: clamp(1.75rem, 1.2rem + 2.2vw, 3rem);
    margin-bottom: clamp(24px, 4vw, 48px);
}

.grow-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 32px;
    align-items: stretch;
}

.grow-tile {
    border-radius: 10px;
    background: #fff;
    padding: 16px;
    display: flex;
}

.grow-tile-inner {
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.grow-caption {
    margin-top: 16px;
}

.grow-caption p:first-child {
    font-weight: 700;
    font-family: 'Libre Franklin', sans-serif;
    margin: 0 0 6px;
}

.grow-caption p:last-child {
    font-size: 0.95rem;
    color: var(--muted);
    margin: 0;
    max-width: none;
}

@media (max-width: 760px) {
    .grow-tiles {
        grid-template-columns: 1fr;
    }
}

/* a genuine screenshot of the app itself, not a recreated fragment —
   everything else on the page that looks like the product (the "how it
   works" tiles, the live diagram) is built in HTML to stay crisp at any
   size; this one is a real capture, so it gets its own frame instead. */
.screenshot-lead {
    font-size: 1.1rem;
    color: rgba(255, 255, 255, 0.75);
    margin: 0 0 32px;
}

.screenshot-img {
    width: 100%;
    border-radius: 12px;
    display: block;
}

/* real app UI fragments — copied from client/src/app/features/tasks and
   client/src/app/features/models, same convention used elsewhere on this
   page (the showcase diagram) */
[data-ui] {
    font-family: ui-sans-serif, system-ui, sans-serif;
}

.bpmn-canvas {
    width: 100%;
    min-width: 0;
    height: 180px;
    color: #000;
    overflow: hidden;
    background: #fff;
}

.app-card {
    background: #fff;
    border-radius: 8px;
    padding: 18px;
    color: #111827;
}

.app-card-title {
    margin: 0 0 10px;
    font-weight: 600;
    font-size: 14px;
}

.mono-id {
    color: #6b7280;
    font-weight: 400;
}

.app-card-row {
    margin: 5px 0;
    font-size: 13px;
}

.app-card-row.muted {
    color: #6b7280;
}

.status-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-right: 5px;
    background: #2563eb;
}

.app-table {
    background: #fff;
    border-radius: 8px;
    overflow: hidden;
    font-size: 12px;
    color: #111827;
}

.app-table-head,
.app-table-row {
    display: grid;
    grid-template-columns: 0.8fr 1.5fr 1fr 0.35fr;
    gap: 6px;
    padding: 10px 12px;
    align-items: center;
}

.app-table-head {
    color: #6b7280;
    font-size: 11px;
    border-bottom: 1px solid #e5e7eb;
}

/* taste-skill-ignore: real table head rule, inside data-ui */
.strong {
    font-weight: 600;
}

.link-blue {
    color: #2563eb;
}

.muted {
    color: #6b7280;
}

.check {
    color: #16a34a;
    display: inline-flex;
}

/* features: two columns of plain text blocks, name over description —
   a single long row (name column, then description trailing off into
   empty space on the right) left a dead gap wherever a description was
   short. Stacking means every block's text fills the width it's given. */
.poster-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px 64px;
}

.poster-row {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.poster-head {
    display: flex;
    align-items: center;
    gap: 16px;
}

.poster-icon {
    width: 2rem;
    height: 2rem;
    flex: none;
    color: var(--accent);
}

.poster-name {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 800;
    font-size: clamp(1.4rem, 1rem + 1.6vw, 2.1rem);
    letter-spacing: -0.02em;
    line-height: 1;
    margin: 0;
}

.poster-desc {
    font-size: 1.05rem;
    color: var(--muted);
    margin: 0;
}

@media (max-width: 760px) {
    .poster-list {
        grid-template-columns: 1fr;
        gap: 28px;
    }
}

/* showcase: split chapters — a picture filling one entire half of the
   screen, the word and its sentence filling the other. A small portrait
   centred in a sea of flat colour read as an empty screen; letting the
   picture bleed edge-to-edge gives it real weight instead. The text side
   only ever carries a short word and one sentence, so the picture (shot
   1:1, not a tall 3:4) gets the wider share of the row and the text
   column stays snug around its own short lines. Alternates sides chapter
   to chapter for rhythm. */
.chapter {
    min-height: 90vh;
    display: grid;
    grid-template-columns: 3fr 2fr;
    color: #fff;
}

.chapter-media {
    grid-column: 1;
    grid-row: 1;
}

.chapter-text {
    grid-column: 2;
    grid-row: 1;
}

/* `order` alone would re-run auto-placement and hand the picture the
   narrower track on alternating rows (it did, until this was caught) —
   placement is explicit instead, so the picture always gets the 3fr
   track and only the column order (so left/right) swaps. `grid-row: 1`
   on both is load-bearing: sparse auto-placement won't backtrack a later
   DOM item into an earlier column of the row the cursor already passed,
   so without pinning the row, the swapped item fell to a second,
   content-sized row instead of sharing the first (which is how the
   picture silently lost its full height on every other chapter). */
.chapter:nth-child(even) {
    grid-template-columns: 2fr 3fr;
}

.chapter:nth-child(even) .chapter-media {
    grid-column: 2;
}

.chapter:nth-child(even) .chapter-text {
    grid-column: 1;
}

.chapter-media {
    position: relative;
    overflow: hidden;
}

.chapter-media-fill {
    position: absolute;
    inset: 0;
    border-radius: 0;
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.4);
    color: #fff;
}

.chapter-media-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.chapter-media-diagram {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(32px, 5vw, 64px);
}

.chapter-top {
    font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 800;
}

.bpmn-canvas-demo {
    height: clamp(280px, 38vh, 420px);
    border-radius: 10px;
}

.chapter-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 32px;
    padding: 48px clamp(24px, 5vw, 64px);
}

.chapter-bottom {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
}

.chapter-bottom p {
    max-width: 28ch;
    font-size: 1.1rem;
    margin: 0;
}

.chapter-bottom a {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 4px;
}

@media (max-width: 860px) {

    .chapter,
    .chapter:nth-child(even) {
        grid-template-columns: 1fr;
    }

    .chapter-media,
    .chapter-text,
    .chapter:nth-child(even) .chapter-media,
    .chapter:nth-child(even) .chapter-text {
        grid-column: 1;
        grid-row: auto;
    }

    .chapter-media {
        aspect-ratio: 1 / 1;
    }
}

/* pricing: lead with what actually costs something (a plain list of
   credit amounts), not a giant disconnected "1000" — that number is the
   free monthly grant, not a price, and leading with it before the actual
   cost facts read as "this is what it costs", which it isn't. */
.price-lead {
    font-size: 1.15rem;
    margin: 0 0 clamp(32px, 5vw, 48px);
}

.price-rows {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 32px;
}

.price-row-figure {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 800;
    font-size: clamp(2rem, 1.5rem + 2vw, 3rem);
    letter-spacing: -0.02em;
    line-height: 1;
    margin: 0 0 12px;
    color: var(--accent);
}

.price-row-desc {
    font-size: 1.05rem;
    color: var(--muted);
    margin: 0;
}

.price-grant {
    display: flex;
    align-items: center;
    gap: 24px;
    background: color-mix(in srgb, var(--accent) 10%, var(--bg));
    border-radius: 16px;
    padding: clamp(28px, 4vw, 36px);
    margin-top: clamp(40px, 6vw, 64px);
}

.price-grant-icon {
    width: 44px;
    height: 44px;
    flex: none;
    color: var(--accent);
}

.price-grant-figure {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 800;
    font-size: clamp(2.5rem, 2rem + 2.5vw, 3.75rem);
    letter-spacing: -0.02em;
    line-height: 1;
    margin: 0 0 6px;
    color: var(--accent);
    white-space: nowrap;
}

.price-grant-unit {
    font-size: 1.5rem;
    font-weight: 700;
}

.price-grant-desc {
    font-size: 1.1rem;
    margin: 0;
}

.price-cta {
    display: flex;
    align-items: center;
    gap: 28px;
    flex-wrap: wrap;
    margin-top: clamp(32px, 5vw, 56px);
}

.price-details-link {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: underline;
    text-underline-offset: 4px;
}

@media (max-width: 760px) {
    .price-rows {
        grid-template-columns: 1fr;
        gap: 28px;
    }
}

/* a real picture, full width, between the price and the FAQ */
.image-band {
    line-height: 0;
}

.image-band img {
    width: 100%;
    height: clamp(320px, 42vw, 640px);
    object-fit: cover;
    object-position: center 35%;
    display: block;
}

/* faq */
.faq-heading {
    font-size: clamp(2rem, 1.3rem + 3vw, 3.4rem);
    max-width: 16ch;
    margin: 0 0 48px;
}

/* the heading used to sit over a tall empty column (the list is pushed
   well right of it, for a wide left margin) — a picture now fills that
   column instead of leaving it blank. The heading stays full width
   (not squeezed into the narrow picture column) so it keeps its own
   measure regardless of how narrow that column gets. */
.faq-grid {
    display: grid;
    grid-template-columns: clamp(220px, 28vw, 380px) 1fr;
    gap: 32px;
}

.faq-portrait {
    width: 100%;
    height: 100%;
    min-height: 280px;
    object-fit: cover;
    border-radius: 10px;
}

.faq-list {
    display: flex;
    flex-direction: column;
}

@media (max-width: 760px) {
    .faq-grid {
        grid-template-columns: 1fr;
    }

    .faq-portrait {
        min-height: 240px;
    }
}

.faq-list details {
    padding: 18px 0;
}

.faq-list summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 1.25rem;
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 600;
    gap: 16px;
}

.faq-list summary::-webkit-details-marker {
    display: none;
}

.chev {
    width: 13px;
    height: 13px;
    border-right: 2px solid var(--ink);
    border-bottom: 2px solid var(--ink);
    transform: rotate(45deg);
    transition: transform 0.2s ease;
    flex: none;
}

details[open] .chev {
    transform: rotate(-135deg);
}

.faq-list p {
    max-width: 48ch;
    font-size: 1.05rem;
    margin: 16px 0 0;
    color: var(--muted);
}

.faq-list details[open] {
    background: var(--surface);
    margin: 0 -24px;
    padding: 18px 24px;
}

/* cta: a plain close, no fake form */
.cta-section {
    background: var(--accent);
    color: #fff;
    padding: clamp(80px, 12vh, 160px) 0;
}

.cta-centered {
    max-width: 640px;
    text-align: center;
}

.cta-close {
    font-size: clamp(2.5rem, 2rem + 3.5vw, 5rem);
    line-height: 0.95;
    margin: 0 0 20px;
}

.cta-close+p {
    max-width: 36ch;
    font-size: 1.1rem;
    margin: 0 auto 32px;
}

/* footer: photograph half, menu half */
.site-footer {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 70vh;
}

/* absolutely positioned (like the chapter photos), not a plain flow img:
   without this, a tall source image can make this column's own content
   height exceed the grid row's intended 70vh, stretching the whole
   footer past the screen on anything shorter than the photo is tall. */
.footer-photo {
    position: relative;
    overflow: hidden;
}

.footer-photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.footer-menu {
    background: var(--ink);
    color: #fff;
    padding: clamp(32px, 6vw, 72px) clamp(24px, 4vw, 48px);
    display: flex;
    flex-direction: column;
}

.footer-menu .nav-logo {
    color: #fff;
    margin-bottom: 48px;
}

.footer-menu-list {
    list-style: none;
    margin: 0 0 auto;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.footer-menu-list a {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 800;
    font-size: clamp(1.4rem, 1.1rem + 1.5vw, 2rem);
    text-decoration: none;
    display: inline-block;
    transition: transform 0.15s ease;
}

.footer-menu-list a:hover {
    transform: translateX(12px);
}

.footer-bottom {
    display: flex;
    justify-content: space-between;
    font-family: 'Libre Franklin', sans-serif;
    font-size: 13px;
    opacity: 0.7;
    margin-top: 48px;
    flex-wrap: wrap;
    gap: 8px;
}

@media (max-width: 860px) {
    .site-footer {
        grid-template-columns: 1fr;
    }

    .footer-photo {
        min-height: 50vh;
    }
}

[data-reveal] {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}

[data-reveal].in-view {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    [data-reveal] {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* The live demo's highlight classes — copied verbatim (colors) from
   client/src/app/shared/components/bpmn-viewer.component.scss. */
#showcase-diagram .processita-executed .djs-visual> :first-child:not(defs),
#showcase-diagram .processita-executed .djs-visual>defs+* {
    stroke: #2563eb !important;
}

#showcase-diagram .processita-active .djs-visual> :first-child:not(defs),
#showcase-diagram .processita-active .djs-visual>defs+* {
    stroke: #16a34a !important;
    stroke-width: 3px !important;
}

#modeled-diagram .djs-visual {
    opacity: 1;
}