/* Dayalabs — styles for the agency site and landing page.
   Clean and monochrome, after Tappz, wonder.design and nalarx.com: no borders or lines; things are grouped by
   spacing and by soft grey cards. Headings are medium weight, and the only colour comes from the product icons.
   Light by default; data-theme="dark" on <html> switches the tokens below. Neither follows the visitor's OS setting,
   and "only" in color-scheme keeps browsers that darken pages on their own (in dark mode) off the light theme.
   Motion is calm and has a job: things ease in as they arrive and answer when touched, with no bounce, glow or colour.
   It all lives under "Motion" at the end and switches off for visitors who ask for reduced motion.
   Colours and sizes come from these tokens; change them here, not in components. */

:root {
    color-scheme: only light;
    --bg: #ffffff;
    --tint: #f5f6f7;
    --tint-2: #edeef1;
    --ink: #0e1116;
    --ink-hover: #2a2f38;
    --on-ink: #ffffff;
    --text: #2b303a;
    --muted: #616874;
    --faint: #6f757e;
    --soft: #8f959f;
    --header-bg: rgba(255, 255, 255, 0.9);
    --selection: rgba(14, 17, 22, 0.12);
    --icon-edge: transparent;
    /* The first-visit loader: a screen in ink that lifts off the page */
    --loader-bg: var(--ink);
    --loader-fg: var(--on-ink);

    --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

    --radius: 12px;
    --radius-lg: 18px;
    --container: 1160px;
    --gutter: 20px;
    --pad: clamp(22px, 3vw, 30px);
    --header-h: 64px;

    /* Fast start, long soft landing for things arriving; an even curve for things that cover the screen */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.76, 0, 0.24, 1);
}

:root[data-theme="dark"] {
    color-scheme: only dark;
    --bg: #0a0a0b;
    --tint: #141416;
    --tint-2: #1c1c1f;
    --ink: #f4f4f5;
    --ink-hover: #d8d9dc;
    --on-ink: #0a0a0b;
    --text: #d4d5d8;
    --muted: #9a9da5;
    --faint: #80848c;
    --soft: #5f636a;
    --header-bg: rgba(10, 10, 11, 0.85);
    --selection: rgba(255, 255, 255, 0.2);
    /* A faint edge so dark app icons don't disappear into the page */
    --icon-edge: rgba(255, 255, 255, 0.1);
    /* A bright screen would flash in the dark, so the loader is a step lighter than the page instead */
    --loader-bg: var(--tint-2);
    --loader-fg: var(--ink);
}

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

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + 16px);
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
}

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

a {
    color: inherit;
    text-decoration: none;
}

h1, h2, h3, h4, p, ul, ol, dl, dd, figure {
    margin: 0;
}

ul, ol {
    padding: 0;
    list-style: none;
}

::selection {
    background: var(--selection);
    color: var(--ink);
}

:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 3px;
    border-radius: 4px;
}

.icon {
    width: 1.25em;
    height: 1.25em;
    flex-shrink: 0;
}

.skip-link {
    position: absolute;
    left: 16px;
    top: -60px;
    z-index: 100;
    padding: 10px 16px;
    border-radius: var(--radius);
    background: var(--ink);
    color: var(--on-ink);
    font-weight: 500;
}

.skip-link:focus {
    top: 12px;
}

