/* The marketing pages.

   Everything here sits on top of app.css, which is loaded first and brings the
   colour tokens, the type scale, both palettes and the button styles. So this
   file only has to lay a page out, and it cannot drift away from the app's
   colours: change a token there and this follows.

   Written plainly because it is read by a browser with nothing else running. No
   framework, no build step, no JavaScript at all on the home page. */

body {
    /* app.css sets html and body to overflow:hidden, which is right for an app
       that scrolls its own panes and wrong for a page that is one long column. */
    overflow: auto;
    min-height: 100%;

    /* A second glow, over the top of the one app.css already lays down.

       That one is anchored at 50% 0% and its comment says what it is for - so
       the dark canvas isn't dead flat - and on a screen this wide it is doing
       the job in the wrong place, dead centre, under nothing in particular.
       This one sits up on the right, behind the screenshots in the hero, so
       they sit on a wash of colour rather than on a flat field. It was there
       for the photograph before them and does the same job for these.

       accent-soft rather than a new colour, so it follows the palette and holds
       in both themes. Not fixed: it belongs to the top of the document, not to
       the top of the viewport, and should scroll away with the hero it belongs
       to. */
    background-image:
        radial-gradient(70% 42% at 76% 0%, var(--accent-soft) 0%, transparent 68%);
    background-repeat: no-repeat;
}

/* ── Header ─────────────────────────────────────────────────────────── */

.site-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px 28px;
    max-width: 1280px;
    margin: 0 auto;
    padding: 22px 28px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 19px;
    font-weight: 650;
    letter-spacing: -0.01em;
    color: var(--text);
    text-decoration: none;
}

.brand img {
    border-radius: 10px;
}

.brand-accent {
    color: var(--accent);
}

.site-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;

    /* Pushes the nav off the brand and the actions to the far end, in one rule
       rather than with a spacer element. */
    margin-inline: auto 0;
}

.site-nav a {
    color: var(--text-dim);
    text-decoration: none;
    font-size: 15px;
}

.site-nav a:hover {
    color: var(--text);
}

.site-actions {
    display: flex;
    gap: 8px;
}

/* ── Hero ───────────────────────────────────────────────────────────── */

main {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 28px 80px;
}


/* Text left, the product right, above the breakpoint. Below it the text runs
   full width and the phone screenshot sits under it on its own; the desktop
   screenshot is never fetched there, see .hero-shot-desktop.

   The text keeps its measure. 36rem on the lead has always been the reason
   the headline reads the way it does, and a second column is what the space
   past it was for. */
.hero {
    position: relative;
    padding: 56px 0 64px;
    display: grid;
    gap: 40px;
    align-items: center;
}

@media (min-width: 62rem) {
    .hero {
        grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
        gap: 48px;
        padding: 64px 0 72px;
    }
}

.hero-text {
    position: relative;
    z-index: 1;
    max-width: 44rem;
}

/* The desktop screenshot, as a background so a phone never fetches it: an img
   with display:none still downloads, a background inside a min-width query
   does not. The same technique the photograph used, for the same file-size
   reason, and the file is the screenshot tool's own 1800 by 1175 output.

   role="img" and an aria-label in the markup, because unlike the photograph
   this is content: it is the product. */
.hero-shot {
    position: relative;
    display: flex;
    justify-content: center;
}

.hero-shot-desktop {
    display: none;
}

/* The phone screenshot is the whole picture below the breakpoint and a corner
   of it above. Real img, real alt, since a phone is exactly the screen that
   should see it. */
.hero-shot-phone {
    display: block;
    width: min(100%, 250px);
    height: auto;
    border: 1px solid var(--border-card);
    border-radius: 22px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.28);
}

@media (min-width: 62rem) {
    .hero-shot {
        display: block;
        /* Room below the frame for the phone to hang past its bottom edge. */
        padding-bottom: 36px;
    }

    .hero-shot-desktop {
        display: block;
        width: 100%;
        aspect-ratio: 1800 / 1175;
        background-image: url("/marketing/shots/desktop-map-full.jpg");
        background-size: cover;
        background-position: top left;
        border: 1px solid var(--border-card);
        border-radius: var(--radius-card);
        box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
    }

    .hero-shot-phone {
        position: absolute;
        right: -8px;
        bottom: 0;
        width: 27%;
        border-radius: 18px;
    }
}

.hero h1 {
    /* clamp so it reads on a phone without a media query. The lower bound is
       the smallest that still feels like a headline; the upper is where the
       line length starts to get uncomfortable rather than impressive. */
    font-size: clamp(30px, 5.2vw, 46px);
    line-height: 1.15;
    letter-spacing: -0.02em;
    font-weight: 650;
    margin: 0 0 26px;
}

.hero-accent {
    color: var(--accent);
}

/* The three concrete things, between the headline and the lead. Set apart
   from the lead by weight rather than size, so it reads as the headline's
   examples and not as a second paragraph. */
.hero-beats {
    margin: 0 0 18px;
    font-size: 19px;
    line-height: 1.5;
    font-weight: 600;
    color: var(--text);
    max-width: 36rem;
}

