/* aos-hub — "release-engineering paper" (RFC-0004).
 *
 * One monospace face, ink on paper, tables and rules as layout, color
 * strictly semantic. Every asset is first-party: JetBrains Mono (OFL)
 * is embedded in the binary and served from /_assets/ — no font CDNs.
 */

@font-face {
  font-family: "JetBrains Mono";
  src: url("/_assets/jetbrains-mono-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("/_assets/jetbrains-mono-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Warm "paper" off-white, not stark white. */
  --paper: #f9f9f6;
  --ink: #1f1d18;
  --rule: #d8d4c8;
  --dim: #6e6a5e;
  --ok: #1c6f4a;
  --warn: #9c5a00;
  --bad: #b3261e;
  /* A warm clay/terracotta as the primary — complements the cream paper
   * and the warm ink (and isn't blue). Deep enough for AA link contrast. */
  --link: #b0492e;
  --accent: #b0492e;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #121310;
    --ink: #d8d8d0;
    --rule: #3a3b36;
    --dim: #8b8c84;
    --ok: #3fb950;
    --warn: #d29922;
    --bad: #f85149;
    /* Lighter clay for contrast on the dark phosphor scheme. */
    --link: #e08a6a;
    --accent: #e08a6a;
  }
}

* { box-sizing: border-box; }

body {
  font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 14px;
  line-height: 1.65;
  background: var(--paper);
  color: var(--ink);
  margin: 0 auto;
  padding: 2.25rem 1.5rem 5rem;
  max-width: 74rem;
  /* Tint every UA-accented control (focus rings, checkboxes, and the
   * search field's clear "x") with our clay primary instead of UA blue. */
  accent-color: var(--accent);
}

p { margin: 0.7rem 0; }

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

header.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.4rem;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 0.7rem;
  margin-bottom: 2rem;
}
header.masthead .brand {
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--ink);
}
header.masthead .crumbs { color: var(--dim); }
header.masthead .crumbs a { color: var(--ink); }
/* Push the session indicator (which doubles as the primary nav when
 * signed in) to the far right; the flex gap keeps the brand and crumbs
 * spaced apart on the left. */
header.masthead .session { color: var(--dim); margin-left: auto; }
header.masthead .session a { color: var(--ink); }
header.masthead .session .who { color: var(--dim); }

h1, h2 {
  font-size: 1rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.4rem;
  margin: 2.4rem 0 1rem;
}
h1 { font-size: 1.15rem; margin-top: 0.5rem; }

table {
  border-collapse: collapse;
  width: 100%;
  margin: 0.6rem 0 1.6rem;
}
th, td {
  text-align: left;
  padding: 0.45rem 1.1rem 0.45rem 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  /* Long unbreakable strings (trust keys, store paths, NAR hashes) must
   * wrap inside the cell rather than widen the table past the page. */
  overflow-wrap: anywhere;
  word-break: break-word;
}
th {
  color: var(--dim);
  font-weight: 400;
  text-transform: uppercase;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
}
td.num { text-align: right; }

code, pre {
  font-family: inherit;
  background: color-mix(in srgb, var(--ink) 6%, var(--paper));
  border: 1px solid var(--rule);
}
code { padding: 0.05rem 0.3rem; }
pre {
  padding: 0.9rem 1.1rem;
  line-height: 1.5;
  overflow-x: auto;
  margin: 0.7rem 0 1.6rem;
}

.ok { color: var(--ok); }
.warn { color: var(--warn); }
.bad { color: var(--bad); }
.dim { color: var(--dim); }
.good { color: var(--ok); }

/* Destructive controls: delete forms and their headings, flagged so a
 * confirmation-gated removal reads as a deliberate, distinct action. */
h2.danger { color: var(--bad); }
button.danger { color: var(--bad); border-color: var(--bad); }

/* The per-registry management link hub on the settings landing page. */
ul.manage-links { columns: 2; list-style: square; }

/* The 16x16 channel partition grid: glyph + color per release, so the
 * encoding survives monochrome and colorblind rendering. r0..r5 follow
 * the legend's frontier-first release order; the glyph alone is
 * sufficient — color is reinforcement, never the only channel. */
pre.partition-grid { line-height: 1.15; letter-spacing: 0.18em; }
.r0 { color: var(--ok); }
.r1 { color: var(--link); }
.r2 { color: var(--warn); }
.r3 { color: var(--bad); }
.r4 { color: var(--accent); }
.r5 { color: var(--dim); }

/* The bucket-calculator's grid cell marker: inverse video, so the hit
 * survives monochrome rendering too. */
.hit { background: var(--ink); }
.hit span { color: var(--paper); }

.statline {
  margin-top: 2.5rem;
  border-top: 1px solid var(--rule);
  padding-top: 0.4rem;
  color: var(--dim);
  font-size: 0.8rem;
}

/* Rollout / progress meter: a bordered track with a solid fill, drawn as a
 * styled box (not tiled block glyphs, which leave hairline gaps). The fill
 * width is a discrete `pct-N` class because the strict CSP forbids the inline
 * `style="width:…"` a continuous value would need. */
