/* Layout of the API reference: only vertical rhythm and the two-way split of each section
   (reference | interactive panel). Everything visual comes from the qf-* classes. */

/* Showing/hiding goes through the "hidden" attribute, which the design system's reset already
   handles with [hidden]{display:none!important}: no rule of our own goes here. */

/* No width cap: the two columns split everything. The only thing bounded is the prose
   (.documentation-description__summary), which is what becomes unreadable on long lines. */

/* .qf-shell__side is sized by its content, so the sidebar's background used to cut off at the last
   link. With a viewport min-height and sticky, it always reaches the bottom. */
.documentation-sidebar { min-height: 100vh; }

/* The container of items the toggle collapses. .qf-docsnav__group is already a grid, but it now has
   two children (the toggle and this), so the spacing between links lives here. */
.documentation-docsnav__items {
  display: grid;
  gap: var(--space-xxs);
}

/* Inside the toggle, which already provides its own, .qf-docsnav__grouptitle's margin and padding
   were being doubled. */
.qf-docsnav__toggle .qf-docsnav__grouptitle {
  margin: 0;
  padding: 0;
}

.documentation-page__intro { margin-bottom: var(--space-huge); }

.documentation-page__lead {
  color: var(--text-secondary);
  margin-top: var(--space-md);
}

/* ---------- Endpoint section ---------- */
/* The air between endpoints is padding on both sides of the hairline, not margin: that way the
   separator stays centred in the gap (32px above, 32px below) instead of stuck to the next section. */
.documentation-endpoint-section {
  padding-block: var(--space-xxl);
  border-top: 1px solid var(--border-hairline);
  /* The sidebar's anchor must not leave the title stuck to the window's edge. */
  scroll-margin-top: var(--space-xl);
}

/* The first one has no separator to respect: only the minimum air below the page header. */
.documentation-endpoint-section:first-of-type {
  border-top: 0;
  padding-top: var(--space-lg);
}

/* Reference 2fr and panel 3fr: the panel holds code and video. minmax(0,…) rather than a px
   minimum because the width is already trimmed by the sidebar and a rigid minimum would overflow. */
.documentation-split {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-xxl);
  align-items: start;
}

.documentation-pane {
  display: grid;
  gap: var(--space-xl);
  align-content: start;
  min-width: 0;
}

/* No max-width of its own: .documentation-page already bounds the measure, and a cap here left the
   rest of the 2fr track as dead space. */

/* Below this the two columns are too narrow for a code block: they stack, reference on top and
   panel below. It is also where the shell starts rearranging itself. */
@media (max-width: 1200px) {
  .documentation-split { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Endpoint header ---------- */
.documentation-endpoint {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-md);
}

.documentation-endpoint__path {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  color: var(--text-secondary);
}

/* ---------- Blocks ---------- */
/* A block title (eyebrow) tight to what it titles, and air between blocks. */
.documentation-block {
  display: grid;
  gap: var(--space-md);
  min-width: 0;
}

/* The block's title on the left and its action ("Reset") at the far end, on the same line. */
.documentation-block__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
}

.documentation-eyebrow { color: var(--text-muted); }

/* The "multipart/form-data" note is a note, not part of the title: no small caps. */
.documentation-eyebrow__note { text-transform: none; }

.documentation-description { display: grid; gap: var(--space-xl); }

/* The reference's only measure cap: the summary is running prose and without this it reads in
   lines of 150+ characters. */
.documentation-description__summary {
  color: var(--text-secondary);
  max-width: 72ch;
  text-wrap: pretty;
}

.documentation-description__summary code,
.qf-spec__desc code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  color: var(--code-property);
}

/* ---------- Assistant ---------- */
.documentation-assistant,
.documentation-demo {
  display: grid;
  gap: var(--space-xl);
  min-width: 0;
}

.documentation-assistant__card {
  display: grid;
  gap: var(--space-md);
}

.documentation-assistant__lead { color: var(--text-secondary); }

/* Input and button on one row: the field grows, the button keeps its natural width and both are
   bottom-aligned (the field's label takes an extra line). */
.documentation-ask {
  display: flex;
  align-items: flex-end;
  gap: var(--space-md);
}

.documentation-ask .qf-field { flex: 1; min-width: 0; }

.documentation-result {
  display: grid;
  gap: var(--space-xl);
  min-width: 0;
}