.hero-lead {
    font-size: 18px;
    line-height: 1.6;
    color: var(--text-dim);

    margin: 0 0 32px;
    max-width: 36rem;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.btn-lg {
    padding: 12px 22px;
    font-size: 16px;
}

.hero-ticks {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 22px;
    margin: 18px 0 0;
    padding: 0;
    list-style: none;
}

.hero-ticks li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    color: var(--text-dim);
}

/* Green, like the ticks band further down and for the same reason: a tick in
   the accent blue reads as a link on a page where every other blue thing is
   one. */
.hero-ticks i {
    font-size: 17px;
    color: var(--green);
}

/* Where it runs, in one line. Icons and words at the note's weight, nothing to
   press but the words "Web app" further up: this states a fact and offers
   nothing, which is what the band it replaced argued for.

   Two groups, each an item of the outer row, so a wrap lands between the two
   sentences and never between an icon and its words. The first draft had the
   icons loose in the row and the second sentence dropped a line without them. */
.hero-platforms {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 18px;
    margin: 16px 0 0;
    font-size: 14px;
    color: var(--text-faint);
}

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

/* The one that is a link reads as one: accent on the words, and the icon
   follows on hover so the pair moves together. */
a.hero-platform {
    color: var(--accent);
    text-decoration: none;
}

a.hero-platform strong,
a.hero-platform i {
    color: var(--accent);
}

a.hero-platform:hover span,
a.hero-platform:focus-visible span {
    text-decoration: underline;
}

.hero-platforms i {
    font-size: 17px;
    color: var(--text-dim);
}

.hero-platforms strong {
    font-weight: 600;
    color: var(--text-dim);
}

.hero-note {
    margin: 14px 0 0;
    font-size: 14.5px;
    color: var(--text-faint);
}

.hero-note a {
    color: var(--accent);
    font-weight: 600;
}

/* ── How it works ───────────────────────────────────────────────────── */

/* Three steps, each a phone screenshot with a line under it. Phone captures
   rather than desktop ones because three portrait frames sit side by side
   where three landscape ones would each be a postage stamp, and because these
   are the screens somebody meets first: the map on a phone in a paddock.

   Between the hero and the ticks. The hero's second button lands here, and
   the ticks are the long list; this is the short story in front of it. */
.how {
    padding: 8px 0 40px;
}

.how > h2 {
    font-size: clamp(20px, 3vw, 26px);
    font-weight: 650;
    letter-spacing: -0.02em;
    margin: 0 0 22px;
}

.how-steps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: 28px;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: step;
}

.how-steps li {
    counter-increment: step;
}

.how-steps img {
    display: block;
    width: min(100%, 230px);
    height: auto;
    margin: 0 0 16px;
    border: 1px solid var(--border-card);
    border-radius: 18px;
}

/* The number, from the counter rather than typed, so reordering the steps
   cannot leave 1, 3, 2 on the page. */
.how-steps strong {
    display: block;
    font-size: 17px;
    font-weight: 650;
    margin: 0 0 6px;
}

.how-steps strong::before {
    content: counter(step) ". ";
    color: var(--accent);
}

.how-steps p {
    margin: 0;
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-dim);
}

.how-more {
    margin: 22px 0 0;
    font-size: 15px;
}

.how-more a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

/* ── Screenshots ────────────────────────────────────────────────────── */

/* Under the features rather than above them. It sat between the hero and the
   cards first, on the reasoning that somebody skimming should see the product
   before they see a wall of text - but the cards are three lines each and are
   the argument for why any of this matters. A screenshot before them answers
   "what does it look like" to somebody who has not yet been told what it is.
   Read what it does, then see it doing it. */
/* 34px at the top rather than 8px. The carousel used to butt straight up
   against the paragraph above it, which is what made it read as part of the
   rental section instead of a new one; the heading below fixes most of that and
   the air finishes it. */
.shots {
    padding: 34px 0 40px;
}

/* Matches .pricing > h2 rather than inventing a third section-heading size.
   Direct child, because .shot figures could gain headings of their own later
   and these rules are about the section's own title. */
.shots > h2 {
    font-size: clamp(20px, 3vw, 26px);
    font-weight: 650;
    letter-spacing: -0.02em;
    margin: 0 0 6px;
}

.shots-lead {
    margin: 0 0 18px;
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-dim);
}


.shots:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 6px;
    border-radius: var(--radius-card);
}

/* The frame holds the height so the page does not jump as slides change. Each
   screenshot is the same shape as the last, so one aspect-ratio does it, and
   the images are stacked rather than laid in a row: no transform, no track
   width to keep in step with the slide count. */
.shot-frame {
    position: relative;
    aspect-ratio: 2880 / 1880;
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
    background: var(--bg-card);
    overflow: hidden;
}

.shot {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;

    /* Kept out of the tab order and off the pointer while hidden, so a stack of
       six does not become six things to tab through. */
    visibility: hidden;
    transition: opacity 0.5s ease, visibility 0.5s;
}

.shot.is-on {
    opacity: 1;
    visibility: visible;
}

.shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top left;
}

/* Over the foot of the shot rather than under it, because a caption below the
   frame would push the whole page down by a line the moment the text wrapped. */