.container {
    width: 100%;
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* ---------- Typography ---------- */

.eyebrow,
.chip {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.display {
    font-size: clamp(2.15rem, 5.6vw, 4.25rem);
    font-weight: 500;
    line-height: 1.05;
    letter-spacing: -0.045em;
    color: var(--ink);
    text-wrap: balance;
}

.h2 {
    font-size: clamp(1.75rem, 3.4vw, 2.6rem);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: -0.035em;
    color: var(--ink);
    text-wrap: balance;
}

.h3 {
    font-size: 1.075rem;
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: -0.01em;
    color: var(--ink);
}

.lead {
    font-size: clamp(1rem, 1.4vw, 1.125rem);
    line-height: 1.6;
    color: var(--muted);
}

.muted {
    color: var(--muted);
}

/* The quieter second half of a two-tone headline */
.text-soft {
    color: var(--soft);
}

.text-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 15px;
    font-weight: 500;
    color: var(--ink);
}

.text-link:hover {
    color: var(--muted);
}

.text-link .icon {
    width: 16px;
    height: 16px;
    transition: transform 0.35s var(--ease-out);
}

.text-link:hover .icon {
    transform: translateX(3px);
}

/* ---------- Buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 20px;
    border: 0;
    border-radius: 999px;
    font: inherit;
    font-size: 15px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.2s, transform 0.25s var(--ease-out);
}

.btn:active {
    transform: scale(0.97);
}

/* main.js wraps each plain-text label in .btn-roll; on hover the label rolls up to a copy of itself (see Motion) */
.btn-roll {
    display: block;
    overflow: hidden;
    line-height: 1.3;
}

.btn-roll > span {
    display: block;
    position: relative;
}

.btn-roll > span::after {
    content: attr(data-label);
    content: attr(data-label) / "";
    position: absolute;
    top: 100%;
    left: 0;
}

.btn .icon {
    width: 18px;
    height: 18px;
}

.btn-sm {
    min-height: 36px;
    padding: 0 16px;
    font-size: 14px;
}

.btn-primary {
    background: var(--ink);
    color: var(--on-ink);
}

.btn-primary:hover {
    background: var(--ink-hover);
}

.btn-secondary {
    background: var(--tint);
    color: var(--ink);
}

.btn-secondary:hover {
    background: var(--tint-2);
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/* ---------- Header ---------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--header-bg);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    /* Stays put while the page underneath cross-fades to the next one */
    view-transition-name: site-header;
}

/* main.js slides the header away while scrolling down and brings it back on the way up */
.site-header.is-hidden {
    transform: translateY(-100%);
}

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

.logo {
    display: inline-flex;
    align-items: center;
    color: var(--ink);
}

.logo-svg {
    display: block;
    width: auto;
    height: 34px;
}

.nav-menu {
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    gap: 20px;
    margin-left: auto;
}

/* The theme toggle, and on small screens the menu button beside it */
.nav-end {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: -6px;
}

/* A moon in the light theme and a sun in the dark one: the icon of the theme it switches to. The two share one spot and
   turn into each other. */
.theme-toggle {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.2s, transform 0.25s var(--ease-out);
}

.theme-toggle:hover {
    background: var(--tint);
}

.theme-toggle:active {
    transform: scale(0.92);
}

.theme-toggle > span {
    grid-area: 1 / 1;
    display: grid;
    transition: transform 0.6s var(--ease-out), opacity 0.3s;
}

.theme-toggle .icon {
    width: 19px;
    height: 19px;
}

.theme-sun,
:root[data-theme="dark"] .theme-moon {
    opacity: 0;
    transform: rotate(-90deg) scale(0.4);
}

:root[data-theme="dark"] .theme-sun {
    opacity: 1;
    transform: none;
}

.nav-menu ul {
    display: flex;
    gap: 4px;
}

.nav-menu ul a {
    display: block;
    padding: 8px 12px;
    font-size: 14.5px;
    color: var(--muted);
    transition: color 0.15s;
}

.nav-menu ul a:hover,
.nav-menu ul a[aria-current="page"] {
    color: var(--ink);
}

/* A soft pill behind the current page's link; main.js slides it to whichever link is hovered or focused */
.nav-pill {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    border-radius: 999px;
    background: var(--tint);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.45s var(--ease-out), width 0.45s var(--ease-out), height 0.45s var(--ease-out), opacity 0.2s;
}

.nav-pill.is-shown {
    opacity: 1;
}

.nav-pill.no-anim {
    transition: none;
}

/* The mark turns one diamond clockwise on hover; the ring has eight, so it lands on itself */
.nav-brand .logo-svg > path:first-child {
    transform-box: fill-box;
    transform-origin: center;
    transition: rotate 0.8s var(--ease-out);
}

.nav-brand:hover .logo-svg > path:first-child {
    rotate: 45deg;
}

.nav-toggle {
    display: none;
    width: 44px;
    height: 44px;
    margin-right: -10px;
    border: 0;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

/* Two bars that cross into an X while the menu is open */
.nav-toggle-bars {
    position: relative;
    width: 22px;
    height: 12px;
}

.nav-toggle-bars::before,
.nav-toggle-bars::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 1.6px;
    border-radius: 1px;
    background: currentColor;
    transition: transform 0.45s var(--ease-out);
}

.nav-toggle-bars::before {
    top: 0;
}

.nav-toggle-bars::after {
    bottom: 0;
}

.nav-open .nav-toggle-bars::before {
    transform: translateY(5.2px) rotate(45deg);
}

.nav-open .nav-toggle-bars::after {
    transform: translateY(-5.2px) rotate(-45deg);
}

@media (max-width: 860px) {
    .nav-toggle {
        display: grid;
        place-items: center;
    }

    /* A full-screen menu under the header: big links at the top, the call to action at the bottom. The header's
       backdrop-filter makes it the containing block, hence a height rather than bottom: 0. */
    .nav-menu {
        position: fixed;
        inset: var(--header-h) 0 auto 0;
        height: calc(100dvh - var(--header-h));
        flex-direction: column;
        align-items: stretch;
        justify-content: space-between;
        gap: 24px;
        padding: 12px var(--gutter) max(24px, env(safe-area-inset-bottom));
        overflow-y: auto;
        background: var(--bg);
        visibility: hidden;
        opacity: 0;
        transition: opacity 0.15s, visibility 0.15s;
    }

    .nav-menu ul {
        flex-direction: column;
        gap: 0;
    }

    .nav-menu ul a {
        padding: 10px 0;
        font-size: 30px;
        font-weight: 500;
        letter-spacing: -0.03em;
        line-height: 1.2;
    }

    .nav-pill {
        display: none;
    }

    .nav-cta {
        min-height: 50px;
        font-size: 16px;
    }

    .nav-open {
        overflow: hidden;
    }

    .nav-open .site-header {
        background: var(--bg);
    }

    .nav-open .nav-menu {
        visibility: visible;
        opacity: 1;
    }
}

/* ---------- Sections ---------- */

.section {
    padding: clamp(56px, 8vw, 104px) 0;
}

.section-tight {
    padding: clamp(32px, 4vw, 48px) 0;
}

.section-head {
    display: grid;
    gap: 12px;
    max-width: 640px;
    margin-bottom: clamp(28px, 4vw, 44px);
}

.section-head-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 20px 40px;
    margin-bottom: clamp(28px, 4vw, 44px);
}

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

