/*
 * dotdotZero, landing page
 *
 * The token set is inherited from the studio's seven-segment renderer, which is
 * where this palette was actually derived: #16181c ground, #0e1013 inside the
 * display, a single interface blue and a single LED red. The split is a rule,
 * not a preference, red belongs to the thing being rendered, blue belongs to
 * the thing you operate. Nothing else gets to be a colour.
 *
 * Tokens, the display geometry and the above-the-fold layout are inlined in
 * index.html so the first paint needs no stylesheet. This file is everything
 * below the hero.
 */

/* ------------------------------------------------------------------ reset -- */

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

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

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

button,
input,
select,
textarea {
    font: inherit;
    color: inherit;
}

a {
    color: inherit;
}

code {
    font-family: var(--mono);
    font-size: 0.88em;
    padding: 0.1em 0.35em;
    border-radius: var(--r-sm);
    background: color-mix(in srgb, var(--ink) 8%, transparent);
    color: var(--ink);
}

::selection {
    background: rgb(var(--lit-rgb) / 0.28);
    color: #fff;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: var(--r-sm);
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: 100;
    padding: 10px 16px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    text-decoration: none;
    font-size: 0.8125rem;
    transition: transform 180ms var(--ease-out);
}

.skip:focus {
    transform: translateY(72px);
}

/* ------------------------------------------------------------ typography -- */

h2 {
    font-size: clamp(1.75rem, 4vw, 2.875rem);
    line-height: 1.06;
    letter-spacing: -0.028em;
    font-weight: 560;
    max-width: 20ch;
    text-wrap: balance;
}

h3 {
    font-size: clamp(1.0625rem, 1.8vw, 1.3125rem);
    line-height: 1.3;
    letter-spacing: -0.015em;
    font-weight: 560;
}

