/* apidoc.css -- styles for the HotCRP API reference generated by
   batch/apidoc.php. Resembles the Scalar API reference, but is plain CSS you
   can edit directly: a fixed sidebar of operations, a scrolling content
   column, colored method badges, and an optional examples column toggled by
   the floating button (see #toggle-examples / body.examples-visible). */

:root {
    --font: system-ui, "Segoe UI", Helvetica, Arial, sans-serif;
    --font-prose: "Yrsa", Georgia, "Times New Roman", serif;
    --font-code: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", monospace;
    --sidebar-width: 300px;

    --accent: #0090cc;
    --bg: #ffffff;
    --bg-soft: #f6f8fa;
    --bg-code: #f3f5f7;
    --fg: #1c2024;
    --fg-soft: #5a6570;
    --border: #e2e6ea;

    --m-get: #0a7d40;
    --m-post: #0090cc;
    --m-put: #b7791f;
    --m-delete: #c0392b;
    --m-patch: #7c5fbf;

    --featured-star: #f5b301;
    --default-pill: #14b8a6;
}

@media (prefers-color-scheme: dark) {
    :root {
        --accent: #2cb8f5;
        --bg: #14171a;
        --bg-soft: #1c2024;
        --bg-code: #1f2429;
        --fg: #e6e9ec;
        --fg-soft: #97a1ab;
        --border: #2b3138;
        --default-pill: #2dd4bf;
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    display: grid;
    grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.55;
    color: var(--fg);
    background: var(--bg);
}

code, pre { font-family: var(--font-code); }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- Sidebar ---- */

.sidebar {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    overflow-y: auto;
    padding: 20px 16px 40px;
    border-right: 1px solid var(--border);
    background: var(--bg-soft);
}
.sidebar-head { margin-bottom: 14px; }
.sidebar-title { font-weight: 650; font-size: 16px; }
.sidebar-version { font-size: 12px; color: var(--fg-soft); }

#nav-filter {
    width: 100%;
    padding: 6px 10px;
    margin-bottom: 14px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg);
    color: var(--fg);
    font: inherit;
    font-size: 13px;
}

.nav-intro { display: block; padding: 4px 8px; font-weight: 550; }

.nav-group { margin-top: 12px; }
.nav-group-title {
    display: block;
    padding: 4px 8px;
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--fg-soft);
}
.nav-group ul { list-style: none; margin: 2px 0 0; padding: 0; }
.nav-op {
    position: relative;
    display: flex;
    align-items: baseline;
    gap: 7px;
    padding: 3px 8px;
    border-radius: 6px;
    color: var(--fg);
}
.nav-op:hover { text-decoration: none; }
.nav-op:hover .nav-op-label { text-decoration: underline; }
.nav-op.active,
.nav-intro.active { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.nav-op-label {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Sidebar method label: abbreviated colored text (no pill), pushed to the
   right end of the line by the flexible label to its left. */
.nav-method {
    flex: none;
    text-align: right;
    font-family: var(--font-code);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .03em;
}
.nav-method-get { color: var(--m-get); }
.nav-method-post { color: var(--m-post); }
.nav-method-put { color: var(--m-put); }
.nav-method-delete { color: var(--m-delete); }
.nav-method-patch { color: var(--m-patch); }

/* ---- Method badges ---- */

.method {
    flex: none;
    display: inline-block;
    min-width: 44px;
    padding: 1px 6px;
    border-radius: 5px;
    font-family: var(--font-code);
    font-size: 10px;
    font-weight: 700;
    text-align: center;
    letter-spacing: .03em;
    color: #fff;
}
.method-get { background: var(--m-get); }
.method-post { background: var(--m-post); }
.method-put { background: var(--m-put); }
.method-delete { background: var(--m-delete); }
.method-patch { background: var(--m-patch); }

/* ---- Content ---- */

.content {
    min-width: 0;
    padding: 36px 44px 120px;
    max-width: 1180px;
}

.intro h1 { margin-top: 0; font-size: 30px; }
.intro-summary { font-size: 17px; color: var(--fg-soft); }

.prose, .op-desc {
    font-family: var(--font-prose);
    font-size: 16px;
}
.prose :is(h1, h2, h3, h4, h5, h6),
.op-desc :is(h1, h2, h3, h4, h5, h6) { font-family: var(--font); line-height: 1.25; }
/* Prose subsection headings. Description fragments are re-leveled on render so
   their shallowest heading is <h3> (one below the <h2> tag/operation heading). */
.prose h3, .op-desc h3 { font-size: 18px; margin: 1.4em 0 .4em; }
.prose h4, .op-desc h4 { font-size: 15px; margin: 1.25em 0 .3em; }
.prose :is(h5, h6), .op-desc :is(h5, h6) { font-size: 13px; margin: 1.1em 0 .3em; }
.prose :is(pre, code),
.op-desc :is(pre, code) { font-family: var(--font-code); font-size: .85em; }

/* Visible to assistive tech only: distinguishes a section heading (e.g. a tag
   category) from a same-ranked operation heading in a screen reader's heading list. */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip: rect(0 0 0 0); clip-path: inset(50%);
    overflow: hidden; white-space: nowrap;
}

pre {
    overflow-x: auto;
    padding: 12px 14px;
    border-radius: 8px;
    background: var(--bg-code);
    font-size: 12.5px;
    line-height: 1.5;
}
:not(pre) > code {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--bg-code);
    font-size: .88em;
}