.section-link {
    margin-top: 28px;
}

.head-compact {
    margin-bottom: 28px;
}

/* ---------- Hero ---------- */

.hero {
    padding: clamp(56px, 9vw, 112px) 0 0;
}

.hero-inner {
    display: grid;
    gap: 20px;
}

/* Headline on the left, text and buttons on the right (wonder.design pattern) */
.hero-split {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 32px clamp(32px, 6vw, 80px);
    align-items: end;
}

.hero-aside {
    display: grid;
    gap: 24px;
}

.hero-proof {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    font-size: 14px;
    color: var(--muted);
}

.hero-proof li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.hero-proof .icon {
    width: 16px;
    height: 16px;
    color: var(--ink);
}

@media (max-width: 860px) {
    .hero-split {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Our products under the hero, on one soft grey card like an app dock: icon on top, name below.
   --cols sets how many sit in a row and the last row is centred, so the 11 items read 11, 6 + 5 or 4 + 4 + 3. */
.shelf {
    padding: clamp(56px, 8vw, 96px) 0 clamp(24px, 3vw, 32px);
    text-align: center;
}

.shelf-title {
    margin-bottom: 20px;
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--faint);
}

.shelf-row {
    --cols: 11;
    --gap: 8px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 24px var(--gap);
    padding: clamp(20px, 2.6vw, 28px);
    border-radius: var(--radius-lg);
    background: var(--tint);
}

.shelf-item {
    flex: 0 0 calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols));
    min-width: 0;
}

.shelf-item,
.shelf-next {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--text);
}

.shelf-row .tile {
    width: 52px;
    height: 52px;
    border-radius: 12px;
}

.shelf-row .tile-letter {
    font-size: 22px;
}

/* The last item: a "+" for the visitor's own product, linking to starting a project */
.shelf-next {
    width: 100%;
    color: var(--muted);
}

.shelf-next:hover {
    color: var(--ink);
}

.tile-plus {
    display: grid;
    place-items: center;
    background: var(--bg);
    color: var(--ink);
    font-size: 24px;
    font-weight: 300;
    line-height: 1;
    transition: background-color 0.15s, color 0.15s, transform 0.6s var(--ease-out);
}

.shelf-next:hover .tile-plus {
    background: var(--ink);
    color: var(--on-ink);
    transform: rotate(90deg);
}

@media (max-width: 1080px) {
    .shelf-row {
        --cols: 6;
    }
}

@media (max-width: 560px) {
    .shelf-row {
        --cols: 4;
        --gap: 4px;
        row-gap: 20px;
        padding: 20px 12px;
    }

    .shelf-item,
    .shelf-next {
        gap: 8px;
        font-size: 12.5px;
    }

    .shelf-row .tile {
        width: 46px;
        height: 46px;
        border-radius: 11px;
    }
}

.page-hero {
    padding: clamp(56px, 8vw, 96px) 0 clamp(24px, 4vw, 48px);
}

.page-hero .hero-inner {
    max-width: 760px;
}

.page-hero .display {
    font-size: clamp(2.25rem, 5vw, 3.6rem);
}

.page-hero .lead {
    max-width: 620px;
}

.page-hero .btn-row {
    margin-top: 8px;
}

/* ---------- Cards ---------- */

.grid {
    display: grid;
    gap: 12px;
}

.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 960px) {
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
    .grid-2,
    .grid-3 { grid-template-columns: minmax(0, 1fr); }
}

/* A soft grey card: no border, no shadow */
.card {
    padding: var(--pad);
    border-radius: var(--radius-lg);
    background: var(--tint);
}

a.card {
    transition: background-color 0.15s;
}

a.card:hover {
    background: var(--tint-2);
}