.meter {
  display: inline-block;
  width: 9rem;
  height: 0.7rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  vertical-align: middle;
  overflow: hidden;
}
.meter-fill { display: block; height: 100%; background: var(--ok); }
.pct-0 { width: 0; }
.pct-5 { width: 5%; }
.pct-10 { width: 10%; }
.pct-15 { width: 15%; }
.pct-20 { width: 20%; }
.pct-25 { width: 25%; }
.pct-30 { width: 30%; }
.pct-35 { width: 35%; }
.pct-40 { width: 40%; }
.pct-45 { width: 45%; }
.pct-50 { width: 50%; }
.pct-55 { width: 55%; }
.pct-60 { width: 60%; }
.pct-65 { width: 65%; }
.pct-70 { width: 70%; }
.pct-75 { width: 75%; }
.pct-80 { width: 80%; }
.pct-85 { width: 85%; }
.pct-90 { width: 90%; }
.pct-95 { width: 95%; }
.pct-100 { width: 100%; }

/* Pagination nav (shared by every paginated list). The page-of-page label is
 * dimmed so the prev/next/first/last links read as the actionable elements. */
p.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 1rem;
  margin: 0.4rem 0 1.6rem;
}
p.pager .of { color: var(--dim); }

/* Package browser: the prominent lede description, the platform chips, the
 * dependency lists, and the raw-metadata disclosure — all monochrome-first,
 * matching the release-engineering paper aesthetic. */
p.lede {
  font-size: 1.05rem;
  margin: 0.4rem 0 0.8rem;
}

/* The registry README preamble: a readable multi-paragraph block above the
 * registry home, set off from the surrounding terminal-style metadata. */
.readme {
  max-width: 60rem;
  margin: 1rem 0 1.8rem;
  padding-left: 1rem;
  border-left: 2px solid var(--rule);
}
.readme p { margin: 0.55rem 0; }
p.chips { margin: 0.2rem 0 0.8rem; }
.chip {
  display: inline-block;
  border: 1px solid var(--rule);
  padding: 0.05rem 0.45rem;
  margin: 0 0.2rem 0.2rem 0;
  font-size: 0.85rem;
}
ul.deps {
  margin: 0.3rem 0 0.8rem;
  padding-left: 1.2rem;
  columns: 18rem;
}
ul.deps li { break-inside: avoid; }
details.raw-metadata { margin-top: 1.5rem; }
details.raw-metadata summary {
  cursor: pointer;
  color: var(--link);
}
form.pkg-search { margin-bottom: 0.4rem; }
form.pkg-search select {
  font: inherit;
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
}
/* The Wireshark-style filter box. The plain <input> is the no-JS floor; the
 * widget wrapper adds a syntax-highlight overlay and a custom autocomplete. */
.filter-field {
  position: relative;
  display: inline-block;
  width: 100%;
  max-width: 52rem;
  vertical-align: top;
  margin-bottom: 0.4rem;
}
input.filter-box {
  width: 100%;
  font: inherit;
}
/* The highlight overlay is hidden until app.js enhances the widget. Once
 * enhanced, the <input> stays in flow and defines the box; the highlight <pre>
 * is layered exactly behind it (so the colored tokens line up under the
 * transparent typed text). */
.filter-field .filter-highlight { display: none; }
.filter-field.enhanced .filter-highlight,
.filter-field.enhanced input.filter-box {
  margin: 0;
  border: 1px solid var(--rule);
  padding: 0.25rem 0.5rem;
  font: inherit;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre;
  overflow: hidden;
  box-sizing: border-box;
}
.filter-field.enhanced .filter-highlight {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--paper);
  color: var(--ink);
}
.filter-field.enhanced .filter-highlight code {
  font: inherit;
  background: none;
  border: none;
  padding: 0;
}
.filter-field.enhanced input.filter-box {
  position: relative;
  z-index: 1;
  background: transparent;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: var(--ink);
}

/* Grey-shade syntax highlighting: fields darkest, then values, operators, and
 * connectives progressively dimmer — monochrome, matching the paper theme. */
.ftok-field { color: var(--ink); font-weight: 700; }
.ftok-value { color: var(--ink); }
.ftok-string { color: var(--dim); }
.ftok-op { color: var(--dim); }
.ftok-bool { color: var(--dim); font-style: italic; }
.ftok-paren { color: var(--dim); }

/* The custom autocomplete dropdown (no native <datalist> popup). */
.filter-suggest {
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 20;
  min-width: 14rem;
  max-width: 100%;
  max-height: 16rem;
  overflow-y: auto;
  margin-top: 2px;
  background: var(--paper);
  border: 1px solid var(--ink);
}
.filter-suggest .fs-item {
  padding: 0.2rem 0.6rem;
  cursor: pointer;
  white-space: pre;
}
.filter-suggest .fs-item:hover,
.filter-suggest .fs-item.active {
  background: color-mix(in srgb, var(--ink) 10%, var(--paper));
}

/* The field/operator legend under the filter box. */
p.filter-help { font-size: 0.8rem; margin: 0.2rem 0 0.8rem; }
p.filter-help code { font-size: 0.8rem; padding: 0 0.25rem; }