.tag-section { margin-top: 48px; padding-top: 8px; }
/* Section-level headings: tag categories, the introduction, and the auth block.
   All are <h2>; operation titles (also <h2>) are styled separately and smaller. */
.tag-section > h2,
.intro > h2,
.auth-block > h2 {
    margin: 0 0 4px;
    padding-bottom: 6px;
    font-size: 22px;
    border-bottom: 2px solid var(--border);
}
.intro > h2 { margin-top: 32px; }

.auth-block { margin-top: 32px; }

/* ---- Tag documentation sections ---- */
/* Standalone prose subsections of a tag (e.g. "The submission object"): peers
   of operations (both <h2>), separated by a rule like operations, but rendered
   as full-width prose rather than the two-column operation layout. */
.doc-section {
    margin: 28px 0;
    padding-top: 24px;
    border-top: 1px solid var(--border);
    scroll-margin-top: 16px;
}
.doc-section > h2.doc-section-heading {
    margin: 0 0 8px;
    font-size: 22px;
}
.doc-section-summary {
    margin: 0 0 12px;
    color: var(--fg-soft);
    font-size: 15px;
}

/* ---- Operations ---- */

.operation {
    margin: 28px 0;
    padding-top: 24px;
    border-top: 1px solid var(--border);
    scroll-margin-top: 16px;
}
.op-main {
    display: grid;
    grid-template-columns: 1fr;
    gap: 28px;
}
.op-head { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 6px; }
.op-path { font-size: 14px; color: var(--fg); word-break: break-all; }
/* Permalink button: appears in the column's left margin when the op-head
   (method/path/title row) is hovered. Sized to the first line so the glyph
   lines up with the method badge even though the title now shares op-head. */
.op-anchor {
    position: absolute;
    right: 100%;
    margin-right: 9px;
    top: 0;
    height: 1.5em;
    display: flex;
    align-items: center;
    color: var(--fg-soft);
    opacity: 0;
    transition: opacity .1s;
}
.op-head:hover .op-anchor,
.op-anchor:focus-visible { opacity: 1; }
.op-anchor:hover { color: var(--accent); }
/* x-badges (e.g. "Admin only"). Echoes the method badge's shape and code font,
   but outlined and not upper-cased. Optional --badge-color set inline per badge. */
.op-badge {
    padding: 1px 6px;
    border-radius: 5px;
    border: 1px solid var(--badge-color, var(--border));
    color: var(--badge-color, var(--fg-soft));
    font-family: var(--font);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .03em;
}
/* `[default VALUE]` pill: reuses the `.op-badge` shape but tinted a light
   green-blue so it reads as informational rather than as a permission badge.
   The "default" label is set in the UI font and italicized; the value keeps a
   bold code font so it reads as a literal value. */
.prop-default {
    border-color: color-mix(in srgb, var(--default-pill) 30%, var(--border));
    background: color-mix(in srgb, var(--default-pill) 5%, transparent);
}
.prop-default-label {
    font-style: italic;
    font-weight: 400;
    letter-spacing: 0;
    margin-right: 2px;
}
.prop-default-val { font-family: var(--font-code); }
/* Featured star (`* badge featured`): the most external/stable calls. A yellow
   five-pointed star, drawn bare (no pill). In the main column it follows the
   method and path, before any other badges; in the sidebar a smaller star hangs
   in the left gutter, ahead of the operation, so labels stay aligned. */
.featured-star {
    flex: none;
    color: var(--featured-star);
    line-height: 1;
}
.featured-star-op { font-size: 19px; }
.featured-star-nav {
    position: absolute;
    right: calc(100% - 4px);
    top: 50%;
    transform: translateY(-50%);
    font-size: 11px;
}

