/* DSDS Spec Site — Stylesheet
   Design tokens are defined in tokens.css, loaded via <link> in every page.
   Reference --ds-* tokens directly — no legacy alias layer. */

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

:target {
    scroll-margin-top: 5vh;
}

html {
    font-size: 16px;
    -webkit-text-size-adjust: 100%; /* still required by Safari; no unprefixed fallback there */
    text-size-adjust: 100%;
    scroll-behavior: smooth;
    background: var(--ds-color-bg-accent);
}

body {
    font-family: var(--ds-font-body);
    font-weight: var(--ds-font-weight-regular);
    color: var(--ds-color-text);
    background: var(--ds-color-bg);
    line-height: 1.6;
    display: flex;
    flex-direction: column;
    min-height: 100vh;

    /* 100dvh accounts for mobile browser chrome (address bar) shrinking
       the real viewport - 100vh alone is the classic mobile-Safari bug
       where a full-height element runs taller than what's actually
       visible. Cascading fallback: an unsupported browser just never
       sees this second declaration and keeps the 100vh above. */
    min-height: 100dvh;
    text-rendering: geometricprecision;
    -webkit-font-smoothing: antialiased;
    padding: 0;
    margin: 0;
}

/* Skip link — visually hidden until keyboard-focused */
.skip-link {
    position: fixed;
    inset-block-start: 0.5rem;
    inset-inline-start: 0.5rem;
    z-index: var(--ds-z-skip-link, 300);
    padding: 0.5rem 1rem;
    background: var(--ds-color-bg);
    color: var(--ds-color-text);
    text-decoration: none;
    transform: translateY(calc(-100% - 1rem));
}

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

/* Main content area — the nav is fixed-position and sits on top of this
   (not pushing it via margin), so padding reserves the same visual inset
   instead of shifting the box itself. Block-start now (a top bar), not
   inline-start (there's no more sidebar column to reserve). */
.content {
    flex: 1;
    min-width: 0;
    display: flex;
}

.content__main {
    flex: 1;
    min-width: 0;
}

.content__container {
    padding-block-start: var(--ds-height-nav, 64px);
}

/* content--full pages (Quick start, Schema) open with <ds-header>'s own
   full-viewport hero (min-height: 100dvh, see header.js) instead of
   flowing straight from the fixed nav bar - the hero already clears the
   nav on its own, so this container's nav-clearance padding is redundant
   weight stacked on top of it, not a second gap that needs clearing. */
.content--full .content__container {
    padding-block-start: 0;
}

.content__inner {
    max-width: var(--ds-width-content);
    margin: 0 auto;
    padding: var(--ds-space-8) var(--ds-space-8);

    /* Generous bottom padding so the page doesn't end abruptly right after
       the last line of content. */
    padding-bottom: calc(var(--ds-space-8) * 4);
}

/* The Schema page's own layout: full viewport width, not the shared
   reading-width cap, so its side-by-side def/example columns have real
   room. Set via renderMainSchema()'s content_class, not by page type name -
   any page could ask for it in principle.

   The right-hand column's white background is painted here, once, as
   content__inner's own background - not per-<ds-def-section>, and not as
   an absolutely-positioned pseudo-element behind everything either (tried
   that first: a position:absolute, z-index:-1 ::before is still a
   *descendant*, and its stacking position depends on content__inner
   forming its own stacking context, which position:relative alone does
   not guarantee - it silently painted behind other content in testing).
   An element's own background always paints beneath all of its
   descendants, full stop, with no stacking-context caveats - so a hard-
   stop gradient here is the one paint layer every <ds-def-section>
   (split or not, with or without an example) and every group heading
   renders on top of, for the page's entire height, automatically. Split
   at the same x position <ds-def-section>'s own .cols grid uses (50% +
   half the column gap, since the container's own padding cancels out of
   that math - see the DEF_SECTION_CSS comment on .end for the matching
   per-section version). */
.content--full .content__inner {
    max-width: none;
    background: linear-gradient(
        to right,
        transparent calc(50% + var(--ds-space-8) / 2),
        var(--ds-color-bg-inverse) 0
    );
}

/* Typography */

p {
    margin-bottom: var(--ds-space-4);
}

a {
    color: var(--ds-color-accent);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    transition: color var(--ds-duration-fast) var(--ds-ease-standard);
}

a:hover {
    /* No separate "hover" token — mixed on the fly from the accent color. */
    color: color-mix(in oklch, var(--ds-color-accent) 80%, black);
}

