/* Venus Lua API — documentation theme.
   Typography, color, and spacing tuned after the Astro / Starlight docs:
   soft body text, high-contrast headings, whitespace instead of boxes.
   Grayscale + accent are Starlight's HSL tokens. Self-contained: no web fonts, no CDNs. */

:root {
  --sidebar-w: 17rem;
  --content-max: 48rem;

  /* Color — light theme (Starlight light grayscale) */
  --bg: hsl(0, 0%, 100%);
  --fg: hsl(224, 10%, 23%);          /* body text (gray-2) */
  --heading: hsl(224, 14%, 11%);     /* headings + signatures (near-black) */
  --muted: hsl(224, 7%, 36%);        /* secondary text (gray-3) */
  --faint: hsl(224, 6%, 52%);        /* tertiary / labels (gray-4) */
  --accent: hsl(234, 90%, 58%);
  --accent-strong: hsl(234, 78%, 42%);
  --accent-weak: hsl(234, 90%, 95%);
  --rule: hsl(224, 9%, 83%);         /* borders */
  --rule-weak: hsl(224, 20%, 93%);   /* hairlines / section rules */
  --code-bg: hsl(224, 24%, 96%);
  --code-fg: hsl(224, 12%, 22%);
  --type: hsl(187, 64%, 27%);        /* return types / emphasized tokens (teal) */
  --sidebar-bg: hsl(224, 22%, 98%);
  --stub: hsl(28, 80%, 40%);
  --authored: hsl(142, 58%, 30%);

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
/* scrollbar-gutter matters specifically because / is one document: switching
   from a long type to a short one changes document height, and without a
   reserved gutter the browser scrollbar appears/disappears and shifts the
   content sideways on every navigation. */
html { -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.7;
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

.skip-link {
  position: absolute; left: -999px; top: 0; padding: .5rem 1rem;
  background: var(--accent); color: #fff; z-index: 100;
}
.skip-link:focus { left: 0; }

/* ── Sidebar ─────────────────────────────────────────────── */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; width: var(--sidebar-w);
  overflow-y: auto; padding: 1.5rem 1rem 3rem;
  background: var(--sidebar-bg); border-right: 1px solid var(--rule-weak);

  /* overscroll-behavior stops a flick past the end of the nav from chaining
     into the document scroll behind it. */
  overscroll-behavior: contain;
}

/* Scrollbar. These two systems do NOT compose. Per spec, a scrollbar-width or
   scrollbar-color of any value other than `auto` OVERRIDES ::-webkit-scrollbar-*
   entirely. An earlier version set `scrollbar-width: thin` alongside a 10px
   webkit thumb, which silently discarded the thumb and left a hit target a few
   pixels wide -- visible, but not reliably clickable on macOS.

   So: mutually exclusive via @supports, and `auto` width, which keeps the grab
   target at the platform's own size. Colors are theme variables, so this follows
   prefers-color-scheme with no extra dark-mode rules.

   Not controllable from CSS: macOS "Show scroll bars" set to "Automatically based
   on mouse or trackpad" gives overlay scrollbars that fade out regardless. If it
   still feels ungrabbable, that setting is the next thing to check. */
@supports (scrollbar-color: auto) {
  .sidebar { scrollbar-width: auto; scrollbar-color: var(--rule) transparent; }
}
@supports not (scrollbar-color: auto) {
  .sidebar::-webkit-scrollbar { width: 12px; }
  .sidebar::-webkit-scrollbar-track { background: transparent; }
  .sidebar::-webkit-scrollbar-thumb {
    background: var(--rule); border-radius: 6px;
    border: 3px solid transparent; background-clip: padding-box;
  }
  .sidebar:hover::-webkit-scrollbar-thumb { background: var(--faint); background-clip: padding-box; }
}
.sidebar-brand { font-weight: 600; font-size: 1.02rem; margin-bottom: 1.5rem; }
.sidebar-brand a { color: var(--heading); }
.nav-group { margin-bottom: .9rem; }
.nav-group-title {
  font-size: .65rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--faint); margin: 0 0 .4rem; font-weight: 600;
}
.nav-group ul { list-style: none; margin: 0; padding: 0; }
.nav-group li { margin: 0; }
.nav-group a {
  display: block; padding: .12rem .55rem; border-radius: 6px;
  color: var(--muted); font-size: .75rem; line-height: 1.45;
}
.nav-group a:hover { color: var(--heading); background: var(--rule-weak); text-decoration: none; }
.nav-group li.active > a { color: var(--accent-strong); background: var(--accent-weak); font-weight: 600; }