/* Click-to-sort column headers. Each sortable <th> holds a link that cycles
 * unsorted → descending → ascending; the glyph shows the current state and is
 * dim until the column is the active sort key. */
th a { color: var(--dim); }
th a:hover { color: var(--ink); }
th a.sorted { color: var(--ink); }
.sort-glyph { font-size: 0.85em; }
th a:not(.sorted) .sort-glyph { opacity: 0.4; }

/* Form controls — styled GLOBALLY so every button and input looks the
 * same on every page (search boxes, the bucket calculator, passkey
 * buttons, and the producer console alike), not just inside .console. */
button,
input[type="submit"],
input[type="button"] {
  font: inherit;
  padding: 0.25rem 0.9rem;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  line-height: 1.2;
  vertical-align: baseline;
}
button:hover,
input[type="submit"]:hover,
input[type="button"]:hover {
  background: color-mix(in srgb, var(--ink) 8%, var(--paper));
}
button:disabled { color: var(--dim); border-color: var(--rule); cursor: default; }

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
select {
  font: inherit;
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink);
}

/* Focus: the clay accent, never the UA blue. A matching border plus a thin
 * accent outline reads as "active" without shifting layout. */
input:focus,
textarea:focus,
select:focus,
button:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

/* The search field's clear control: WebKit/Blink draw a fixed gray-blue "x"
 * that ignores `accent-color`. Replace it with an accent-tinted X via a mask
 * so it tracks the theme (Firefox already honors `accent-color` above). */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  height: 0.8em;
  width: 0.8em;
  cursor: pointer;
  background-color: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 3l10 10M13 3L3 13' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 3l10 10M13 3L3 13' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Producer console: the no-JS tier is the floor, so every mutation is a
 * plain form + redirect. Layout only — the control styling is global. */
form.console { margin: 0.9rem 0 1.8rem; }
form.console label { display: block; margin: 0.6rem 0; }
form.console input[type="text"],
form.console input[type="email"],
form.console input[type="password"],
form.console select { min-width: 18rem; }

/* A standalone field caption (used where a tall control would baseline-align
 * an inline <label> to its bottom edge). Matches the table-header treatment. */
.field-label {
  display: block;
  margin: 0.9rem 0 0.3rem;
  color: var(--dim);
  text-transform: uppercase;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
}

/* The TOML config editor: a plain <textarea> (the no-JS floor) plus a
 * highlight overlay that app.js fills in and reveals by adding `.enhanced`.
 * Until then the textarea is a normal, full-width, resizable control. */
.code-editor textarea {
  display: block;
  width: 100%;
  font: inherit;
  line-height: 1.5;
  tab-size: 2;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--rule);
  background: color-mix(in srgb, var(--ink) 6%, var(--paper));
  color: var(--ink);
  resize: vertical;
}
.code-editor .code-highlight { display: none; }

/* Enhanced mode: the highlight <pre> sits in flow and sizes the box; the
 * textarea is layered on top with transparent text and a visible caret, so
 * what you type lines up exactly over the colored tokens beneath it. */
.code-editor.enhanced { position: relative; }
.code-editor.enhanced .code-highlight,
.code-editor.enhanced textarea {
  margin: 0;
  border: 1px solid var(--rule);
  padding: 0.9rem 1.1rem;
  font: inherit;
  font-size: 14px;
  line-height: 1.5;
  tab-size: 2;
  white-space: pre;
  overflow: auto;
  box-sizing: border-box;
}
.code-editor.enhanced .code-highlight {
  display: block;
  min-height: 18rem;
  background: color-mix(in srgb, var(--ink) 6%, var(--paper));
  color: var(--ink);
  pointer-events: none;
}
.code-editor.enhanced .code-highlight code {
  font: inherit;
  background: none;
  border: none;
  padding: 0;
}
.code-editor.enhanced textarea {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  resize: none;
  background: transparent;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: var(--ink);
}

/* TOML token palette — drawn entirely from the theme variables so the editor
 * tracks light/dark and never introduces an off-scheme color. */
.code-highlight .t-c { color: var(--dim); font-style: italic; } /* comment */
.code-highlight .t-h { color: var(--accent); font-weight: 700; } /* [table] */
.code-highlight .t-k { color: var(--ink); }                      /* key */
.code-highlight .t-s { color: var(--ok); }                       /* string */
.code-highlight .t-n { color: var(--warn); }                     /* number */
.code-highlight .t-b { color: var(--link); }                     /* boolean */
.code-highlight .t-a { color: var(--ink); }                      /* array/inline table */

p.notice {
  border-left: 3px solid var(--ok);
  padding: 0.4rem 0.8rem;
  margin: 0.6rem 0;
  background: color-mix(in srgb, var(--ok) 6%, var(--paper));
}
p.confirm {
  border-left: 3px solid var(--warn);
  padding: 0.4rem 0.8rem;
  margin: 0.6rem 0;
  background: color-mix(in srgb, var(--warn) 6%, var(--paper));
}
.secret {
  display: block;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--bad);
  background: color-mix(in srgb, var(--bad) 5%, var(--paper));
  word-break: break-all;
}
