/* ==========================================================================
   Tical docs — three-column reference layout.

   Loaded only by /sdk, on top of tical.css. Every colour, easing and radius
   here comes from the :root tokens in tical.css; this file adds no new ones.

   Deliberately NOT in tical.css: the landing page has no reason to download
   2 kB of sidebar rules, and tical.css is already 2000 lines.
   ========================================================================== */

/* ==========================================================================
   Shell
   ========================================================================== */

/* Wider than .container (1200px) — three columns need the room. */
.docs-shell {
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  padding: 0 1.5rem 5rem;
  display: grid;
  grid-template-columns: 15.5rem minmax(0, 1fr) 13.5rem;
  gap: 0 3rem;
  align-items: start;
}

/* ==========================================================================
   Left sidebar — grouped section links
   ========================================================================== */

/* The rail is the height budget; it does not scroll. It caps at the viewport, lays its two
   children out in a column - the search panel, then the list - and the list is the only thing
   that scrolls. That split is the whole design of this column and it is worth stating plainly:
   the panel sits OUTSIDE the scrollport, so nothing ever passes behind it. It needs no sticky
   positioning of its own, no z-index, no opaque fill to mask what is moving under it, and no
   fade at the join, because there is no join. Everything this file used to carry to make a box
   inside a scroller look like it was above the scroller went out with it. */
.docs-nav {
  position: sticky;
  top: calc(var(--header-h) + 1.5rem);
  max-height: calc(100vh - var(--header-h) - 3rem);
  display: flex;
  flex-direction: column;
  padding: 2.5rem 0 2rem;
  font-size: .875rem;
}

/* The scrollport. min-height: 0 is what lets a flex child shrink below its content and scroll at
   all - without it the list keeps its full height and pushes the rail past the fold instead of
   scrolling inside it. The right padding is here rather than on .docs-nav so that it sits
   between the links and their own scrollbar.

   The mask is what keeps a link from being cut in half on its way out of the top of the list -
   it dims out over its own height instead. It is on the scrollport rather than on anything above
   it, so it cannot be out of register with the panel the way a separate element under the panel
   was; a mask is painted against the element's own box and does not travel with the content.
   The padding-top is the half of this that makes it free: it is the same 1rem the mask fades
   over, so at rest the fade is over blank padding and the first label below it is untouched, and
   there is nothing to switch on and off as the list scrolls. Keep the two numbers equal, and
   keep their sum with .docs-search's margin-bottom at the 1.25rem gap the column is drawn to. */
.docs-nav > nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-top: 1rem;
  padding-right: .5rem;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 1rem);
  mask-image: linear-gradient(to bottom, transparent 0, #000 1rem);
}

.docs-nav-group + .docs-nav-group { margin-top: 1.5rem; }

.docs-nav-group > span {
  display: block;
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: .5rem;
  padding-left: .85rem;
}

.docs-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  /* The rail the active marker slides along. */
  border-left: 1px solid var(--border);
}

.docs-nav a {
  display: block;
  position: relative;
  padding: .35rem .75rem .35rem .85rem;
  color: var(--text-dim);
  font-size: .855rem;
  line-height: 1.45;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  transition: color var(--t-fast) var(--e-out),
              background-color var(--t-fast) var(--e-out);
}
.docs-nav a::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 50%;
  width: 2px;
  height: 0;
  background: var(--accent);
  transform: translateY(-50%);
  transition: height var(--t-base) var(--e-out);
}
.docs-nav a:hover { color: var(--text); background: rgb(255 255 255 / .03); }
.docs-nav a[aria-current="true"] { color: var(--accent); font-weight: 600; }
.docs-nav a[aria-current="true"]::before { height: 100%; }

/* ==========================================================================
   Right rail — "On this page"
   ========================================================================== */