.shot figcaption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 64px 22px 16px;
    font-size: 15px;
    font-weight: 500;
    color: #fff;

    /* Nearly opaque at the foot and tall enough to fade out well clear of the
       text. The first attempt was a thin 82% wash, which let the app's own rows
       show straight through the caption and read as two things printed on top
       of each other rather than a label on a picture. */
    background: linear-gradient(to top,
        rgba(5, 8, 13, 0.96) 0%,
        rgba(5, 8, 13, 0.88) 38%,
        rgba(5, 8, 13, 0) 100%);
}

/* A single screenshot on a text page, rather than one slide of a carousel.
   Used on /sharing for the grants sheet.

   Nothing is cropped here, which is the difference from .shot: the carousel
   crops to a fixed frame so the slides line up, and this one is the whole sheet
   or it is not worth showing. The caption sits under it for the same reason -
   there is no frame for it to sit inside. */
.shot-still {
    margin: 22px 0 26px;
}

.shot-still img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--border-card);
    border-radius: 12px;
}

.shot-still figcaption {
    margin-top: 8px;
    font-size: 14px;
    color: var(--text-faint);
}

.shot-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;

    /* Dark disc and white glyph in both themes: these sit on a screenshot of a
       dark app, not on the page, so they follow the picture rather than the
       palette. */
    background: rgba(13, 17, 23, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.24);
    color: #fff;
    font-size: 20px;
    cursor: pointer;
    opacity: 0.9;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
    transition: opacity 0.15s, background 0.15s;
}

.shot-arrow:hover {
    opacity: 1;
    background: rgba(13, 17, 23, 0.92);
    border-color: rgba(255, 255, 255, 0.4);
}

.shot-arrow:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

.shot-prev { left: 12px; }
.shot-next { right: 12px; }

.shot-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 14px 0 0;
}

.shot-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--border-chip);
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
}

.shot-dot.is-on {
    background: var(--accent);
    transform: scale(1.35);
}

.shot-dot:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* The line about whose map that is. Centred and quiet: it is an explanation,
   not a claim, and it should read as candour rather than as an apology. It used
   to explain why there was no map at all; now it explains why the one on screen
   is a park. */
.shot-note {
    max-width: 44rem;
    margin: 16px auto 0;
    text-align: center;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--text-faint);
}

/* Directly under the explanation, because the explanation ends by saying you
   get the map when you start and the button is then the next thing your eye
   lands on. Centred with the note rather than pulled left, so the pair reads as
   one thought. */
.shot-cta {
    display: block;
    width: fit-content;
    margin: 16px auto 0;
}

@media (max-width: 720px) {
    /* The phone captures, which the picture element has already swapped in. */
    .shot-frame {
        aspect-ratio: 780 / 1688;
        max-width: 340px;
        margin: 0 auto;
    }

    .shot-arrow {
        width: 34px;
        height: 34px;
        font-size: 17px;
    }

    .shot-prev { left: 6px; }
    .shot-next { right: 6px; }
}

/* ── Features ───────────────────────────────────────────────────────── */

/* auto-fit rather than a fixed column count, so the six cards reflow from three
   across to two to one without a single media query, and the last row never
   leaves a lonely stretched card. */
.features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
    gap: 20px;
    padding-bottom: 32px;
}

.feature {
    padding: 26px 24px;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
}

.feature i {
    display: block;
    font-size: 24px;
    color: var(--accent);
    margin-bottom: 12px;
}

/* A splash, not a rainbow.
 *
 * Every icon on this page was the same blue, which made nine cards read as one
 * undifferentiated wall. But colouring all nine differently would be decoration:
 * the colour would mean "this is a different card", which the border already
 * says.
 *
 * So only the four where the app itself already uses that colour for that idea,
 * and the values are lifted from TemplateUi rather than picked to look nice
 * beside each other. A visitor who signs up meets the same red on a vehicle and
 * the same amber on something falling due, so the page is a preview of the
 * product's own language rather than a paint job over it.
 *
 * The rest stay accent blue on purpose. Colour carries meaning here or it does
 * not appear. */
.feature.tint-vehicle i { color: #d64545; }   /* TemplateUi "vehicle" */
.feature.tint-due i     { color: var(--amber); }  /* what "due soon" is everywhere */
.feature.tint-money i   { color: var(--green); }  /* what money in is on the ledger */
.feature.tint-people i  { color: #a06cd5; }   /* TemplateUi "comms", the shared-line colour */

.feature h2 {
    font-size: 18.5px;
    font-weight: 600;
    margin: 0 0 8px;
    letter-spacing: -0.01em;
}

.feature p {
    margin: 0;
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--text-dim);
}

/* ── Cards that go somewhere ────────────────────────────────────────── */

/* An <a> wearing .feature, so a card with a page behind it is one target rather
   than a paragraph with a link in it. The rules below only undo what a browser
   does to links; everything else it inherits, which is the point - a linked card
   and a plain one must look identical until you notice the chevron. */
a.feature {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s ease, transform 0.15s ease;
}

a.feature:hover {
    border-color: var(--accent-line);
}

/* Keyboard focus has to be visible on a card whose whole surface is the target,
   and the hover colour alone is not it: somebody tabbing gets no hover. */
a.feature:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

.feature-more {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 14px;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--accent);
}

/* Two of them on the lead card, which is why that one is an <article> and not a
   card-shaped link: it points at two pages and an anchor cannot hold an anchor.
   Wraps rather than truncates on a narrow screen, where they stack. */
.feature-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    margin: 16px 0 0;
}