.card p {
    color: var(--muted);
    font-size: 15px;
}

.card .h3 + p {
    margin-top: 8px;
}

.card-icon {
    display: block;
    margin-bottom: 28px;
    color: var(--ink);
}

.card-icon .icon {
    width: 22px;
    height: 22px;
    stroke-width: 1.4;
}

.card-kicker {
    margin-bottom: 28px;
    font-size: 13px;
    color: var(--faint);
}

/* Service bullet list */
.pillar-list {
    display: grid;
    gap: 8px;
    margin-top: 22px;
}

.pillar-list li {
    display: flex;
    gap: 10px;
    font-size: 14.5px;
    color: var(--text);
}

.pillar-list .icon {
    width: 16px;
    height: 16px;
    margin-top: 3px;
    color: var(--faint);
}

/* ---------- Products ---------- */

.tile {
    width: 48px;
    height: 48px;
    border-radius: 11px;
    flex-shrink: 0;
    box-shadow: 0 0 0 1px var(--icon-edge);
}

.tile-letter {
    display: grid;
    place-items: center;
    background: var(--ink);
    color: var(--on-ink);
    font-size: 20px;
    font-weight: 500;
}

/* Case studies: a real screenshot on a soft grey stage, then the name and a one-line summary */
.cases {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 48px 20px;
}

.cases > li {
    min-width: 0;
}

/* A text-only card in the same grid sits at the top instead of stretching to the screenshot's height */
.cases > li > .card {
    height: auto;
}

@media (max-width: 760px) {
    .cases {
        grid-template-columns: minmax(0, 1fr);
        gap: 36px;
    }
}

.case {
    display: grid;
    gap: 18px;
}

/* The screenshot sits in from the top and sides and runs off the bottom of the stage */
.case-shot {
    display: block;
    aspect-ratio: 16 / 11;
    padding: 7% 7% 0;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background: var(--tint);
    transition: background-color 0.15s;
}

.case-shot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top left;
    border-radius: 8px 8px 0 0;
}

/* For a screenshot that must not be cropped, like a wide toolbar */
.case-shot-contain {
    display: grid;
    place-items: center;
    padding: 7%;
}

.case-shot-contain img {
    height: auto;
    object-fit: contain;
    border-radius: 8px;
}

/* A product with a landing page: the landing page sits in at the top left, and the app sits in front of it at the
   bottom right, running off the bottom. A ring in the stage's own colour keeps the two apart, instead of a shadow. */
.case-shot-pair {
    position: relative;
    padding: 0;
}

.case-shot-pair img {
    position: absolute;
    height: auto;
    aspect-ratio: 16 / 11;
    object-fit: cover;
    object-position: top left;
}

.case-shot-pair .case-landing {
    top: 7%;
    left: 7%;
    width: 70%;
    border-radius: 8px;
}

.case-shot-pair .case-app {
    top: 40%;
    right: 7%;
    width: 62%;
    border: 5px solid var(--tint);
    border-radius: 12px;
    transition: border-color 0.15s;
}

/* Several app screens (more_shots) share the front spot; the one showing is .is-active, and main.js moves it along */
.case-shot[data-rotate] .case-app:not(.is-active) {
    opacity: 0;
    scale: 0.97;
}

.case-shot[data-rotate] .case-app.is-active {
    z-index: 1;
}

/* A wide strip, like Docka's toolbar, keeps its own shape near the bottom instead of running off it */
.case-shot-pair.case-shot-contain .case-app {
    top: auto;
    bottom: 9%;
    aspect-ratio: auto;
    object-fit: contain;
}

a.case:hover .case-shot {
    background: var(--tint-2);
}

a.case:hover .case-shot-pair .case-app {
    border-color: var(--tint-2);
}

.case-info {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 2px 14px;
    align-items: start;
}

.case-info .tile {
    grid-row: span 4;
    width: 40px;
    height: 40px;
    border-radius: 10px;
}

.case-info .tile-letter {
    font-size: 17px;
}

.case-name {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 16px;
    font-weight: 500;
    color: var(--ink);
}

.case-name .icon {
    width: 15px;
    height: 15px;
    color: var(--faint);
}

a.case:hover .case-name .icon {
    color: var(--ink);
}

.case-kind {
    font-size: 15px;
    color: var(--muted);
}

.case-text {
    margin-top: 4px;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--muted);
}

.case-meta {
    margin-top: 4px;
    font-size: 13px;
    color: var(--faint);
}


/* A client: logo beside the text, in a card */
.product {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    height: 100%;
}

.product-body {
    min-width: 0;
    flex: 1;
}

.product-name {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: 16px;
    font-weight: 500;
    color: var(--ink);
}

.product-name .icon {
    width: 15px;
    height: 15px;
    color: var(--faint);
}