.docs-toc {
  position: sticky;
  top: calc(var(--header-h) + 1.5rem);
  max-height: calc(100vh - var(--header-h) - 3rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2.5rem 0 2rem;
  font-size: .8125rem;
}

.docs-toc-title {
  display: block;
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: .65rem;
}

.docs-toc ul { list-style: none; margin: 0; padding: 0; }
.docs-toc a {
  display: block;
  padding: .25rem 0;
  color: var(--text-faint);
  line-height: 1.4;
  transition: color var(--t-fast) var(--e-out);
}
.docs-toc a:hover { color: var(--text-dim); }
.docs-toc a.is-active { color: var(--accent); }

/* ==========================================================================
   Content column
   ========================================================================== */

.docs-body {
  /* Measure, not width — long API signatures still get the full column via
     their own overflow containers. */
  max-width: 46rem;
  padding: 2.5rem 0 0;
  min-width: 0;
}

.docs-body > p,
.docs-body > ul,
.docs-body > ol { color: var(--text-dim); }

.docs-body h1 {
  /* The global h1 clamps up to 4.5rem, which is a hero size, not a doc title. */
  font-size: clamp(2rem, 4vw, 2.6rem);
  margin-bottom: .75rem;
}
.docs-body h2 {
  font-size: clamp(1.5rem, 2.6vw, 1.9rem);
  margin: 4rem 0 1rem;
  padding-top: 2rem;
  border-top: 1px solid var(--border);
}
.docs-body h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 3rem; }
.docs-body h3 {
  font-size: 1.125rem;
  margin: 2.5rem 0 .85rem;
  color: var(--text);
}
.docs-body h4 {
  font-family: var(--font-mono);
  font-size: .95rem;
  margin: 1.75rem 0 .6rem;
  color: var(--text);
}

.docs-lede {
  font-size: 1.075rem;
  line-height: 1.6;
  color: var(--text-dim);
  margin-bottom: 2rem;
}

.docs-body ul, .docs-body ol { padding-left: 1.25rem; }
.docs-body li { margin-bottom: .4rem; }
.docs-body li::marker { color: var(--text-faint); }

/* Heading anchors — the "#" that appears on hover. */
.anchor {
  margin-left: .5rem;
  color: var(--text-faint);
  font-weight: 400;
  opacity: 0;
  transition: opacity var(--t-fast) var(--e-out), color var(--t-fast) var(--e-out);
}
h2:hover > .anchor,
h3:hover > .anchor,
.anchor:focus-visible { opacity: 1; }
.anchor:hover { color: var(--accent); }

/* ==========================================================================
   API reference entries
   ========================================================================== */

.api-group {
  font-family: var(--font-mono) !important;
  font-size: .72rem !important;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 2rem 0 .75rem !important;
}

.api-list { border-top: 1px solid var(--border); }

.api-item {
  padding: 1rem 0 1rem 1rem;
  border-bottom: 1px solid var(--border);
  border-left: 2px solid transparent;
  transition: border-color var(--t-fast) var(--e-out),
              background-color var(--t-fast) var(--e-out);
}
.api-item:hover { border-left-color: var(--border-strong); background: rgb(255 255 255 / .014); }
/* Deep-linked member lights up so you can see what you landed on. */
.api-item:target { border-left-color: var(--accent); background: rgb(163 230 53 / .045); }

.api-sig {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem .75rem;
  margin-bottom: .4rem;
}

.api-name {
  font-family: var(--font-mono);
  font-size: .9rem;
  font-weight: 600;
  color: var(--accent);
  word-break: break-word;
}

.api-type {
  font-family: var(--font-mono);
  font-size: .8rem;
  color: var(--text-dim);
  /* Generic signatures get long; let them scroll rather than the page. */
  max-width: 100%;
  overflow-x: auto;
  white-space: nowrap;
}

.api-item > p {
  margin: 0;
  font-size: .9rem;
  line-height: 1.6;
  color: var(--text-dim);
}
.api-item > p + p { margin-top: .5rem; }

.api-badge {
  display: inline-block;
  padding: .1rem .45rem;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: .65rem;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: lowercase;
  white-space: nowrap;
}
.api-req      { background: rgb(163 230 53 / .12); color: var(--accent);     border-color: rgb(163 230 53 / .3); }
.api-opt      { background: rgb(148 163 184 / .1); color: var(--text-dim);   border-color: rgb(148 163 184 / .22); }
.api-abstract { background: rgb(251 191 36 / .1);  color: var(--warn);       border-color: rgb(251 191 36 / .28); }
.api-virtual  { background: rgb(56 189 248 / .1);  color: #7dd3fc;           border-color: rgb(56 189 248 / .26); }
.api-static   { background: rgb(167 139 250 / .1); color: #c4b5fd;           border-color: rgb(167 139 250 / .26); }
.api-default  { background: rgb(148 163 184 / .07); color: var(--text-faint); border-color: rgb(148 163 184 / .18); }

/* ==========================================================================
   Type signature banner — the declaration line above a type's members
   ========================================================================== */

.api-decl {
  margin: 0 0 1.25rem;
  padding: .8rem 1rem;
  background: var(--n-950);
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-sm);
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: .8125rem;
  line-height: 1.6;
  color: var(--text-dim);
  white-space: pre;
}

.api-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: -.5rem 0 1.25rem;
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--text-faint);
}
.api-meta span { padding: .1rem .5rem; border: 1px solid var(--border); border-radius: var(--r-pill); }