strong {
    font-weight: var(--ds-font-weight-bold);
}

em {
    font-style: italic;
}

hr {
    border: none;
    margin: var(--ds-space-16) 0;
    height: 0;
}

/* Lists */
ul,
ol {
    margin-bottom: var(--ds-space-4);
    padding-inline-start: var(--ds-space-8);
}

li {
    margin-bottom: var(--ds-space-1);
    line-height: 1.6;
}

li > ul,
li > ol {
    margin-top: var(--ds-space-1);
    margin-bottom: 0;
}

ul {
    list-style: square;
}

/* Blockquotes / notes */
blockquote {
    border-inline-start: 1px solid var(--ds-color-accent);
    background: var(--ds-color-accent-subtle);
    padding: var(--ds-space-4) var(--ds-space-8);
    margin-bottom: var(--ds-space-8);
    font-size: 0.9375rem;
}

blockquote p:last-child {
    margin-bottom: 0;
}

@media (max-width: 900px) {
    /* The bar's own reserved block-start space (.content__container's base
       rule) still applies here - the top bar never disappears at mobile,
       it just gains a collapsible dropdown, so content still needs to
       clear its closed-state height. Only the side padding shrinks. */
    .content__inner {
        padding-inline: var(--ds-space-4);
        padding-bottom: calc(var(--ds-space-8) * 4);
    }

    /* The desktop hard-stop gradient (see .content--full .content__inner
       above) splits left/right at the midpoint of a two-column .cols row -
       correct there, since .start and .end each really do occupy one
       half. Below the 900px breakpoint .cols collapses to a single
       column (guide-section.js/def-section.js), so .start stretches to
       the full width and would sit on top of whichever half of the
       gradient happens to fall behind it - a 50/50 tan/white split
       behind stacked, full-width content, not a meaningful boundary
       between two columns that no longer exist. Solid instead: .end's
       own white background (painted directly on itself, not borrowed
       from this gradient) still shows wherever an .end panel actually
       renders below .start, same as always. */
    .content--full .content__inner {
        background: var(--ds-color-bg);
    }
}

/* Print */
@media print {
    ds-spec-nav,
    ds-back-to-top {
        display: none;
    }

    .content__container {
        padding-block-start: 0;
    }

    pre {
        white-space: pre-wrap;
        overflow-wrap: break-word;
    }
}

/* ── Page transitions ─────────────────────────────────────────────────
   Opts every same-origin navigation into the browser's native
   cross-document view transition (a plain cross-fade unless overridden
   below). Browsers without support just navigate normally — no fallback
   needed. Durations come from the same tokens as the rest of the site's
   motion, so prefers-reduced-motion (tokens.css) turns this off too. */
@view-transition {
    navigation: auto;
}

@keyframes move-out {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

@keyframes move-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

::view-transition-old(root) {
    animation: 0.3s ease-in both move-out; /* FIX */
}

::view-transition-new(root) {
    animation: 0.3s ease-in both move-in 0.4s; /* FIX */
}

/* ── Site footer ─────────────────────────────────────────────────────────
   Plain semantic HTML rather than a custom element (see nav.js's
   buildFooter): every page ends with it, and a reader without JS should
   never have to hydrate a shadow root to find the Conformance page.
   Conformance and Stability live here rather than in the top nav - they're
   the spec's normative and forward-looking halves, cited constantly and
   read start-to-finish rarely, so they'd compete with the four pages
   someone actually works through in order. */

.site-footer {
    background: var(--ds-color-bg-accent);
    padding: var(--ds-space-8) var(--ds-space-4);
    font-size: var(--ds-font-size-sm);
}

.site-footer__inner {
    max-inline-size: 72rem;
    margin-inline: auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: var(--ds-space-8);
}

.site-footer__group {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    align-items: start;
}

.site-footer__heading {
    margin: 0 0 var(--ds-space-1);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-font-size-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--ds-color-text-muted, var(--ds-color-text));
}

.site-footer__group a {
    color: var(--ds-color-text);
    text-decoration: none;
    text-underline-offset: 0.2em;
}

.site-footer__group a:hover,
.site-footer__group a:focus-visible {
    text-decoration: underline;
    color: var(--ds-color-accent);
}

.site-footer__meta {
    max-inline-size: 72rem;
    margin: var(--ds-space-8) auto 0;
    font-family: var(--ds-font-mono);
    font-size: var(--ds-font-size-xs);
}