.product p {
    margin-top: 6px;
    font-size: 15px;
    line-height: 1.55;
}

.tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 14px;
}

.tag {
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--bg);
    font-size: 13px;
    color: var(--muted);
}

.filter {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 36px;
}

.filter button {
    min-height: 36px;
    padding: 0 14px;
    border: 0;
    border-radius: 999px;
    background: var(--tint);
    color: var(--text);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.25s, color 0.25s, transform 0.25s var(--ease-out);
}

.filter button:hover {
    background: var(--tint-2);
}

.filter button:active {
    transform: scale(0.96);
}

.filter button[aria-pressed="true"] {
    background: var(--ink);
    color: var(--on-ink);
}

[data-product][hidden] {
    display: none;
}

/* Row of product icons */
.logo-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.logo-strip .tile {
    width: 40px;
    height: 40px;
    border-radius: 10px;
}

.logo-strip .tile-letter {
    font-size: 17px;
}

/* ---------- Steps ---------- */

/* Four plain columns, numbered */
.steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 32px 24px;
}

.step-num {
    display: block;
    margin-bottom: 20px;
    font-size: 13px;
    color: var(--faint);
}

.step-terms {
    display: block;
    margin-top: 4px;
    font-size: 14px;
    color: var(--faint);
}

.step p {
    margin-top: 12px;
    font-size: 15px;
    color: var(--muted);
}

@media (max-width: 960px) {
    .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
    .steps { grid-template-columns: minmax(0, 1fr); }
}

/* Steps stacked as cards, beside a sticky heading */
.steps-stack {
    display: grid;
    gap: 12px;
}

.steps-stack .step {
    padding: var(--pad);
    border-radius: var(--radius-lg);
    background: var(--tint);
}

.steps-stack .step-num {
    margin-bottom: 14px;
}

/* Numbered process rows */
.process {
    display: grid;
    gap: 12px;
}

.process-row {
    display: grid;
    grid-template-columns: 80px minmax(0, 1fr) minmax(0, 1.2fr);
    gap: 12px 32px;
    padding: var(--pad);
    border-radius: var(--radius-lg);
    background: var(--tint);
}

.process-num {
    font-size: clamp(1.75rem, 3.4vw, 2.5rem);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.04em;
    color: var(--soft);
}

.process-title {
    font-size: clamp(1.2rem, 2.2vw, 1.5rem);
    font-weight: 500;
    letter-spacing: -0.025em;
    line-height: 1.2;
    color: var(--ink);
}

.process-row .step-terms {
    margin-top: 8px;
}

.process-row > p {
    color: var(--muted);
}

@media (max-width: 760px) {
    .process-row {
        grid-template-columns: 40px minmax(0, 1fr);
    }

    .process-row > p {
        grid-column: 2;
    }
}

/* Stack */
.stack {
    display: grid;
    gap: 24px;
}

.stack-group {
    display: grid;
    grid-template-columns: 120px minmax(0, 1fr);
    gap: 16px;
    align-items: baseline;
}

.stack-label {
    font-size: 14px;
    font-weight: 500;
    color: var(--ink);
}

@media (max-width: 560px) {
    .stack-group {
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
    }
}

/* ---------- Two columns ---------- */

.split {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: clamp(32px, 6vw, 80px);
    align-items: start;
}

.split-sticky {
    position: sticky;
    top: calc(var(--header-h) + 32px);
}

.split-sticky .section-head {
    margin-bottom: 0;
}

.split-sticky .btn-row {
    margin-top: 28px;
}

@media (max-width: 860px) {
    .split {
        grid-template-columns: minmax(0, 1fr);
    }

    .split-sticky {
        position: static;
    }
}

/* Label and text pairs */
.rows {
    display: grid;
    gap: 28px;
}

.row {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    gap: 8px 32px;
}

.row p {
    color: var(--muted);
    font-size: 15px;
}

@media (max-width: 560px) {
    .row {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Checklist */
.checklist {
    display: grid;
    gap: 12px;
}

.checklist li {
    display: flex;
    gap: 10px;
    color: var(--text);
}

.checklist .icon {
    width: 18px;
    height: 18px;
    margin-top: 3px;
    color: var(--ink);
}

/* ---------- FAQ ---------- */

/* Each question is a soft grey row */
.faq {
    display: grid;
    gap: 8px;
}

.faq details {
    border-radius: var(--radius);
    background: var(--tint);
}

.faq summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 18px 22px;
    font-size: 16px;
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
    list-style: none;
}

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

/* The plus turns into a cross while the answer is open; main.js adds .is-closing while an answer slides shut */
.faq summary::after {
    content: "+";
    flex-shrink: 0;
    font-size: 22px;
    font-weight: 300;
    line-height: 1;
    color: var(--muted);
    transition: transform 0.45s var(--ease-out);
}

.faq details[open]:not(.is-closing) summary::after {
    transform: rotate(45deg);
}

.faq details p {
    max-width: 680px;
    padding: 0 22px 20px;
    color: var(--muted);
}

/* ---------- Call to action ---------- */

/* Plain and centred, no box (Tappz pattern) */
.cta {
    display: grid;
    gap: 16px;
    justify-items: center;
    max-width: 640px;
    margin: 0 auto;
    text-align: center;
}

.cta .btn-row {
    justify-content: center;
    margin-top: 12px;
}

/* The first-call agenda on the contact page */
.cta-card {
    padding: var(--pad);
    border-radius: var(--radius-lg);
    background: var(--tint);
}

.cta-card-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
    font-size: 15px;
    font-weight: 500;
    color: var(--ink);
}