.op-head > h2.op-title { flex-basis: 100%; margin: 5px 0 0; font-size: 19px; }
.op-section { margin-top: 20px; }
.op-section > h3 {
    margin: 0 0 8px;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--fg-soft);
}
/* Unobtrusive note: the endpoint accepts/returns values beyond those listed. */
.op-extra {
    margin-top: 8px;
    font-size: 13px;
    font-style: italic;
    color: var(--fg-soft);
}
.op-extra::before { content: "+ "; font-style: normal; }
/* Property trees */
.props { list-style: none; margin: 0; padding: 0; }
/* Open child attributes are boxed in a silver rounded border. The extra
   left padding gives the hanging required asterisk room. */
.children > .props {
    margin: 6px 0 4px;
    padding: 2px 12px 2px 18px;
    border: 1px solid var(--border);
    border-radius: 6px;
}
.props > li { padding: 6px 0; }
.props > li + li { border-top: 1px solid var(--border); }
.prop { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.prop-id { position: relative; }
.prop-prefix { font-family: var(--font-code); font-size: 13px; color: var(--fg-soft); }
.prop-name { font-family: var(--font-code); font-size: 13px; font-weight: 600; }
/* Required marker: a red asterisk that hangs in the gutter to the left of the
   name, so names stay aligned whether or not they are required. */
.prop-id.req::before {
    content: "*";
    position: absolute;
    right: 100%;
    margin-right: 3px;
    color: var(--m-delete);
    font-weight: 700;
}
.prop-type { font-family: var(--font-code); font-size: 12px; color: var(--accent); }
/* A condition value (e.g. `format=csv`) shown as a code pill, distinct from the
   outlined `.op-badge` metadata pills. */
.prop-cond {
    padding: 0 5px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    color: var(--accent);
    font-family: var(--font-code);
    font-size: 11px;
    white-space: nowrap;
    width: fit-content;
}
/* "if <cond> and <cond>" label; "if"/"and" are connective words in the UI font,
   each condition is a code pill. */
.prop-cond-if { font-size: 12px; color: var(--fg-soft); }
.prop-cond-if em, .prop-cond-and { font-style: italic; }
/* Subtle "Body parameter" hint after a parameter's first description paragraph:
   best sent in the request body, though the query string also works. */
.param-body {
    display: inline-block;
    margin-left: 5px;
    padding: 0 7px;
    border-radius: 999px;
    background: var(--bg-soft);
    color: var(--fg-soft);
    font-family: var(--font);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
    vertical-align: baseline;
}
/* A run of fields sharing a condition, drawn as a fieldset: the "if <cond>"
   label straddles the top edge of a rounded, slightly blue border, inset from
   the left. The `.props > li.prop-cond-group` selector outranks the base
   `.props > li` padding/border rules so the box keeps its own border and inset. */
.props > li.prop-cond-group {
    position: relative;
    margin: 16px 0;
    padding: 10px 12px 2px;
    border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
    border-radius: 5px;
}
.prop-cond-group > .props { margin: 0; padding: 0; border: 0; }
/* The label sits on the top border; its background masks only the bit of border
   directly behind it (width: max-content), not the whole edge. */
.prop-cond-label {
    position: absolute;
    top: 0;
    left: 12px;
    width: max-content;
    transform: translateY(-50%);
    padding: 0 4px;
    background: var(--bg);
}
/* A non-group row after a box needs no separator; another box keeps its own
   border (so don't zero a group that follows a group). */
.props > li.prop-cond-group + li:not(.prop-cond-group) { border-top: 0; }
/* Extra breathing room between two adjacent condition boxes. */
.props > li.prop-cond-group + li.prop-cond-group { margin-top: 28px; }
/* "one of": a set of mutually-exclusive parameters, drawn like the condition
   fieldset (above) but labelled "one of". A blue rule separates the
   alternatives; the box implies the set as a whole is required. */
.props > li.prop-oneof-group {
    position: relative;
    margin: 16px 0;
    padding: 10px 12px 2px;
    border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
    border-radius: 5px;
}
.prop-oneof-group > .props { margin: 0; padding: 0; border: 0; }
.prop-oneof-label {
    position: absolute;
    top: 0;
    left: 12px;
    width: max-content;
    transform: translateY(-50%);
    padding: 0 4px;
    background: var(--bg);
    font-size: 12px;
    color: var(--fg-soft);
}
.prop-oneof-label em { font-style: italic; }
/* Each alternative after the first is separated by a rule matching the box
   border, pulled out with negative side margins so it meets the border, and
   labelled "or" the way the box itself is labelled "one of". */
.prop-oneof-group > .props > li.prop-oneof-sep {
    position: relative;
    margin: 12px -12px 0;
    padding: 12px 12px 6px;
    border-top: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
}
.prop-oneof-group > .props > li.prop-oneof-sep::before {
    content: "or";
    position: absolute;
    top: 0;
    left: 12px;
    transform: translateY(-50%);
    padding: 0 4px;
    background: var(--bg);
    font-style: italic;
    font-size: 12px;
    color: var(--fg-soft);
}
/* The group's own border sets it off from the next row; suppress the default
   row divider that would otherwise follow it. */
.props > li.prop-oneof-group + li:not(.prop-oneof-group) { border-top: 0; }
/* An ad-hoc `* group`: consecutive fields drawn in the same fieldset as the
   condition box, but titled with a plain label rather than an "if <cond>". */
.props > li.prop-group {
    position: relative;
    margin: 16px 0;
    padding: 10px 12px 2px;
    border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
    border-radius: 5px;
}
.prop-group > .props { margin: 0; padding: 0; border: 0; }
.prop-group-label {
    position: absolute;
    top: 0;
    left: 12px;
    width: max-content;
    transform: translateY(-50%);
    padding: 0 4px;
    background: var(--bg);
    font-size: 12px;
    color: var(--fg-soft);
}
.props > li.prop-group + li:not(.prop-group) { border-top: 0; }
.props > li.prop-group + li.prop-group { margin-top: 28px; }
/* Property/parameter descriptions, dimmed so the field names stay prominent.
   The first paragraph (the summary) sits flush with the field; any longer
   expansion below it is indented so the field list above stays scannable. */
.prop-desc { font-family: var(--font-prose); font-size: 14.5px; color: var(--fg-soft); margin: 2px 0; }
.prop-desc > :first-child { margin-top: 0; }
.prop-desc > :last-child { margin-bottom: 0; }
.prop-desc > :not(:first-child) { margin-left: 14px; }
.prop-desc p { margin: .55em 0; }
.prop-desc ul, .prop-desc ol { margin: .55em 0; padding-left: 1.4em; }
.prop-desc pre { margin: .55em 0; }
.prop-desc :not(pre) > code { font-size: .85em; }
/* Enum/constant values: grey code pills, bar-separated when there are several. */
.enum-val {
    padding: 0 5px;
    border-radius: 4px;
    background: var(--bg-code);
    color: var(--fg);
}
.enum-bar { color: var(--fg-soft); }
/* A response media type (shown only for non-JSON or multi-type responses). */
.returns-content { display: flex; align-items: baseline; gap: 8px; margin: 4px 0; }
.returns-ct { font-family: var(--font-code); font-size: 12px; color: var(--fg-soft); }

/* Collapsible nested-object attributes. The summary text toggles between its
   "show" and "hide" forms via the [open] state, so no JavaScript is needed. */
.children { margin: 5px 0 2px; }
.children > summary {
    list-style: none;
    display: inline-block;
    cursor: pointer;
    font-size: 12px;
    color: var(--accent);
    user-select: none;
}
.children > summary::-webkit-details-marker { display: none; }
.children > summary:hover { text-decoration: underline; }
.children > summary .hide { display: none; }
.children[open] > summary .show { display: none; }
.children[open] > summary .hide { display: inline; }

/* ---- Examples column ---- */

.op-examples { display: none; }
.example-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--fg-soft);
    margin: 0 0 6px;
}
.example-label + .example-code { margin-bottom: 16px; }
.example-code { white-space: pre; }

body.examples-visible .op-examples { display: block; }
@media (min-width: 1100px) {
    body.examples-visible .op-main {
        grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    }
    body.examples-visible .op-examples {
        position: sticky;
        top: 16px;
        align-self: start;
    }
}

/* ---- Examples toggle button ---- */

/* Default ("Show examples"): solid blue, so it stands out as a call to action. */
#toggle-examples {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 50;
    padding: 7px 14px;
    border: 1px solid var(--accent);
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font: 500 13px/1 var(--font);
    box-shadow: 0 1px 4px rgba(0, 0, 0, .18);
    cursor: pointer;
}
#toggle-examples:hover { background: color-mix(in srgb, var(--accent) 88%, #000); }

/* While examples are shown ("Hide examples"), the button recedes to white. */
body.examples-visible #toggle-examples {
    border-color: var(--border);
    background: var(--bg);
    color: var(--fg);
}
body.examples-visible #toggle-examples:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--bg);
}

/* ---- Narrow screens ---- */

@media (max-width: 800px) {
    body { grid-template-columns: 1fr; }
    .sidebar { position: static; height: auto; border-right: none; border-bottom: 1px solid var(--border); }
    .content { padding: 24px 18px 80px; }
}
