/* TextTray — marketing site
   No frameworks, no external requests, no build step. The only JavaScript
   is assets/theme.js, a small vanilla light/dark toggle. */

:root {
    --bg: #ffffff;
    --bg-subtle: #f6f7f9;
    --text: #1a1d21;
    --text-muted: #5c6570;
    --border: #e3e6ea;
    --accent: #2563eb;
    --accent-soft: #eff4ff;
    --danger: #c02b20;
    --danger-soft: #fdecea;
    --radius: 12px;
    --measure: 42rem;
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #101215;
        --bg-subtle: #181b1f;
        --text: #e9ecef;
        --text-muted: #9aa4b0;
        --border: #272b31;
        --accent: #6899ff;
        --accent-soft: #172033;
        --danger: #ff6f61;
        --danger-soft: #33201d;
    }
}

/* Explicit choice from the theme switch (assets/theme.js) overrides the
   system preference above — the attribute selector outranks a bare :root
   rule regardless of which media query it's nested in. */
:root[data-theme="light"] {
    --bg: #ffffff;
    --bg-subtle: #f6f7f9;
    --text: #1a1d21;
    --text-muted: #5c6570;
    --border: #e3e6ea;
    --accent: #2563eb;
    --accent-soft: #eff4ff;
    --danger: #c02b20;
    --danger-soft: #fdecea;
}

:root[data-theme="dark"] {
    --bg: #101215;
    --bg-subtle: #181b1f;
    --text: #e9ecef;
    --text-muted: #9aa4b0;
    --border: #272b31;
    --accent: #6899ff;
    --accent-soft: #172033;
    --danger: #ff6f61;
    --danger-soft: #33201d;
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 17px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}

.wrap {
    max-width: 60rem;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.narrow {
    max-width: var(--measure);
}

a {
    color: var(--accent);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

code,
kbd {
    font-family: var(--mono);
    font-size: 0.88em;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0.1em 0.4em;
    white-space: nowrap;
}

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

header.site {
    padding: 2rem 0 0;
}

header.site .wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--text);
}

.brand:hover {
    text-decoration: none;
}

/* The app icon (assets/icon-64.png, rendered from the app's TextTray.icon).
   Its own rounded-square shape and white tile come from the image itself. */
.brand-mark {
    width: 28px;
    height: 28px;
    display: block;
    flex: none;
    /* follows the icon's own outline so the white tile still reads on a white header */
    filter: drop-shadow(0 0 0.5px rgba(0, 0, 0, 0.35)) drop-shadow(0 1px 2px rgba(0, 0, 0, 0.12));
}

/* ---------- Theme switch ---------- */

.theme-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    user-select: none;
}

.theme-switch-label {
    font-size: 0.85rem;
    color: var(--text-muted);
}