.cta-card-title .icon {
    color: var(--muted);
}

.cta-card .checklist {
    font-size: 15px;
}

/* ---------- Contact ---------- */

.contact-list {
    display: grid;
    gap: 12px;
}

.contact-item {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 20px var(--pad);
}

.contact-item .card-icon {
    margin: 0;
}

.contact-label {
    font-size: 13px;
    color: var(--muted);
}

.contact-value {
    font-weight: 500;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.form {
    display: grid;
    gap: 18px;
}

.field {
    display: grid;
    gap: 8px;
}

.field label {
    font-size: 14px;
    font-weight: 500;
    color: var(--ink);
}

.field .hint {
    font-weight: 400;
    color: var(--muted);
}

/* Fields sit inside a grey card, so they are the page colour; the outline only appears on focus */
.field input,
.field select,
.field textarea {
    width: 100%;
    min-height: 46px;
    padding: 11px 14px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--ink);
    font: inherit;
    font-size: 16px;
    transition: border-color 0.2s;
}

.field textarea {
    min-height: 140px;
    resize: vertical;
}

.field select {
    appearance: none;
    padding-right: 40px;
    text-overflow: ellipsis;
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 20px) 50%, calc(100% - 15px) 50%;
    background-size: 5px 5px;
    background-repeat: no-repeat;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--ink);
}

.field-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

@media (max-width: 560px) {
    .field-row {
        grid-template-columns: minmax(0, 1fr);
    }
}

.form-note {
    font-size: 13px;
    color: var(--muted);
}

/* Filled in by main.js once the form hands the message to the email app */
.form-status {
    font-size: 14px;
    color: var(--ink);
}

.form-status:empty {
    display: none;
}

.form-card {
    padding: clamp(24px, 4vw, 36px);
}

/* ---------- Footer ---------- */

.site-footer {
    margin-top: clamp(24px, 4vw, 48px);
    background: var(--tint);
}

.footer-main {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px 48px;
    padding-top: 48px;
    padding-bottom: 24px;
}

.footer-about p {
    max-width: 340px;
    margin-top: 14px;
    font-size: 14px;
    color: var(--muted);
}

.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 24px;
    font-size: 14px;
    color: var(--muted);
}

.footer-links a:hover,
.footer-bottom a:hover {
    color: var(--ink);
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px 24px;
    padding-top: 16px;
    padding-bottom: 32px;
    font-size: 13px;
    color: var(--faint);
}

.is-landing .site-footer {
    margin-top: 0;
}

.is-landing .footer-bottom {
    padding-top: 32px;
}

/* ---------- Landing page ---------- */

.lp-sticky-cta {
    display: none;
}

@media (max-width: 640px) {
    .lp-sticky-cta {
        position: fixed;
        left: 12px;
        right: 12px;
        bottom: 12px;
        z-index: 40;
        display: flex;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s;
    }

    .lp-sticky-cta .btn {
        flex: 1;
        box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.35);
    }

    .lp-sticky-cta.is-visible {
        opacity: 1;
        pointer-events: auto;
    }

    .is-landing .site-footer {
        padding-bottom: 72px;
    }
}

.fit-list {
    display: grid;
    gap: 12px;
}

.fit-card {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 20px var(--pad);
}

.fit-card > .icon {
    width: 20px;
    height: 20px;
    margin-top: 2px;
    color: var(--ink);
}

.fit-card p {
    color: var(--text);
    font-size: 16px;
}

/* ---------- Small pieces ---------- */

/* Contact line beside the FAQ */
.person {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 28px;
}

.person .card-icon {
    margin: 0;
}

.person-name {
    font-size: 14px;
    font-weight: 500;
    color: var(--ink);
}

.person a {
    font-size: 14px;
    color: var(--muted);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.person a:hover {
    color: var(--ink);
}

.chip {
    justify-self: start;
}

/* About page story card */
.story {
    display: grid;
    gap: 20px;
}

.story p {
    font-size: 16px;
    line-height: 1.7;
    color: var(--text);
}

/* A line of text with a link under a grid */
.note-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
    margin-top: 28px;
    color: var(--muted);
}