/* ── Content ─────────────────────────────────────────────── */
.content {
  margin-left: var(--sidebar-w); padding: 2.5rem 3rem 5rem;
  max-width: calc(var(--sidebar-w) + var(--content-max));
}
.crumb { color: var(--muted); font-size: .8rem; margin: 0 0 .5rem; }
.type-header h1 {
  margin: 0 0 .35rem; font-size: 2.1rem; font-weight: 600;
  line-height: 1.15; letter-spacing: -.012em; color: var(--heading);
}
.tagline { color: var(--muted); font-size: 1.125rem; line-height: 1.5; margin: .35rem 0 .85rem; }
.badges { margin: .35rem 0 2rem; display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.badge {
  display: inline-block; font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; padding: .14rem .5rem; border-radius: 999px;
  background: transparent; border: 1px solid var(--rule);
}
.badge.status-stub { color: var(--stub); }
.badge.status-authored { color: var(--authored); }
.src { font-size: .78rem; color: var(--faint); background: var(--code-bg); padding: .12rem .45rem; border-radius: 4px; }

/* Hide the redundant markdown H1 (the layout header already prints the page title).
   The header's <h1> is nested in .type-header, so this targets only the in-content one —
   which is kept in the source so the pages still read standalone on GitHub. */
.type-page > h1:first-of-type { display: none; }

/* ── Headings ────────────────────────────────────────────── */
h2 {
  margin: 2.75rem 0 1.1rem; padding-bottom: .35rem;
  font-size: 1.5rem; font-weight: 600; line-height: 1.25; color: var(--heading);
  border-bottom: 1px solid var(--rule-weak);
}
h3 { margin: 2rem 0 .65rem; font-size: 1.2rem; font-weight: 600; line-height: 1.3; color: var(--heading); }
h4 { margin: 1.5rem 0 .45rem; font-size: 1rem; font-weight: 600; color: var(--heading); }

p { margin: .9rem 0; }

/* Inline code */
code {
  font-family: var(--mono); font-size: .875em;
  background: var(--code-bg); color: var(--code-fg);
  padding: .12rem .34rem; border-radius: 4px;
}

/* Return types + emphasized tokens (e.g. **null**, **GameObject**) */
strong { color: var(--type); font-weight: 600; }

/* ── API member entries ──────────────────────────────────────
   Each entry is a paragraph that opens with a `signature` code span,
   then a <br>, then the description. No cards — Astro-style, the
   signature earns prominence through weight + contrast, the
   description recedes in body gray, entries part on whitespace. */
.type-page p:has(> code:first-child) { margin: 1.6rem 0; }
.type-page p:has(> code:first-child) > code:first-child {
  background: transparent; padding: 0;
  font-size: 1rem; font-weight: 600; color: var(--heading);
}

/* Example / multi-line code blocks */
pre {
  background: var(--code-bg); border: 1px solid var(--rule-weak); border-radius: 8px;
  padding: 1rem 1.15rem; overflow-x: auto; line-height: 1.55; margin: 1.1rem 0;
}
pre code { background: transparent; padding: 0; font-size: .85rem; color: var(--code-fg); }

/* Tables (used on the audit page) */
/* Wide content must scroll or wrap ITSELF, never widen its container. In the
   single-document build the panels clip horizontally so a swipe is never eaten
   by an inner scroll; that only works if nothing here can overflow unchecked.
   `display: block` makes the table its own scroll container (internal table
   layout still applies via anonymous boxes), so wide API tables pan sideways
   on their own instead of stretching the page. */
table {
  border-collapse: collapse; width: 100%; margin: 1.25rem 0; font-size: .9rem;
  display: block; overflow-x: auto; max-width: 100%;
}
/* Long unbroken tokens -- a 90-odd character signature in inline code -- would
   otherwise push the line box wider than its container. Block code inside <pre>
   is deliberately excluded: it keeps its own horizontal scroll. */
:not(pre) > code { overflow-wrap: break-word; }
pre { max-width: 100%; }
th, td { border: 1px solid var(--rule-weak); padding: .45rem .65rem; text-align: left; }
th { background: var(--sidebar-bg); color: var(--heading); font-weight: 600; }

blockquote {
  margin: 1.25rem 0; padding: .5rem 1rem; color: var(--muted);
  border-left: 3px solid var(--rule); background: var(--sidebar-bg); border-radius: 0 6px 6px 0;
}
hr { border: none; border-top: 1px solid var(--rule-weak); margin: 2.5rem 0; }

.site-footer {
  margin-top: 3.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule-weak);
  color: var(--faint); font-size: .82rem;
}