.feature-links a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
}

/* Same reason as .feature-more i below: .feature i is a 24px block with a
   margin, meant for the card's own icon at the top, and inherited here it would
   put each chevron on its own line at twice the size of the words. */
.feature-links a i {
    display: inline-block;
    font-size: 16px;
    color: inherit;
    margin: 0;
    transition: transform 0.15s ease;
}

.feature-links a:hover i {
    transform: translateX(2px);
}

/* .feature i is a block with a 24px face and a margin, which is right for the
   card's own icon at the top and would put the chevron on its own line at twice
   the size of the words beside it. */
.feature-more i {
    display: inline-block;
    font-size: 16px;
    color: inherit;
    margin: 0;
    transition: transform 0.15s ease;
}

a.feature:hover .feature-more i {
    transform: translateX(3px);
}

/* Nobody asked for the animation, and a card that slides under a cursor is
   worse for anybody who did not. */
@media (prefers-reduced-motion: reduce) {
    a.feature,
    .feature-more i {
        transition: none;
    }

    a.feature:hover .feature-more i {
        transform: none;
    }
}

/* ── The lead feature ───────────────────────────────────────────────── */

/* The map card spans the row it sits in, because it is the difference rather
   than one of six equal things. On a narrow screen every card is full width
   anyway, so this costs nothing there. */
@media (min-width: 900px) {
    .feature.is-lead {
        grid-column: 1 / -1;

        /* Two statements, side by side, using the space instead of leaving it.

           This card spans the whole grid and its prose was capped at 46rem, so
           the text sat in the left two thirds with the right third empty and the
           two paragraphs touching each other. The cap was right and is why: a
           line running the full width of a 1280px card is a measure nobody can
           read comfortably.

           So the answer is not a wider paragraph, it is a second column. The two
           paragraphs are already two different statements - what the thing IS,
           against what you DO with it - which is what makes them sit beside each
           other rather than read as one broken in half.

           Grid rather than CSS columns, because columns would flow the links row
           at the foot into them as well. */
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 40px;
        align-items: start;

        /* No row gap, and that is deliberate rather than an omission. The icon,
           the heading and the links row already carry their own margins, 12px,
           8px and 16px, and those are what give every other card on this page
           its rhythm. A row gap here would add to each of them and leave the one
           card that is meant to look like the others looking airier than all of
           them. The two paragraphs share a row, so they need no vertical gap at
           this width anyway. */
        row-gap: 0;
    }

    /* Everything that is not one of the two paragraphs runs the full width. */
    .feature.is-lead > i,
    .feature.is-lead > h2,
    .feature.is-lead > .feature-links {
        grid-column: 1 / -1;
    }

    .feature.is-lead h2 {
        font-size: 21px;
    }

    /* The cap comes off, because the column is now what sets the measure and
       46rem is wider than a column ever gets. Leaving both in place would let
       the narrower of the two win at some widths and not others, which is a
       layout that changes its mind halfway across a monitor. */
    .feature.is-lead p {
        max-width: none;
    }
}

/* The two paragraphs touch on a phone, where they are stacked and there is no
   row gap doing it for them. .feature p is margin: 0 for the six single
   paragraph cards, which is right for them and wrong for the only card that has
   two. */
.feature.is-lead p + p {
    margin-top: 14px;
}

@media (min-width: 900px) {
    .feature.is-lead p + p {
        margin-top: 0;
    }
}

/* ── Pricing ────────────────────────────────────────────────────────── */

.pricing {
    padding-top: 20px;
}

.pricing > h2 {
    font-size: clamp(20px, 3vw, 26px);
    font-weight: 650;
    letter-spacing: -0.02em;
    margin: 0 0 18px;
}

.tiers {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
    gap: 20px;
}

.tier {
    padding: 26px 24px;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
}

/* The paid one is marked, not shouted. A border in the accent says "this is the
   one most people want" without the page leaning on somebody. */
.tier.is-best {
    border-color: var(--accent-line);
    background: var(--accent-soft);
}

.tier h3 {
    margin: 0 0 8px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-dim);
}

.tier-price {
    margin: 0 0 14px !important;
    font-size: 32px;
    font-weight: 650;
    letter-spacing: -0.02em;
    color: var(--text) !important;
    line-height: 1.1;
}

.tier-price span {
    display: block;
    margin-top: 4px;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--text-dim);
}

.tier p {
    margin: 0;
    font-size: 15px;
    line-height: 1.65;
    color: var(--text-dim);
}

/* The numbers, under the sentence and quieter than it. Somebody skimming for
   the price should not trip over them, and somebody checking whether the thing
   fits their place should find them without opening a comparison table. */
.tier-limits {
    margin: 12px 0 0 !important;
    padding-top: 12px;
    border-top: 1px solid var(--border-card);
    font-size: 13.5px !important;
    color: var(--text-faint) !important;
}

.pricing-note {
    margin: 18px 0 0;
    font-size: 14px;
    color: var(--text-faint);
}

/* ── Contact ────────────────────────────────────────────────────────── */

/* Matched to .legal below it, so the title and the first card share an edge.
   Left behind at 40rem when that widened, the h1 would sit inset from the
   content it introduces. */
.page-head {
    padding: 56px 0 36px;
    max-width: 60rem;
}