.mt-sm { margin-top: 12px; }
.mt-md { margin-top: 28px; }

/* ---------- Motion ---------- */

/* Hero headlines come split into words from hero_heading() in functions.php; they lay out the same either way */
.w,
.w > span {
    display: inline-block;
}

/* With the header slid away, sticky headings move up into its place */
.header-hidden .split-sticky {
    top: 32px;
}

/* A thin bar at the top while the next page loads (main.js); it stays out of sight unless the wait passes 150ms */
.nav-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 210;
    height: 2px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: 0 50%;
    opacity: 0;
    pointer-events: none;
}

.nav-progress.is-active {
    opacity: 1;
    transform: scaleX(0.85);
    transition: transform 4s cubic-bezier(0.1, 0.7, 0.2, 1) 0.15s, opacity 0.2s 0.15s;
}

/* Only drawn when the head script sets .has-loader: the first page of a visit */
.loader {
    display: none;
}

/* A page Chrome prerenders in the background holds its animations until it is actually opened */
.is-prerendering *,
.is-prerendering *::before,
.is-prerendering *::after {
    animation-play-state: paused !important;
}

@media (prefers-reduced-motion: no-preference) {
    /* Between pages the old page cross-fades into the new one while the header stays put (Chrome, Edge, Safari) */
    @view-transition {
        navigation: auto;
    }

    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation-duration: 0.35s;
    }

    /* Loader: the mark builds itself diamond by diamond, clockwise, turning as it goes, then the screen lifts away.
       It runs on time alone (about 1.8s) rather than waiting for the page, so a slow connection is never held up. */
    .has-loader .loader {
        position: fixed;
        inset: 0;
        z-index: 200;
        display: grid;
        place-items: center;
        background: var(--loader-bg);
        color: var(--loader-fg);
        animation: loader-lift 0.8s var(--ease-in-out) 1.05s forwards;
    }

    .loader-mark {
        width: 60px;
        height: 60px;
        overflow: visible;
        animation: mark-turn 1.2s var(--ease-out) both, mark-leave 0.5s var(--ease-in-out) 1s forwards;
    }

    .loader-mark path {
        fill: currentColor;
        transform-box: fill-box;
        transform-origin: center;
        animation: piece-in 0.6s var(--ease-out) both;
        animation-delay: calc(0.08s + var(--i) * 0.05s);
    }

    .has-loader .site-header {
        animation: drop-in 0.9s var(--ease-out) 1.45s backwards;
    }

    /* Each page opens on its hero: the eyebrow, the headline word by word, then the text, buttons and product dock.
       --intro is when that starts; on the first page it begins as the loader starts to lift, so there is a page
       coming into view underneath it. */
    :root {
        --intro: 0.05s;
    }

    .has-loader {
        --intro: 1.1s;
    }

    .hero .eyebrow,
    .hero .lead,
    .hero .btn-row,
    .hero-proof,
    .shelf-title,
    .shelf-row {
        animation: rise 1s var(--ease-out) both;
        animation-delay: var(--intro);
    }

    .hero .lead { animation-delay: calc(var(--intro) + 0.3s); }
    .hero .btn-row { animation-delay: calc(var(--intro) + 0.4s); }
    .hero-proof { animation-delay: calc(var(--intro) + 0.5s); }
    .shelf-title { animation-delay: calc(var(--intro) + 0.45s); }
    .shelf-row { animation-delay: calc(var(--intro) + 0.5s); }

    /* Each word rises from behind its own baseline; the clip reaches past the glyphs on every side but the bottom */
    .hero .w {
        clip-path: inset(-0.3em -0.3em -0.14em -0.3em);
    }

    .hero .w > span {
        animation: word-up 1.1s var(--ease-out) both;
        animation-delay: calc(var(--intro) + 0.06s + var(--w) * 0.045s);
    }

    .shelf-item {
        animation: rise-small 0.8s var(--ease-out) both;
        animation-delay: calc(var(--intro) + 0.6s + var(--i) * 0.035s);
    }

    /* Sections fade up as they scroll into view; main.js marks them and staggers the ones arriving together */
    [data-reveal] {
        transition: opacity 0.9s var(--ease-out), transform 1.1s var(--ease-out);
        transition-delay: var(--delay, 0s);
    }

    [data-reveal]:not(.is-in) {
        opacity: 0;
        transform: translateY(32px);
    }

    .site-header {
        transition: transform 0.5s var(--ease-out), background-color 0.3s;
    }

    .split-sticky {
        transition: top 0.5s var(--ease-out);
    }

    /* The mobile menu wipes down from the header and its links follow one after another */
    @media (max-width: 860px) {
        .nav-menu {
            opacity: 1;
            clip-path: inset(0 0 100% 0);
            transition: clip-path 0.6s var(--ease-in-out), visibility 0s linear 0.6s;
        }

        .nav-open .nav-menu {
            clip-path: inset(0);
            transition: clip-path 0.6s var(--ease-in-out), visibility 0s;
        }

        .nav-menu li,
        .nav-cta {
            opacity: 0;
            transform: translateY(20px);
            transition: opacity 0.25s, transform 0.25s;
        }

        .nav-open .nav-menu li,
        .nav-open .nav-cta {
            opacity: 1;
            transform: none;
            transition: opacity 0.6s var(--ease-out), transform 0.8s var(--ease-out);
            transition-delay: calc(0.15s + var(--i) * 0.05s);
        }
    }

    /* Screenshots fade in once loaded, over a stage that breathes between two greys while it waits */
    .case-shot img,
    .case-shot-pair .case-app {
        transition: opacity 0.7s var(--ease-out), transform 0.9s var(--ease-out), scale 0.9s var(--ease-out), border-color 0.15s;
    }

    .img-fade .case-shot img:not(.is-loaded) {
        opacity: 0;
    }

    .img-fade .case-shot:not(.is-loaded) {
        animation: stage-pulse 1.2s ease-in-out infinite alternate;
    }

    /* On hover, only for things that are links: the shot leans in and the arrow points the way */
    @media (hover: hover) {
        .btn-roll > span {
            transition: transform 0.5s var(--ease-out);
        }

        .btn:hover .btn-roll > span {
            transform: translateY(-100%);
        }

        a.case:hover .case-shot:not(.case-shot-pair) img {
            transform: scale(1.025);
            transform-origin: 50% 100%;
        }

        a.case:hover .case-landing {
            transform: translate(-1.5%, -2%);
        }

        a.case:hover .case-app {
            transform: translateY(-3%);
        }

        .case-name .icon,
        .product-name .icon {
            transition: transform 0.4s var(--ease-out), color 0.15s;
        }

        a.case:hover .case-name .icon,
        a.card:hover .product-name .icon {
            transform: translate(2px, -2px);
        }
    }

    /* Scroll-linked, where the browser supports it: the app and its landing page settle into place at different
       speeds as a case study scrolls up, and the home hero recedes as it leaves. .case-shot clips its content, so it
       names its own view timeline rather than using view(). */
    @supports (animation-timeline: view()) {
        .case-shot-pair {
            view-timeline: --shot block;
        }

        .case-shot-pair .case-app {
            animation: settle-app linear both;
            animation-timeline: --shot;
            animation-range: entry 0% cover 50%;
        }

        .case-shot-pair .case-landing {
            animation: settle-landing linear both;
            animation-timeline: --shot;
            animation-range: entry 0% cover 50%;
        }

        .hero-split {
            animation: recede linear both;
            animation-timeline: view();
            animation-range: exit 0% exit 100%;
        }
    }

    /* Switching theme: the new one spreads out in a circle from the toggle (main.js animates the clip). The header joins
       the page for it, so the circle sweeps over both. */
    .theme-switching::view-transition-old(root),
    .theme-switching::view-transition-new(root) {
        animation: none;
        mix-blend-mode: normal;
    }

    .theme-switching .site-header {
        view-transition-name: none;
    }

    /* The Work filter: cards slide to their new places, and ones joining or leaving fade (main.js) */
    ::view-transition-group(*.case) {
        animation-duration: 0.55s;
        animation-timing-function: var(--ease-out);
    }
}