/* ── Mobile ──────────────────────────────────────────────── */
.nav-toggle {
  display: none; position: fixed; top: .75rem; right: .75rem; z-index: 50;
  font-size: 1.25rem; background: var(--bg); border: 1px solid var(--rule);
  border-radius: 6px; padding: .25rem .6rem; cursor: pointer; color: var(--fg);
}
@media (max-width: 56rem) {
  .nav-toggle { display: block; }
  .sidebar { transform: translateX(-100%); transition: transform .2s ease; z-index: 40; box-shadow: 0 0 30px rgba(0,0,0,.15); }
  body.nav-toggled .sidebar { transform: translateX(0); }
  .content { margin-left: 0; padding: 48px 20px 60px; transition: margin-left .2s ease; }

  /* Code examples wrap instead of scrolling. Measured across all 49 pages:
     780 code lines, median 36 chars, p90 75, max 98 -- against roughly 44 that
     fit a mobile panel. That is 307 lines (39%) overflowing, so a horizontal
     scrollbar would be the normal case, not the exception, and each one is a
     nested horizontal scroller competing with the filmstrip swipe.

     Desktop keeps `overflow-x: auto`: ~122 chars fit there, so the 98-char
     worst case never wraps and alignment is preserved where there is room.

     pre-wrap keeps authored newlines and indentation; only over-long lines
     break. break-word handles single tokens longer than the line box. */
  pre { white-space: pre-wrap; overflow-wrap: break-word; overflow-x: visible; }
  pre code { white-space: inherit; }

  /* Drawer squeezes the content instead of covering it. The sidebar is
     position:fixed so it claims no flow space -- the margin does the work. */
  body.nav-toggled .content { margin-left: var(--sidebar-w); }
}

/* ── Global scale: touch devices only ─────────────────────────────────────
   Deliberately keyed on `pointer: coarse`, NOT on viewport width.

   These two conditions are unrelated and were previously conflated in the
   width breakpoint above, which made a merely-narrow DESKTOP window render at
   30px type -- vast, because desktop never applies the scale this compensates
   for.

   What this compensates for: _layouts/single.html sets a fixed
   `<meta name="viewport" content="width=800">`, so a mobile browser lays out at
   800 CSS px and then downscales to fit the device -- roughly 0.49 on a 390px
   phone, which puts 16px body text near 8px on glass. Desktop browsers ignore
   the viewport meta entirely and render 1:1, so they need none of this.

   `pointer: coarse` reports the PRIMARY input, so a touchscreen laptop driven
   by a trackpad still reads as `fine` and correctly stays unscaled.

   The knob is the root font-size. Nearly every content size in this sheet is
   rem-based, so one value scales headings, tagline, tables, code and body
   together -- do not add per-element mobile sizes here. Media-query rem always
   resolves against the initial 16px, so the 56rem breakpoint above is unaffected
   and this cannot feed back on itself. */
@media (pointer: coarse) {
  html { font-size: 30px; }
  body { font-size: 1rem; }

  /* Excluded from the scale-up: the sidebar. Its width is already right, and
     letting 17rem grow with the root would swallow the screen. Pinned in px and
     sized by hand -- 22px keeps the longest label (SkinnedMeshRenderer, ~209px)
     inside the ~222px of usable width. These are no-ops at a 16px root, so they
     are harmless if this block is ever widened. */
  :root { --sidebar-w: 272px; }
  .sidebar { padding: 24px 16px 48px; }
  .sidebar-brand { font-size: 24px; margin-bottom: 20px; }
  .nav-group { margin-bottom: 14px; }
  .nav-group-title { font-size: 17px; margin: 0 0 6px; }
  .nav-group a { font-size: 22px; line-height: 1.45; padding: 8px 10px; }

  /* Drawer starts OPEN on touch. CSS cannot set a default class, so instead of
     scripting one in, the default state is inverted here and `.nav-toggled`
     means "flipped from this platform's default" rather than "open":

        narrow desktop  default closed -> toggled opens
        touch           default open   -> toggled closes

     The button is unchanged and still reads as a toggle. Doing this in CSS
     rather than with a class on <body> keeps it free of any flash, and keeps a
     merely-narrow desktop window from inheriting a mobile default. */
  .sidebar { transform: translateX(0); }
  .content { margin-left: var(--sidebar-w); }
  body.nav-toggled .sidebar { transform: translateX(-100%); }
  body.nav-toggled .content { margin-left: 0; }
}

/* ── Dark mode (Starlight dark grayscale) ─────────────────── */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: hsl(224, 10%, 10%);
    --fg: hsl(224, 8%, 76%);
    --heading: hsl(0, 0%, 100%);
    --muted: hsl(224, 7%, 58%);
    --faint: hsl(224, 6%, 46%);
    --accent: hsl(224, 100%, 74%);
    --accent-strong: hsl(224, 100%, 83%);
    --accent-weak: hsl(224, 46%, 20%);
    --rule: hsl(224, 10%, 26%);
    --rule-weak: hsl(224, 12%, 17%);
    --code-bg: hsl(224, 14%, 14%);
    --code-fg: hsl(224, 8%, 80%);
    --type: hsl(187, 46%, 62%);
    --sidebar-bg: hsl(224, 12%, 12%);
    --stub: hsl(30, 80%, 64%);
    --authored: hsl(142, 50%, 62%);
  }
}