h4 {
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.kicker {
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    /* --lit-ink, not --lit: at 11px on a panel surface the LED red sits at
       4.36:1, just under AA. Same rule for every other run of red text. */
    color: var(--lit-ink);
    margin-bottom: 18px;
    font-variant-numeric: tabular-nums;
}

.band__lede {
    margin-top: 20px;
    max-width: 66ch;
    color: var(--ink-dim);
    font-size: clamp(0.9375rem, 1.4vw, 1.0625rem);
    line-height: 1.68;
    text-wrap: pretty;
}

.band__lede b,
.band__lede strong {
    color: var(--ink);
    font-weight: 500;
}

/* -------------------------------------------------------------- structure -- */

.band {
    padding-block: clamp(64px, 9vw, 128px);
    border-top: 1px solid var(--line-soft);
}

.band--panel {
    background: linear-gradient(180deg, var(--panel) 0%, color-mix(in srgb, var(--panel) 55%, var(--bg)) 100%);
}

.band__head {
    margin-bottom: clamp(40px, 5vw, 64px);
}

/* -------------------------------------------------------------------- btn -- */

.btn {
    --btn-bg: transparent;
    --btn-fg: var(--ink);
    --btn-line: var(--line);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 20px;
    border: 1px solid var(--btn-line);
    border-radius: var(--r-lg);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-size: 0.9063rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: transform 140ms var(--ease-out), background-color 180ms ease, border-color 180ms ease,
        box-shadow 180ms ease;
}

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

.btn--sm {
    padding: 8px 15px;
    font-size: 0.8438rem;
}

.btn--block {
    width: 100%;
}

/* The surface is --cta, not --lit: the LED red holds white text at 3.7:1, which
   fails AA at button sizes. The glow stays LED-red, a light bleeding onto the
   control, and the deeper surface is what makes the label legible. */
.btn--primary {
    --btn-bg: var(--cta);
    --btn-fg: #fff;
    --btn-line: transparent;
    box-shadow: 0 0 0 0 rgb(var(--lit-rgb) / 0.4);
}

.btn--ghost {
    --btn-bg: color-mix(in srgb, var(--ink) 4%, transparent);
}

@media (hover: hover) and (pointer: fine) {
    /* Hover deepens rather than lightens: contrast improves under the pointer
       instead of dipping below the bar exactly when someone is about to act. */
    .btn--primary:hover {
        --btn-bg: color-mix(in srgb, var(--cta) 86%, #000);
        box-shadow: 0 0 24px -4px rgb(var(--lit-rgb) / 0.45);
    }

    .btn--ghost:hover {
        --btn-line: var(--ink-faint);
        --btn-bg: color-mix(in srgb, var(--ink) 8%, transparent);
    }
}

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

/* The hero's one action. The email renders on the display as it is typed,
   which is the pitch, and Enter sends the lead and walks the visitor into the
   contact form. Glass input, pill geometry: the island's radius. */
.hero__mail {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 36px;
    max-width: 480px;
}

.hero__mail input {
    flex: 1 1 220px;
    min-width: 0;
    padding: 12px 20px;
    background: color-mix(in srgb, var(--display-bg) 62%, transparent);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);
    border-radius: 999px;
    color: var(--ink);
    /* 1rem, never less: iOS Safari zooms the whole page into any focused
       input under 16px, and no field is worth that lurch. */
    font-size: 1rem;
    transition: border-color 160ms ease;
}

.hero__mail input:focus {
    outline: none;
    border-color: var(--accent);
}

.hero__mail input::placeholder {
    color: var(--ink-dim);
}

.hero__mail .btn {
    border-radius: 999px;
}

.hero__mail-note {
    flex-basis: 100%;
    font-size: 0.8125rem;
    color: var(--ink-dim);
    text-shadow: 0 1px 12px rgb(14 16 19 / 0.8);
}

/* --------------------------------------------------------------------- why -- */

.band--why {
    border-top: 0;
    padding-block: clamp(44px, 6vw, 72px);
}

.why {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: clamp(20px, 4vw, 56px);
    align-items: start;
}

.why__q {
    font-size: clamp(1.125rem, 2vw, 1.5rem);
    line-height: 1.25;
    letter-spacing: -0.02em;
    font-weight: 560;
    text-wrap: balance;
}

.why__a {
    font-size: clamp(0.9375rem, 1.4vw, 1.0625rem);
    line-height: 1.68;
    color: var(--ink-dim);
    text-wrap: pretty;
}

.why__a span {
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

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

/* ------------------------------------------------------------------ strip -- */

.strip {
    border-top: 1px solid var(--line-soft);
    padding-block: clamp(40px, 5vw, 64px);
}

.strip__label {
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: clamp(20px, 3vw, 28px);
}

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

.fig {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-left: 18px;
    border-left: 1px solid var(--line);
}

.fig__num {
    font-size: clamp(2.125rem, 4.6vw, 3.25rem);
    line-height: 1;
    letter-spacing: -0.04em;
    font-weight: 500;
    /* Proportional figures at rest: tabular gives every digit the width of a
       zero, which leaves a number like 260 looking gappy at this size. Tabular
       is switched on only while the value is counting, where the alternative is
       the whole tile juddering as the digits change width. */
    font-variant-numeric: proportional-nums;
}

.fig__num[data-counting] {
    font-variant-numeric: tabular-nums;
}

.fig--lit {
    border-left-color: rgb(var(--lit-rgb) / 0.6);
}

.fig--lit .fig__num {
    color: var(--lit);
}

.fig__label {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--ink-faint);
}

/* Three tiles hold their row down to small tablets; below that they stack,
   because a 2+1 wrap leaves one figure orphaned under the others. */
@media (max-width: 640px) {
    .strip__grid {
        grid-template-columns: 1fr;
        gap: 24px;
    }
}

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

.offer {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    overflow: hidden;
}

/* Hairline gaps rather than six separate cards: the offer is one thing with six
   parts, and gaps in the surface colour say that without drawing six boxes. */
.offer__item {
    padding: clamp(22px, 2.4vw, 30px);
    background: var(--panel);
    display: grid;
    gap: 10px;
    align-content: start;
}

.offer__n {
    font-family: var(--mono);
    font-size: 0.6875rem;
    letter-spacing: 0.1em;
    color: var(--lit-ink);
    font-variant-numeric: tabular-nums;
}

.offer__item p:not(.offer__n) {
    font-size: 0.875rem;
    line-height: 1.65;
    color: var(--ink-dim);
}

@media (max-width: 980px) {
    .offer {
        grid-template-columns: repeat(2, 1fr);
    }
}

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

/* ---------------------------------------------------------------- process -- */

.steps {
    display: grid;
    gap: 1px;
    background: var(--line);
    border-block: 1px solid var(--line);
}

.step {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr);
    gap: clamp(16px, 3vw, 40px);
    padding: clamp(20px, 2.6vw, 30px) 0;
    background: var(--bg);
    transition: background-color 200ms ease;
}

@media (hover: hover) and (pointer: fine) {
    .step:hover {
        background: var(--panel);
    }
}

.step__n {
    font-family: var(--mono);
    font-size: 1.25rem;
    color: var(--lit-ink);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

.step h3 {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px 14px;
    margin-bottom: 8px;
}

.step__tag {
    font-family: var(--mono);
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-faint);
    font-weight: 400;
}

.step p {
    font-size: 0.875rem;
    line-height: 1.65;
    color: var(--ink-dim);
    max-width: 70ch;
}

@media (max-width: 620px) {
    .step {
        grid-template-columns: 1fr;
        gap: 10px;
    }
}

/* ------------------------------------------------------------------ start -- */

.band--start {
    background: radial-gradient(120% 100% at 12% 0%, color-mix(in srgb, var(--lit) 7%, transparent) 0%, transparent 62%);
}

/* The contact form: name and email are the requirements, the rest is help.
   Fields sit on panel surfaces rather than glass, because this section is on
   solid ground and legibility beats atmosphere in a form. */
.leadForm {
    margin-top: 32px;
    max-width: 560px;
}