.documentation-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

/* ---------- Live responses of "Try it" ---------- */
.documentation-live {
  display: grid;
  gap: var(--space-lg);
  min-width: 0;
}

/* The StatusDot goes at the far end of the block's bar; .qf-codeblock__name does not push (unlike
   __tabs/__endpoint, which carry their own margin-left:auto). */
.documentation-live .qf-status { margin-left: auto; }

/* .qf-status draws its dot in ::before even with no text: while the step has not started, the
   <span> is empty and must not leave a stray dot floating in the bar. */
.documentation-live .qf-status:empty { display: none; }

/* ---------- Previews ---------- */
/* Code example and media rail on the same row: the code takes the leftover width and the previews
   go in a fixed, narrow column. */
/* The rail's track is declared with :has() and not with an "auto" track: an empty column still
   takes the gap and left the code 24px short of the edge. */
.documentation-workbench {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
}

.documentation-workbench:has(> .documentation-previews) {
  grid-template-columns: minmax(0, 1fr) 200px;
}

/* Where the whole panel already takes the page's width (the two columns stacked), the rail on the
   side leaves the code too narrow: it moves below and stretches. */
@media (max-width: 900px) {
  .documentation-workbench:has(> .documentation-previews) {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The rail is reference material, so it stays compact. The height cap keeps a job with many outputs
   from stretching the row by measuring against the narrow column. */
.documentation-previews {
  display: grid;
  gap: var(--space-md);
  align-content: start;
  min-width: 0;
  max-height: 640px;
  overflow-y: auto;
}

.documentation-preview-group {
  display: grid;
  gap: var(--space-sm);
  align-content: start;
  min-width: 0;
}

/* One MediaPreview per file, stacked. */
.documentation-media {
  display: grid;
  gap: var(--space-sm);
  align-content: start;
  min-width: 0;
}

.documentation-media video,
.documentation-media audio { width: 100%; }

/* .qf-media__img crops with object-fit:cover, right for a video frame but not for a logo: here the
   inputs can be anything and they are shown whole. */
.documentation-media .qf-media__img { object-fit: contain; }

/* A <video> with no metadata loaded is 300px by default and that size bubbled up the whole chain
   until it stretched the card out of the rail. It is stopped by fixing tracks at every link. */
.documentation-media .qf-media,
.documentation-media .qf-media__stage,
.documentation-media .qf-media__bar,
.documentation-media .qf-media__name { min-width: 0; }

.documentation-media .qf-media__stage { grid-template-columns: minmax(0, 1fr); }

/* .qf-media is a <figure> and the user agent gives it 40px of margin on each side: in a 200px rail
   the cards ended up 120 wide. The air between cards comes from the gap. */
.documentation-media .qf-media { margin: 0; }

/* The placeholder's stage is not tied to 16:9: at 200px wide the text does not fit in the 112px of
   height that ratio leaves, and it was cut in half. */
.documentation-media__stage--empty { min-height: 96px; }

/* The <audio> has no aspect ratio of its own: its stage fits the control, not 16:9. */
.documentation-media__stage--audio { padding: var(--space-md); }

/* ---------- Result explanation ---------- */
/* base.css zeroes the margin of every h* and p, so the rhythm goes here: an eyebrow is the title of
   what follows, so it has to sit tight below and separated above. */
.documentation-explanation__body { margin-top: var(--space-lg); }

/* Air between blocks: paragraph → flag list → next eyebrow. */
.documentation-explanation__body > * + * { margin-top: var(--space-xl); }

/* Exception: what follows an eyebrow is precisely what that eyebrow titles. They are separated by
   the margin-bottom the design system's own .qf-card__eyebrow already carries, not by this margin. */
.documentation-explanation__body > .qf-card__eyebrow + * { margin-top: 0; }

/* ---------- Editable body of the cURL example ---------- */
/* The contenteditable <span> inside the code block; the invalid state reuses the inputs' error
   border token, so no colour is invented. */
.editable-json {
  outline: none;
  border-bottom: 1px dashed var(--border-input);
}

.editable-json:focus { border-bottom-color: var(--border-input-focus); }

.editable-json--invalid { border-bottom-color: var(--border-input-error); }

/* The confirmation after a successful "Try it" now comes from the design system as
   .qf-codeblock--flash-success. */
