/* base.css -- Reset, element defaults, typography
   Part of the site stylesheet, split out of the former single
   site.css. Load order is significant and is fixed in
   src/view/layout.php -- theme first (tokens), then base, then
   layout, then components. Rules were moved verbatim, in their
   original order, so the cascade is unchanged. */

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    background: var(--bg-base);
    color: var(--body-color);
    font-family: var(--font-body);
    font-size: var(--body-font-size);
    line-height: var(--body-line-height);
    /* Shared with body::before's height and .page's top padding, so
       real content always starts clear of the fixed fade overlay --
       otherwise it renders underneath it and looks faded by default,
       even before any scrolling happens. */
    --top-fade-height: 7.4em;
}

/* app-layout: logged-in account pages (layout.php's app_layout branch).
   The muted canvas lives on body itself, not just .app-page/main --
   matching how real dashboards (Basecamp, etc.) actually do it, so the
   wash always covers the full viewport regardless of .page's own
   height math, and the raised .sheet panel reads as sitting on top of
   something rather than blending into a body that's still --bg-base
   underneath/around it. */
body.app-layout {
    background: var(--bg-neutral-section);
}

/* The 37signals-style top fade (below) fades from --bg-base -- makes
   no sense over a body that's now --bg-neutral-section instead, and
   this hero-fade effect doesn't belong on a dashboard screen anyway
   (same reasoning as skipping the golden-ratio spacers, see layout.php). */
body.app-layout::before {
    display: none;
}

body::before {
    /* 37signals' actual technique: a separate fade overlay, not the
       header's own background (the header has none -- see above).
       position:fixed removes it from body's flex flow, so it doesn't
       affect header/main/footer layout. z-index sits below the
       header (100) so the nav text stays crisp on top, but above
       normal page content. */
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: var(--top-fade-height);
    /* Fades over (almost) the whole height, then stays fully
       transparent for the last stretch -- 37signals' own ratio. */
    background: linear-gradient(180deg, var(--bg-base) 0, transparent 90%);
    pointer-events: none;
    z-index: 90;
}

@media (min-width: 64em) and (hover: hover) and (pointer: fine) {
    body {
        --top-fade-height: max(22.2vh, 5.4em);
    }
}

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

a:hover {
    color: var(--link-hover-color);
    text-decoration: underline;
}

h1, h2, h3 {
    font-family: var(--font-heading);
    font-weight: var(--heading-weight);
    line-height: var(--heading-leading);
    letter-spacing: var(--heading-tracking);
    color: var(--fg-neutral-accent);
    text-wrap: balance;
    /* Anchor jumps (e.g. #about-foundry) would otherwise land right
       under body::before's fixed fade overlay at the top. */
    scroll-margin-top: var(--top-fade-height);
}

h1 {
    font-size: var(--heading-size-h1);
    margin: 0 0 var(--spacing-3);
}

h2 {
    font-size: var(--heading-size-h3);
    margin: var(--spacing-12) 0 var(--spacing-3);
}

h3 {
    font-size: var(--heading-size-h5);
    margin: var(--spacing-8) 0 var(--spacing-2);
}

p {
    margin: 0 0 var(--spacing-4);
    max-width: var(--prose-width);
}

.hero-actions, .tokens, .card p, .footer-inner p {
    max-width: none;
}

ul {
    padding-left: 1.25em;
    max-width: var(--prose-width);
}

ul.card-grid {
    max-width: none;
}

/* layout */