.leadForm__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.leadForm label {
    display: grid;
    gap: 6px;
}

.leadForm label span {
    font-size: 0.6875rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-dim);
}

.leadForm label i {
    font-style: normal;
    text-transform: none;
    letter-spacing: 0;
    color: var(--ink-faint);
}

.leadForm input,
.leadForm textarea {
    padding: 10px 14px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    color: var(--ink);
    /* 1rem, never less: iOS Safari zooms into any focused input under 16px. */
    font-size: 1rem;
    transition: border-color 180ms ease;
}

.leadForm textarea {
    resize: vertical;
    min-height: 74px;
}

.leadForm ::placeholder {
    color: var(--ink-faint);
}

.leadForm input:focus,
.leadForm textarea:focus {
    outline: none;
    border-color: var(--accent);
}

.leadForm input[aria-invalid='true'],
.leadForm textarea[aria-invalid='true'] {
    border-color: var(--warn);
}

.leadForm__wide {
    grid-column: 1 / -1;
}

.leadForm .btn {
    margin-top: 16px;
}

.leadForm__note {
    margin-top: 12px;
    font-size: 0.7813rem;
    line-height: 1.6;
    color: var(--ink-faint);
    transition: color 200ms ease;
}

.leadForm__note[data-state='error'] {
    color: var(--warn);
}

.leadForm__note[data-state='sent'] {
    color: var(--ok);
}

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

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

.footer {
    border-top: 1px solid var(--line);
    background: var(--display-bg);
    padding-block: clamp(48px, 6vw, 72px) 32px;
}

.footer__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    gap: clamp(28px, 4vw, 56px);
    padding-bottom: 40px;
}

.footer__brand {
    display: grid;
    gap: 16px;
    align-content: start;
}

.footer__brand .display {
    width: 68px;
}

.footer__brand p {
    font-size: 0.8438rem;
    line-height: 1.65;
    color: var(--ink-faint);
    max-width: 44ch;
}

.footer__nav {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
}

.footer__nav div {
    display: grid;
    gap: 9px;
    align-content: start;
}

.footer__nav h4 {
    margin-bottom: 3px;
}

.footer__nav a {
    font-size: 0.8438rem;
    color: var(--ink-dim);
    text-decoration: none;
    transition: color 160ms ease;
    justify-self: start;
}

@media (hover: hover) and (pointer: fine) {
    .footer__nav a:hover {
        color: var(--lit);
    }
}

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

    .footer__nav {
        grid-template-columns: repeat(2, 1fr);
        gap: 28px 20px;
    }
}

/* ----------------------------------------------------------------- reveal -- */

/*
 * Sections lift in once, on first sight. This is a decorative animation seen
 * a handful of times per visit, which is the only place decoration is worth
 * spending on, and it is transform/opacity only, so it never touches layout.
 */
.reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
}

.reveal.is-revealed {
    opacity: 1;
    transform: none;
}

/*
 * If a revealed element carries a transition of its own, the reveal's 620ms wins
 * at equal specificity and the element answers hovers late. Hand the transition
 * back with a `.thing.is-revealed` override — the case cards did, before they
 * were cut. No revealed element currently needs it.
 */

/*
 * Three independent preferences, not one.
 *
 * Reduced motion is the one everybody remembers. A reader who has asked for
 * less transparency is telling the OS that blurred, see-through chrome is hard
 * to read, so the island stops being a material and becomes a surface. A
 * reader who has asked for more contrast wants edges defined rather than
 * implied, which is where this palette's one-step-off-surface rules give way to
 * real ones.
 */
@media (prefers-reduced-transparency: reduce) {
    .island {
        background: var(--display-bg);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    .hero__mail input {
        background: var(--display-bg);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
}

@media (prefers-contrast: more) {
    :root {
        --ink-dim: #c3cad3;
        --ink-faint: #a2abb6;
        --line: #4a525d;
        --line-soft: #3d444e;
        --unlit: #3a3f47;
    }

    .island {
        background: var(--display-bg);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        border-color: var(--ink-faint);
    }

    .offer__item,
    .leadForm input,
    .leadForm textarea {
        border-color: var(--line);
    }

    .btn--ghost {
        --btn-line: var(--ink-faint);
    }

    .footer__nav a {
        text-decoration: underline;
        text-underline-offset: 3px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .reveal {
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
    }



    /* Moves rather than fades, with a colour change carrying the same meaning
       underneath. The movement goes; the meaning stays. */
    .skip {
        transition-duration: 1ms;
    }

    .reveal {
        opacity: 1;
        transform: none;
    }

    /* Reduced motion is not "no feedback". The press still has to answer, so the
       3% scale is traded for a change of surface rather than dropped. */
    .btn:active {
        transform: none;
        filter: brightness(1.35);
    }
}

.footer__legal {
    padding-top: 24px;
    border-top: 1px solid var(--line-soft);
    font-size: 0.75rem;
    color: var(--ink-faint);
}