.theme-switch-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.theme-switch-track {
    width: 2.375rem;
    height: 1.375rem;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px;
    display: flex;
    align-items: center;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.theme-switch-thumb {
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background: var(--text-muted);
    transform: translateX(0);
    transition: transform 0.15s ease, background-color 0.15s ease;
}

.theme-switch-input:checked + .theme-switch-track {
    background: var(--accent-soft);
    border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.theme-switch-input:checked + .theme-switch-track .theme-switch-thumb {
    transform: translateX(1rem);
    background: var(--accent);
}

.theme-switch-input:focus-visible + .theme-switch-track {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .theme-switch-track,
    .theme-switch-thumb {
        transition: none;
    }
}

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

.hero {
    padding: 4.5rem 0 3rem;
    text-align: center;
}

.badge {
    display: inline-block;
    background: var(--accent-soft);
    color: var(--accent);
    border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
    border-radius: 999px;
    padding: 0.3rem 0.9rem;
    font-size: 0.83rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    margin-bottom: 1.75rem;
}

.badge-danger {
    background: var(--danger-soft);
    color: var(--danger);
    border-color: color-mix(in srgb, var(--danger) 25%, transparent);
}

h1 {
    font-size: clamp(2.1rem, 6vw, 3.4rem);
    line-height: 1.1;
    letter-spacing: -0.025em;
    margin: 0 0 1.25rem;
    font-weight: 700;
}

.lede {
    font-size: clamp(1.05rem, 2.4vw, 1.25rem);
    color: var(--text-muted);
    max-width: var(--measure);
    margin: 0 auto 2rem;
}

.cta-row {
    display: flex;
    gap: 0.75rem;
    justify-content: center;
    flex-wrap: wrap;
    align-items: center;
}

.btn {
    display: inline-block;
    background: var(--accent);
    color: #fff;
    border-radius: 10px;
    padding: 0.7rem 1.4rem;
    font-weight: 600;
    font-size: 1rem;
    border: 1px solid transparent;
    transition: filter 0.15s ease, transform 0.15s ease;
}

.btn:hover {
    text-decoration: none;
    filter: brightness(1.08);
    transform: translateY(-1px);
}

.btn:active {
    filter: brightness(0.97);
    transform: translateY(0);
}

.btn-quiet {
    background: transparent;
    color: var(--text);
    border-color: var(--border);
}

.cta-note {
    font-size: 0.9rem;
    color: var(--text-muted);
    margin-top: 1rem;
}

/* ---------- Screenshot ---------- */

.shot {
    margin: 3rem auto 0;
    max-width: 46rem;
}

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

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

section {
    padding: 3.5rem 0;
}

section.tinted {
    background: var(--bg-subtle);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

h2 {
    font-size: clamp(1.5rem, 3.5vw, 2rem);
    letter-spacing: -0.02em;
    margin: 0 0 0.75rem;
    font-weight: 650;
}

.section-intro {
    color: var(--text-muted);
    margin: 0 0 2.5rem;
    max-width: var(--measure);
}

.center {
    text-align: center;
}

.center .section-intro {
    margin-left: auto;
    margin-right: auto;
}

/* ---------- Features ---------- */

/* Flex rather than grid: with five items, grid leaves a hole at the end of the
   last row, while flex + justify-content lets that row centre under the one
   above. Column counts are set explicitly per breakpoint so the last row keeps
   the same item width as the full rows instead of stretching to fill. */
.features {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.75rem 2rem;
    list-style: none;
    padding: 0;
    margin: 0;
}

.features > li {
    flex: 0 1 100%;
}

@media (min-width: 34rem) {
    .features > li {
        flex-basis: calc((100% - 2rem) / 2);
    }
}

@media (min-width: 52rem) {
    .features > li {
        flex-basis: calc((100% - 4rem) / 3);
    }
}

.features h3 {
    margin: 0 0 0.35rem;
    font-size: 1.02rem;
    font-weight: 620;
}

.features p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.95rem;
}

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

.steps {
    counter-reset: step;
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: 1.75rem 2rem;
}

.steps li {
    counter-increment: step;
}

.steps li::before {
    content: counter(step);
    display: grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 700;
    font-size: 0.9rem;
    margin-bottom: 0.6rem;
}

.steps p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.95rem;
}

.steps strong {
    display: block;
    color: var(--text);
    font-weight: 620;
    font-size: 1.02rem;
    margin-bottom: 0.3rem;
}

/* ---------- Pricing ---------- */

.price-card {
    border: 1px solid var(--border);
    background: var(--bg);
    border-radius: 16px;
    padding: 2.5rem 2rem;
    text-align: center;
    max-width: 26rem;
    margin: 0 auto;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 20px 44px -24px rgba(0, 0, 0, 0.3);
}

.price {
    font-size: 3rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1;
}

.price-term {
    font-size: 1rem;
    font-weight: 500;
    color: var(--text-muted);
}

.price-list {
    list-style: none;
    padding: 0;
    margin: 1.5rem 0 0;
    text-align: left;
    display: inline-block;
    color: var(--text-muted);
    font-size: 0.95rem;
}

.price-list li {
    padding-left: 1.5rem;
    position: relative;
    margin-bottom: 0.4rem;
}

.price-list li::before {
    content: "✓";
    position: absolute;
    left: 0;
    color: var(--accent);
    font-weight: 700;
}

/* ---------- Invite form ---------- */

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

.invite-form {
    display: flex;
    gap: 0.75rem;
    justify-content: center;
    flex-wrap: wrap;
    align-items: center;
}

.invite-input {
    flex: 1 1 14rem;
    max-width: 20rem;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.7rem 1rem;
    font-family: var(--font);
    font-size: 1rem;
}

.invite-input::placeholder {
    color: var(--text-muted);
}

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

button.btn {
    font-family: inherit;
    line-height: inherit;
    margin: 0;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

.invite-note {
    font-size: 0.85rem;
    color: var(--text-muted);
    margin: 1rem 0 0;
}

/* Honeypot: off-screen, not display:none, so basic bots that skip hidden
   fields still fill it in. Real visitors never see or reach it. */
.hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

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

/* The one authored moment: the hero is the only thing every visitor sees,
   so it gets a rehearsed entrance on load, each line arriving a beat after
   the last. Nothing below the fold repeats this — a landing page that
   fades every section up identically teaches visitors to stop looking
   after the second one. */
@media (prefers-reduced-motion: no-preference) {
    .hero > * {
        opacity: 0;
        animation: hero-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
    }

    .hero > *:nth-child(1) { animation-delay: 0ms; }
    .hero > *:nth-child(2) { animation-delay: 80ms; }
    .hero > *:nth-child(3) { animation-delay: 150ms; }
    .hero > *:nth-child(4) { animation-delay: 220ms; }
    .hero > *:nth-child(5) { animation-delay: 280ms; }
    .hero > *:nth-child(6) { animation-delay: 340ms; }
}

@keyframes hero-in {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Progressive enhancement only: .reveal is fully visible with no animation
   support at all, so a browser without view-timelines (or a user with
   reduced-motion set) sees the exact same page, just without the entrance.
   Scoped to the "Core features" and "How it works" lists only — the two
   places content actually reads as a list and a sibling stagger earns its
   keep; single blocks (section intros, the price card, the invite panel)
   stay still. */
.reveal {
    opacity: 1;
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .features > li.reveal,
        .steps li.reveal {
            opacity: 0;
            animation: reveal-up 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
            animation-timeline: view();
            animation-range: entry 0% entry 55%;
        }

        /* Delays are proportions of the range above, not wall time. */
        .features > li.reveal:nth-child(1) { animation-delay: 0ms; }
        .features > li.reveal:nth-child(2) { animation-delay: 70ms; }
        .features > li.reveal:nth-child(3) { animation-delay: 140ms; }
        .features > li.reveal:nth-child(4) { animation-delay: 210ms; }
        .features > li.reveal:nth-child(5) { animation-delay: 280ms; }

        .steps li.reveal:nth-child(1) { animation-delay: 0ms; }
        .steps li.reveal:nth-child(2) { animation-delay: 90ms; }
        .steps li.reveal:nth-child(3) { animation-delay: 180ms; }
    }
}

@keyframes reveal-up {
    from {
        opacity: 0;
        transform: translateY(22px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

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

    .hero > * {
        animation: none;
        opacity: 1;
        transform: none;
    }

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

    .btn {
        transition: none;
    }

    .btn:hover,
    .btn:active {
        transform: none;
    }
}

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

footer.site {
    border-top: 1px solid var(--border);
    padding: 2.5rem 0 3.5rem;
    font-size: 0.92rem;
    color: var(--text-muted);
}

.footer-links {
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

/* ---------- Legal pages ---------- */

.legal {
    padding: 3rem 0 4rem;
}

.legal h1 {
    font-size: clamp(1.8rem, 4vw, 2.4rem);
    margin-bottom: 0.5rem;
}

.legal h2 {
    font-size: 1.2rem;
    margin: 2.25rem 0 0.5rem;
}

.legal .updated {
    color: var(--text-muted);
    font-size: 0.92rem;
    margin: 0 0 2rem;
}

.legal p,
.legal li {
    color: var(--text-muted);
}

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

.back-link {
    display: inline-block;
    margin-bottom: 2rem;
    font-size: 0.93rem;
}