/* ==========================================================================
   Code blocks — .code / .code-head come from tical.css; this adds the copy
   button and the docs-specific spacing.
   ========================================================================== */

.docs-body .code-head {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: 1.25rem;
}
.docs-body .code { margin-bottom: 1.25rem; }

.code-copy {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: .15rem .55rem;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--t-fast) var(--e-out),
              border-color var(--t-fast) var(--e-out);
}
.code-copy:hover { color: var(--accent); border-color: var(--border-strong); }

/* A code block with no filename header still gets breathing room. */
.docs-body > .code { margin-top: 1.25rem; }

/* ==========================================================================
   Docs-local helpers
   ========================================================================== */

.docs-body .callout { margin: 1.5rem 0; }
.docs-body .table-wrap { margin: 1.5rem 0; }
.docs-body .slotmap { margin: 1.5rem 0; }

/* Two-up cards for "which base class do I want" style comparisons. */
.docs-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
  margin: 1.5rem 0;
}
.docs-split > div {
  padding: 1rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-size: .875rem;
  color: var(--text-dim);
}
.docs-split h4 { margin-top: 0 !important; }

/* Card titles inside .docs-split. They used to be <h4> sitting above the first <h2> on the
   page, which opened /sdk with an h1 -> h4 jump in the outline. They label the two halves of a
   comparison rather than open a section, so they are not headings any more. Same type as
   .docs-body h4 on purpose - this was a rename, not a restyle. docs.js only ever collected
   h3[id], so nothing in the table of contents or the scrollspy changed. */
.docs-split-title {
  font-family: var(--font-mono);
  font-size: .95rem;
  margin: 0 0 .6rem;
  color: var(--text);
}

/* Alphabetical type index. */
.docs-index { font-size: .85rem; }
.docs-index td:first-child { font-family: var(--font-mono); white-space: nowrap; }

/* ==========================================================================
   Sidebar toggle — hidden until the drawer breakpoint
   ========================================================================== */