/* The trail above the heading, on the pages that sit under /use-cases.
   Visible rather than markup alone: BreadcrumbList is what search results and
   summarisers read, and it is meant to describe a trail somebody can actually
   see rather than one that only exists in JSON. Small, quiet, and above the
   title so it reads as position rather than as navigation. */
.page-head .page-crumb {
    margin: 0 0 10px;
    font-size: 14px;
    color: var(--text-dim);
}

.page-head .page-crumb a {
    color: var(--text-dim);
}

.page-head .page-crumb a:hover {
    color: var(--text);
}

/* Not a slash, because a screen reader reads punctuation aloud inconsistently
   and the separator carries no meaning. Hidden from the tree, and the list
   semantics come from the markup instead. */
.page-head .page-crumb span {
    margin: 0 6px;
    opacity: 0.5;
}

.page-head h1 {
    font-size: clamp(26px, 4.2vw, 36px);
    font-weight: 650;
    letter-spacing: -0.02em;
    margin: 0 0 14px;
}

.page-head p {
    margin: 0;
    font-size: 16px;
    line-height: 1.6;
    color: var(--text-dim);
}

/* The form leads and the aside follows it down on a narrow screen, because the
   aside is what you read if the form is not what you wanted. */
.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 28px;
    align-items: start;
}

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

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 28px;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
}

.contact-form label {
    display: flex;
    flex-direction: column;
    gap: 7px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}

.contact-form input,
.contact-form textarea {
    width: 100%;
    font: inherit;
    font-weight: 400;
}

.contact-form textarea {
    resize: vertical;
    min-height: 8rem;
    line-height: 1.55;
}

.contact-form small {
    font-size: 12.5px;
    font-weight: 400;
    color: var(--text-faint);
}

.contact-form button {
    align-self: flex-start;
}

/* The honeypot.

   Hidden four ways rather than one, because the bots worth catching check for
   display:none and skip those fields. Off-screen, no size, no pointer and out
   of the tab order: a person cannot reach it with a mouse, a finger, a keyboard
   or a screen reader, and something filling the form in blind fills it in. */
.hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
    pointer-events: none;
}

.contact-note {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    min-height: 1.2em;
}

.contact-note.is-ok {
    color: var(--green);
}

.contact-note.is-bad {
    color: var(--red);
}

.contact-aside {
    padding: 4px 0 0;
}

.contact-aside h2 {
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 6px;
}

.contact-aside h2 + p {
    margin: 0 0 24px;
    font-size: 15.5px;
    line-height: 1.6;
    color: var(--text-dim);
}

.contact-aside a {
    color: var(--accent);
}

/* ── Legal pages ────────────────────────────────────────────────────── */

/* One column, and 60rem rather than the 40 it was.

   The rule for this was already written, over on .help-page: the legal pages
   stay narrow because they are "unbroken paragraphs, where a short measure is
   the whole point", and help is wider because "a card that stops 370px short of
   the header above it reads as unfinished in a way a paragraph never does".

   Carding these pages moved them from one side of that sentence to the other.
   They are bordered cards now, so the reason for 40rem went with the paragraphs
   it was about, and the page read thin and squeezed beside the homepage.

   60rem and not the full 1280 of main, for the reason .help-page also gives:
   filling it lines up with the header for about a second, and then the longer
   paragraphs run to 130 characters and the eye loses its place coming back to
   the left. The homepage never runs prose that wide either. Its cards are 20rem
   in a grid; only the frame around them is 1280. */
.legal {
    max-width: 60rem;
    padding-bottom: 24px;
}

.legal h2 {
    font-size: 18px;
    font-weight: 650;
    letter-spacing: -0.01em;
    margin: 36px 0 10px;
}

.legal h2:first-child {
    margin-top: 0;
}

.legal p {
    margin: 0 0 14px;
    font-size: 15.5px;
    line-height: 1.7;
    color: var(--text-dim);
}

.legal a {
    color: var(--accent);
}

.legal-date {
    margin-top: 14px !important;
    font-size: 13.5px;
    color: var(--text-faint) !important;
}

/* The h2 above is only 18px, so a subheading has to come down rather than up.
   A browser default h3 lands almost exactly on top of it and the hierarchy
   stops existing. */
.legal h3 {
    font-size: 15.5px;
    font-weight: 650;
    color: var(--text);
    margin: 26px 0 8px;
}

.legal strong {
    color: var(--text);
    font-weight: 620;
}

/* A list in the middle of legal text is a paragraph that happens to have
   bullets, so it matches .legal p rather than inventing a second voice. This
   had been falling through to browser defaults on the privacy page. */
.legal-list {
    margin: 0 0 14px;
    padding-left: 20px;
    font-size: 15.5px;
    line-height: 1.7;
    color: var(--text-dim);
}

.legal-list li {
    margin-bottom: 6px;
}

/* The bit somebody has to actually see before they act. Amber rather than red:
   this is "read this first", not "something has gone wrong".

   Compound selector because .legal p already sets a colour and would otherwise
   win on specificity. */
.legal .legal-note {
    padding: 12px 14px;
    border-left: 3px solid var(--amber-line);
    border-radius: 0 var(--radius-input) var(--radius-input) 0;
    background: var(--amber-soft);
    color: var(--text);
}

/* ── The help page ──────────────────────────────────────────────────── */

