/* ==========================================================================
   VELNOIR — base layer (Phase 7). Document defaults on the token grammar.
   Rules: every value is a var() from tokens.css (Design Law 2); every
   transition/animation lives inside prefers-reduced-motion: no-preference
   (Design Law 6 — the static composition is the default, not the fallback).
   ========================================================================== */

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

* {
    margin: 0;
}

html {
    background: var(--surface);
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 100%;
    -webkit-text-size-adjust: 100%;
    scroll-behavior: auto;
}

body {
    font-size: var(--text-0);
    line-height: var(--leading-body);
    min-height: 100vh;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
    font-family: var(--font-display);
    font-weight: 500;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    text-wrap: balance;
}

p {
    max-width: var(--container-text);
}

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

a {
    color: var(--ink);
    text-decoration-color: var(--accent);
    text-decoration-thickness: var(--hairline);
    text-underline-offset: 0.2em;
}

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

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

/* Skip link — visible on focus, in the brand voice. */
.skip-link {
    position: absolute;
    left: var(--space-4);
    top: var(--space-4);
    z-index: 100;
    padding: var(--space-2) var(--space-4);
    background: var(--surface-high);
    color: var(--ink);
    border: var(--hairline) solid var(--line);
    border-radius: var(--radius-1);
    transform: translateY(-300%);
}

.skip-link:focus {
    transform: none;
}

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

.container--text {
    max-width: var(--container-text);
}

/* The reveal vocabulary (D123): hidden states exist ONLY under html.anim
   (JS present AND motion preferred), and the anim-done failsafe releases
   everything if the deferred bundle never runs. Without JS nothing is
   ever hidden. */
.reveal {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: no-preference) {
    html.anim:not(.anim-done) .reveal {
        opacity: 0;
        transform: translateY(var(--reveal-rise));
    }

    html.anim .reveal.is-in,
    html.anim.anim-done .reveal {
        opacity: 1;
        transform: none;
        transition:
            opacity var(--dur-3) var(--ease-out),
            transform var(--dur-3) var(--ease-out);
        transition-delay: calc(var(--reveal-i, 0) * 90ms);
    }

    a,
    button {
        transition:
            color var(--dur-1) var(--ease-out),
            background-color var(--dur-1) var(--ease-out),
            border-color var(--dur-1) var(--ease-out),
            opacity var(--dur-1) var(--ease-out);
    }
}