.docs-nav-toggle {
  display: none;
  position: sticky;
  top: var(--header-h);
  z-index: 900;
  width: 100%;
  align-items: center;
  gap: .5rem;
  padding: .75rem 0;
  background: rgb(10 10 10 / .92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 0;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
.docs-nav-toggle svg { transition: transform var(--t-base) var(--e-out); }
.docs-nav-toggle[aria-expanded="true"] svg { transform: rotate(90deg); }

/* ==========================================================================
   Responsive

   1180px — the right rail is the first thing to go; it is pure convenience.
   1024px — the left sidebar becomes a collapsible drawer.
   ========================================================================== */

@media (max-width: 1180px) {
  .docs-shell { grid-template-columns: 15rem minmax(0, 1fr); gap: 0 2.5rem; }
  .docs-toc { display: none; }
}

@media (max-width: 1024px) {
  .docs-nav-toggle { display: flex; }

  .docs-shell { grid-template-columns: minmax(0, 1fr); }

  .docs-nav {
    position: static;
    max-height: none;
    padding: 0 0 1.5rem;
    border-bottom: 1px solid var(--border);
    /* Collapsed by default; .is-open reveals it. Uses the same clip+fade as
       the site nav so the two drawers feel like one mechanism. */
    display: none;
  }
  .docs-nav.is-open { display: block; }

  /* The whole drawer moves with the page here, so the list gives its scrollport back and simply
     runs to its full height. */
  .docs-nav > nav {
    overflow: visible;
    padding-top: 0;
    padding-right: 0;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .docs-body { max-width: none; padding-top: 2rem; }
}

@media (max-width: 560px) {
  .docs-shell { padding-left: 1.15rem; padding-right: 1.15rem; }
  .api-item { padding-left: .75rem; }
}

/* ==========================================================================
   Sidebar search — the filter box, and the button that opens the palette
   ========================================================================== */

/* First child of .docs-nav and not part of the scrollport below it, so it stays put with no
   help: no sticky, no z-index, nothing under it to mask. What it does still need is a fill that
   belongs to this page - the earlier version of this box was `background: var(--bg)`, a flat
   #0a0a0a rectangle, and the page is not --bg: .bg-fx paints fixed aurora blobs and a drifting
   grid behind everything, so that read as a hole punched in the background rather than as part
   of the sidebar. Translucent over a backdrop blur keeps the aurora's colour underneath, and the
   border and radius are the ones the cards in .docs-split use. */
.docs-search {
  margin-bottom: .25rem;
  padding: .6rem .65rem .65rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: rgb(23 23 23 / .82);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
}

.docs-filter { font-size: .8125rem; padding: .5rem .7rem; }

/* type=search paints a browser clear button that does not match anything else here. */
.docs-filter::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.docs-filter-empty {
  margin: .5rem 0 0;
  font-size: .75rem;
  line-height: 1.45;
  color: var(--text-faint);
}

.docs-jump {
  display: flex;
  align-items: center;
  gap: .45rem;
  width: 100%;
  margin-top: .5rem;
  padding: .45rem .6rem;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-faint);
  font-family: var(--font-sans);
  font-size: .78rem;
  text-align: left;
  cursor: pointer;
  transition: color var(--t-fast) var(--e-out), border-color var(--t-fast) var(--e-out);
}
.docs-jump:hover { color: var(--text); border-color: var(--border-strong); }
.docs-jump kbd { margin-left: auto; }

/* Shared by the button and the palette's footer. */
.docs-jump kbd,
.palette-foot kbd {
  display: inline-block;
  min-width: 1.35em;
  padding: .05em .35em;
  border: 1px solid var(--border-strong);
  border-radius: .3rem;
  background: var(--n-950);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: .72em;
  line-height: 1.5;
  text-align: center;
}

/* ==========================================================================
   Jump-to-member palette

   The chrome (backdrop, panel, fade, focus trap) is .modal-backdrop/.modal from tical.css,
   driven by modal() in motion.js. Everything here is the difference between a dialog and a
   palette: it sits near the top of the viewport rather than centred, because the list grows
   downward and a vertically-centred one would walk up the screen as you type.
   ========================================================================== */

.palette-backdrop {
  align-items: start;
  padding-top: clamp(3rem, 12vh, 8rem);
}

.palette {
  max-width: 40rem;
  padding: 1rem;
}

.palette-input {
  font-size: .9rem;
  padding: .7rem .85rem;
}

.palette-list {
  list-style: none;
  margin: .75rem 0 0;
  padding: 0;
  /* Capped so the panel cannot outgrow a short viewport; the list scrolls inside it. */
  max-height: min(24rem, 50vh);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.palette-list:empty { display: none; }

/* One row, one line, always. A few .api-name cells document several members at once
   ("OnAppStartedAsync · OnActivatedAsync · …") and wrapping one of those turned a row four
   lines tall and pushed the type column under the section label. A palette is a list to scan,
   so the row is nowrap and whatever does not fit is elided. */
.palette-item {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  flex-wrap: nowrap;
  padding: .45rem .6rem;
  border-radius: var(--r-sm);
  cursor: pointer;
  scroll-margin: .5rem;
}
/* One highlight, moved by the arrow keys, and the mouse writes to the same class rather than
   having a :hover of its own — two competing highlights in one list is the thing that makes a
   palette feel broken. */
.palette-item.is-active { background: rgb(163 230 53 / .1); }

.palette-name {
  /* min-width:0 is what lets a flex item shrink below its content and ellipsis at all. */
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: .85rem;
  color: var(--text);
}

/* .api-type is shared with the reference body, where it is allowed its own sideways scroll.
   Inside a palette row that would be a scrollbar per result, so it elides here instead and
   yields to the name, which is what is being searched for. */
.palette-item .api-type {
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
}
.palette-item.is-active .palette-name { color: var(--accent); }

.palette-in {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: .7rem;
  color: var(--text-faint);
  white-space: nowrap;
}

.palette-empty {
  margin: .9rem .6rem .3rem;
  font-size: .85rem;
  color: var(--text-faint);
}

.palette-foot {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem 1rem;
  margin: .85rem 0 0;
  padding-top: .75rem;
  border-top: 1px solid var(--border);
  font-size: .72rem;
  color: var(--text-faint);
}
.palette-foot span { display: inline-flex; align-items: center; gap: .3rem; }