/* Everything inside this comes from Help.razor.css, copied whole by
   deploy/build-help.cs, and none of it is edited here. What is left for this
   file is where the column sits on the page, which is a marketing layout
   question rather than anything the app's own help screen has an opinion about:
   in the app that page fills a phone, and here it is sitting inside a 1100px
   main between a header and a footer.

   Wider than the legal pages, which is a departure and a deliberate one. Those
   are unbroken paragraphs, where a short measure is the whole point. This is
   eighteen bordered cards, and a card that stops 370px short of the header
   above it reads as unfinished in a way a paragraph never does.

   60rem rather than filling main. Filling it lines the cards up with the header
   exactly, which looks tidier for about a second, and then the longer
   paragraphs run to 130 characters and the eye starts losing its place coming
   back to the left. This is the widest the text stays comfortable at. */
.help-page {
    max-width: 60rem;
    padding: 32px 0 24px;
}

/* ── Footer ─────────────────────────────────────────────────────────── */

.site-foot {
    max-width: 1280px;
    margin: 0 auto;
    padding: 32px 28px 56px;
    border-top: 1px solid var(--border-row);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 24px;
}

.foot-links {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
}

/* The light/dark switch, in the footer rather than the header.

   The header was the obvious home and does not have the room: on a phone it is
   already brand and two buttons on one line with the nav wrapped underneath, and
   a third control pushes that past a 360px screen. Down here it costs nothing,
   and somebody who wants it goes looking in a footer anyway.

   A circle with a hairline round it, no fill. It is a quiet control - nobody
   arrives wanting to change the theme - so it reads as a mark rather than as a
   button competing with Get started free. */
/* Holds the button and the word that appears beside it. Positioned, so the word
   can be taken out of the flow and cannot nudge the footer as it comes and
   goes. */
.theme-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
}

/* The state, named for a moment after a click.

   A three state cycle always has one step that changes no colour: auto and
   light are the same thing on a light laptop, so that click looked like a dead
   button. Rather than drop the state - pinning light is a real thing to want,
   it stops following when the machine flips at sunset - the switch says which
   one it landed on.

   To the left, because the switch sits at the right-hand end of the footer and
   anything to its right would be off the edge on a phone. */
.theme-said {
    position: absolute;
    right: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
    font-size: 13px;
    color: var(--text-dim);
    background: var(--bg-chip);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-chip);
    padding: 4px 10px;
    opacity: 0;

    /* Never in the way while invisible, and never a tab stop. */
    pointer-events: none;
    transition: opacity 0.18s ease;
}

.theme-said.is-on {
    opacity: 1;
}

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 1px solid var(--border-chip);
    border-radius: 50%;
    background: transparent;
    color: var(--text-dim);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.theme-toggle:hover {
    color: var(--text);
    border-color: var(--accent);
    background: var(--bg-chip);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.theme-toggle i {
    font-size: 18px;

    /* The glyph swaps between a sun and a moon, and the two have different
       optical weights. Fixing the box stops the circle twitching as it changes. */
    width: 18px;
    height: 18px;
    line-height: 18px;
    text-align: center;
}

.foot-links a {
    color: var(--text-dim);
    text-decoration: none;
    font-size: 14px;
}

.foot-links a:hover {
    color: var(--text);
}

.foot-credit {
    margin: 0;
    font-size: 13px;
    color: var(--text-faint);
}

.foot-credit a {
    color: var(--text-dim);
}

/* The header stacks before the hero does, because three groups across is the
   first thing to run out of room. */
/* The header on a phone: brand and the two buttons on one line, the nav on its
   own line underneath.

   That much was already here, and it was not enough. The nav kept the desktop
   28px padding, 16px gaps and 15px links, which comes to more than a 360px
   phone has: the row wrapped and Contact dropped alone onto a third line,
   under-hanging the rest and looking like a mistake.

   So the row is told not to wrap and the links not to break, and everything
   that was spending width gives some back. At 14px the five links measure about
   234px, which leaves room to spare inside 320px once the padding comes down,
   and space-between spreads whatever is left evenly rather than bunching them
   at one end. Nothing here relies on the number of links: four on the inner
   pages spread wider, and the same rules hold. */
@media (max-width: 640px) {
    .site-head {
        gap: 10px;
        padding: 16px 18px;
    }

    .brand {
        font-size: 17.5px;
    }

    .site-nav {
        order: 3;
        width: 100%;
        margin-inline: 0;

        /* A minimum rather than a fixed gap: space-between does the spacing,
           and this only stops the links touching on the narrowest screens. */
        gap: 6px;
        flex-wrap: nowrap;
        justify-content: space-between;
    }

    .site-nav a {
        font-size: 14px;

        /* The actual fix for the reported wrap. Without it the longest link
           breaks inside itself rather than the row breaking, which is worse. */
        white-space: nowrap;
    }

    /* Five links held one line at 320px with the old set. "How it works" is
       longer than the "Home" it replaced, and the five no longer fit, so it is
       the one that steps out: the band it points at is one scroll below the
       hero, and the hero's own second button goes there too. */
    .site-nav .nav-wide {
        display: none;
    }

    .site-actions {
        margin-inline: auto 0;
    }

    /* Trimmed so the brand and both buttons hold one line together. They come
       to about 292px at desktop sizing, which is more than a 320px screen has
       once the padding is counted. */
    .site-actions .btn {
        padding: 8px 13px;
    }
}
/* ── The rental call-out ────────────────────────────────────────────── */

/* Carded rather than plain, because it is answering one reader's question
   rather than continuing the argument, and it has to be findable by somebody
   skimming for the word "rental". Sits between the features and the
   screenshots: after "here is what it does" and before "here is what it looks
   like", which is where "is this for me" belongs. */
/* Two prose bands, one shape. The rental one answers "is this for me", the
   category one answers "what is this", and a reader meeting them at opposite
   ends of the page should not be able to tell they were written months apart.
   Grouped rather than copied, so they cannot drift. */
.rental,
.category {
    margin-top: 32px;
    padding: 26px 24px;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
}

.rental h2,
.category h2 {
    margin: 0 0 12px;
    font-size: clamp(19px, 2.6vw, 23px);
    font-weight: 650;
    letter-spacing: -0.02em;
}

.rental p,
.category p {
    margin: 0 0 10px;
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--text-dim);
}