@keyframes loader-lift {
    to {
        transform: translateY(-100%);
        visibility: hidden;
    }
}

@keyframes mark-turn {
    from { rotate: -90deg; }
}

@keyframes mark-leave {
    to {
        opacity: 0;
        scale: 0.85;
        translate: 0 -24px;
    }
}

@keyframes piece-in {
    from {
        opacity: 0;
        scale: 0.2;
    }
}

@keyframes drop-in {
    from { transform: translateY(-100%); }
}

@keyframes rise {
    from {
        opacity: 0;
        transform: translateY(24px);
    }
}

@keyframes rise-small {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
}

@keyframes word-up {
    from { transform: translateY(110%); }
}

@keyframes stage-pulse {
    to { background-color: var(--tint-2); }
}

@keyframes settle-app {
    from { translate: 0 14%; }
}

@keyframes settle-landing {
    from { translate: 0 4%; }
}

@keyframes recede {
    to {
        opacity: 0.2;
        translate: 0 12%;
    }
}

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

    .nav-pill,
    .nav-brand .logo-svg > path:first-child,
    .tile-plus,
    .text-link .icon,
    .theme-toggle > span {
        transition: none;
    }
}

@media print {
    .loader,
    .nav-progress {
        display: none !important;
    }

    [data-reveal] {
        opacity: 1 !important;
        transform: none !important;
    }
}