.rental p:last-child,
.category p:last-child {
    margin-bottom: 0;
}

/* The line worth carrying away, given the weight of body text rather than the
   whisper of it. It is the only sentence on the page that tells somebody what
   shelf to put this on. */
.category p:first-of-type {
    color: var(--text);
    font-size: clamp(16.5px, 2.1vw, 18.5px);
}

/* ── Questions people ask ───────────────────────────────────────────── */

/* details and summary, so the page keeps its promise of running no JavaScript.
   The browser handles opening and closing, keyboard included, and a crawler
   reads the answers whether they are open or shut. */
.faq {
    padding-top: 40px;
}

.faq > h2 {
    font-size: clamp(20px, 3vw, 26px);
    font-weight: 650;
    letter-spacing: -0.02em;
    margin: 0 0 18px;
}

.faq details {
    border-bottom: 1px solid var(--border-card);
}

.faq summary {
    padding: 16px 34px 16px 0;
    position: relative;
    font-size: 16.5px;
    font-weight: 600;
    cursor: pointer;

    /* The default triangle sits too close to the text and differs between
       browsers, so it goes and a chevron takes its place on the other side. */
    list-style: none;
}

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

.faq summary::after {
    content: "";
    position: absolute;
    right: 6px;
    top: 22px;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--text-faint);
    border-bottom: 2px solid var(--text-faint);
    transform: rotate(45deg);
    transition: transform 0.15s ease;
}

.faq details[open] summary::after {
    transform: rotate(-135deg);
    top: 26px;
}

.faq summary:hover {
    color: var(--accent);
}

.faq summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-input);
}

.faq details p {
    margin: 0 0 14px;
    padding-right: 34px;
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--text-dim);
    max-width: 44rem;
}

.faq details p a {
    color: var(--accent);
}

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

/* ── The sharing page's persona table ───────────────────────────────── */

/* Scrolls inside its own box rather than pushing the page sideways. Three
   columns of prose is wider than a phone whatever you do to the type, and a
   horizontally scrolling body is the one layout failure that makes every other
   page element feel broken too. */
.share-table-wrap {
    overflow-x: auto;
    margin: 0 0 14px;
    -webkit-overflow-scrolling: touch;
}

.share-table {
    width: 100%;
    min-width: 34rem;
    border-collapse: collapse;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--text-dim);
}

/* Two columns rather than three, so nothing needs holding apart: the role names
   are single words and the sentence beside them wraps happily. The shared
   min-width would only invent a scrollbar on a phone. */
.share-table.is-pairs {
    min-width: 0;
}

.share-table th,
.share-table td {
    text-align: left;
    vertical-align: top;
    padding: 10px 14px 10px 0;
    border-bottom: 1px solid var(--border-row);
}

.share-table thead th {
    font-size: 12.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-faint);
    border-bottom-color: var(--border-card);
}

/* The row heading is the person, and it is what somebody scans for - so it
   carries the weight rather than the cells beside it. */
.share-table tbody th {
    font-weight: 620;
    color: var(--text);
    white-space: nowrap;
    padding-right: 20px;
}

.share-table tbody tr:last-child th,
.share-table tbody tr:last-child td {
    border-bottom: none;
}

@media (max-width: 30rem) {
    .share-table {
        min-width: 30rem;
        font-size: 14px;
    }

    /* The name wraps on a narrow screen after all. Holding it on one line is
       what keeps the table readable at every other width, and at this one it is
       what forces the scroll to be long rather than short. */
    .share-table tbody th {
        white-space: normal;
    }
}

/* ── The five-second version ────────────────────────────────────────── */

/* Two columns where there is room and one where there is not, rather than a
   grid of fixed cards: these are lines of text, and a line of text that wraps
   inside a box it shares with a tick reads worse than one that simply runs on. */
.ticks {
    padding: 4px 0 28px;
}

.ticks ul {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
    gap: 10px 28px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ticks li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 15.5px;
    line-height: 1.55;
    color: var(--text-dim);
}

/* Green, and the only green on the page. A tick in the accent blue reads as a
   link on a page where every other blue thing is one. */
.ticks li i {
    flex-shrink: 0;
    margin-top: 2px;
    font-size: 17px;
    color: var(--green);
}

/* ── Read next ──────────────────────────────────────────────────────── */

/* The way on from an explainer page. Constrained to the same measure as .legal
   so it sits under the prose rather than beside it, which is why it moved with
   it when .legal went to 60rem. */
.page-more {
    max-width: 60rem;
    margin: 40px 0 8px;
    padding-top: 24px;
    border-top: 1px solid var(--border-card);
}

.page-more h2 {
    font-size: 13px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
    margin: 0 0 10px;
}

.page-more a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 13px 16px;
    margin-bottom: 8px;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-input);
    color: var(--text);
    text-decoration: none;
    font-size: 15.5px;
    font-weight: 600;
    transition: border-color 0.15s ease;
}

.page-more a:hover {
    border-color: var(--accent-line);
}

.page-more a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.page-more a i {
    color: var(--accent);
    font-size: 17px;
    flex-shrink: 0;
}

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

/* A document, shown on a page about documents.

   Capped by height rather than width, because these are portrait A4 at roughly
   1:1.4 and a full-width one would be over a screen tall on a phone. The reader
   is being shown the SHAPE of the thing, not asked to read it, so the right size
   is the largest that still lets the paragraph under it be reached by scrolling.

   The white paper carries its own hairline border, drawn into the image by
   document-shots.py, so it does not need one here and cannot be given a
   different one on the two themes by accident. */
.doc-shot {
    margin: 22px 0 26px;
    text-align: center;
}

.doc-shot img {
    max-width: 100%;
    max-height: 62vh;
    width: auto;
    height: auto;
    border-radius: 4px;
    box-shadow: 0 10px 30px -18px rgba(15, 23, 42, 0.55);
}

.doc-shot figcaption {
    margin-top: 10px;
    color: var(--text-dim);
    font-size: 14px;
    line-height: 1.5;
}

/* A link at the end of a paragraph, made obvious.

   These were ordinary inline anchors sitting at the end of a sentence, which on
   a page whose whole job is to send people to the eight pages behind it is the
   one thing that had to be unmissable and was not. The site already had two
   shapes for "go and read that": .feature-more inside a card, and .page-more as
   a full-width row at the foot. Neither fits mid-article, so this is the third
   and the smallest.

   A block rather than inline-flex on its own, and that is the point of the
   wrapper below: a pill that flows with the text lands halfway along a line
   whenever the paragraph above it happens to end there, which reads as a stray
   button rather than as the next step. */
.read-on-row {
    margin: 14px 0 4px;
}

.read-on {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 15px;
    background: var(--bg-chip);
    border: 1px solid var(--border-chip);
    border-radius: 999px;
    color: var(--text);
    text-decoration: none;
    font-size: 14.5px;
    font-weight: 600;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.read-on:hover {
    background: var(--bg-card);
    border-color: var(--accent-line);
}

.read-on:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.read-on i {
    color: var(--accent);
    font-size: 15px;
}

/* Jump to the section that is you, at the top of /use-cases.

   The same chips the app's help page puts at the top of itself, and for the
   same reason: a page that is a list of audiences should let somebody say which
   one they are rather than read until they find out.

   Wrap without a shrink of any kind. flex-wrap: wrap and flex-shrink: 0 on one
   element cancel out, the wrap loses, and the row overflows the page on a phone
   instead of stacking. That shipped on the Areas screen once and probe-css
   refuses it now. */
.use-jump {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 18px 0 26px;
}

.use-jump a {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px;
    border: 1px solid var(--border-chip);
    border-radius: 999px;
    background: var(--bg-chip);
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.use-jump a:hover {
    background: var(--bg-card);
    border-color: var(--accent-line);
}

.use-jump a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.use-jump a i {
    color: var(--accent);
    font-size: 15px;
}

/* Breathing room above a heading somebody jumped to.

   Not for a sticky header: there is not one on this site, and the first version
   of this comment said there was and put 84px against it. The header scrolls
   away with everything else, so the only problem is a heading landing flush
   against the top edge of the window, which reads as the page having been cut
   off rather than scrolled to. */
.legal h2[id] {
    scroll-margin-top: 24px;
}

/* Inside a card the heading is already 20px down from the card's top edge, so
   the margin has to clear that too or the thing somebody jumped to opens with
   its own top cropped off the screen. */
.legal-card > h2[id] {
    scroll-margin-top: 44px;
}

/* A section of an article, in a card.

   The app's help page has done this for a while and the difference is the whole
   reason to copy it: flat text running down a page reads as a blog, and a page
   that is a set of separate answers is not one. On /use-cases a reader arrives
   at one section from the chips at the top rather than reading from the start,
   and a card is what tells them where the answer they asked for begins and ends.

   The marketing site's own card rather than the app's. .feature uses these three
   tokens and this sits on the same site, so matching it keeps /use-cases looking
   like the homepage instead of like a screenshot of the product. */
.legal-card {
    padding: 20px 22px;
    margin: 0 0 14px;
    background: var(--bg-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-card);
}

/* The first heading in a card has the card's own padding above it and needs no
   margin of its own on top. Without this every card opens with a gap that none
   of them meant. */
.legal-card > h2:first-child {
    margin-top: 0;
}

.legal-card > p:last-child,
.legal-card > .read-on-row:last-child {
    margin-bottom: 0;
}
