/* XRPL Access Hub — layout and components. Managed by Ansible (role: hub_landing).
   Every colour comes from tokens.css, which must load first. No colour literal
   belongs in this file.
   Light only: there is no dark theme and no [data-theme] override. Code blocks
   and the ledger mosaic are the two navy surfaces, by design.
   No inline <style> anywhere — the pages are served under style-src 'self'.
   status.js and hub.js build markup with these class names; renaming one is a
   change to those scripts and their tests too. */

/* ── Base ─────────────────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important;
                           transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

body.hub {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font: 400 16px/26px var(--font-sans);
  -webkit-font-smoothing: antialiased;
}
/* Plus Jakarta Sans's contextual alternates (calt) turn the x in "5xx" into a
   multiplication sign. Every `font:` shorthand resets ligatures to on, and some
   (`.hub-table th`, `.hub-table .num`, `.hub code`) outrank any plain selector,
   so this is the one !important in the file. */
body.hub, body.hub * { font-variant-ligatures: no-contextual !important; font-feature-settings: "calt" 0 !important; }

.hub h1, .hub h2, .hub h3, .hub p, .hub ul, .hub ol, .hub dl, .hub dd, .hub figure { margin: 0; }
.hub ul, .hub ol { padding: 0; list-style: none; }
.hub img, .hub svg { max-width: 100%; }

/* The UA's `[hidden] { display: none }` is an author-beatable rule, so any class here
   that sets an explicit display (.hub-chart, .hub-key, .hub-metrics …) would otherwise
   keep a hidden element on screen — an undrawn chart reserving its full height, or a
   legend describing nothing. The JS toggles `hidden` on exactly these elements. */
.hub [hidden] { display: none !important; }

.hub a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--link-underline);
  text-underline-offset: 3px;
}
.hub a:hover { text-decoration-color: var(--ink); }

/* The single focus treatment on the site. outline stays declared but transparent
   so Windows forced-colors mode, which ignores box-shadow, still paints a ring. */
.hub :focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* ── Type ─────────────────────────────────────────────────────────────────── */

/* Headings are Archivo at full width and heavy weight, set in capitals: the
   display voice the Commons app fleet shares. Body copy stays in sentence case. */
.hub-display {
  font: 900 88px/80px var(--font-display);
  font-stretch: 125%;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.hub-h2 {
  font: 900 34px/36px var(--font-display);
  font-stretch: 125%;
  text-transform: uppercase;
}
.hub-h3 {
  font: 800 19px/24px var(--font-display);
  font-stretch: 115%;
  text-transform: uppercase;
}
.hub-p       { font: 400 16px/26px var(--font-sans); }
.hub-lead    { font: 400 19px/30px var(--font-sans); color: var(--ink-muted); }
.hub-small   { font: 400 14px/22px var(--font-sans); color: var(--ink-muted); }

/* The only label style on the site. Anything that reads as a caption, a column
   header or a field name uses this and nothing else. */
.hub-label {
  font: 600 13px/18px var(--font-sans);
  color: var(--ink-subtle);
}

/* Secondary text is one colour. Do not mix --ink and --ink-muted inside a block. */
.hub-muted { color: var(--ink-muted); }

/* Mono is for code, the endpoint URL and numbers in tables — nothing else. Every
   number is tabular so columns and live-updating figures do not jitter. */
.hub-num { font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* ── Container and page frame ─────────────────────────────────────────────── */

/* One container. The header rule, every section, every hairline and the footer
   stop on the same two edges. */
.hub-container {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--space-8);
}

.hub-header {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 68px;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}
.hub-header__rule { width: 1px; align-self: stretch; min-height: 24px; background: var(--line); flex: none; }
.hub-header__brand { color: var(--ink); white-space: nowrap; }
/* On the pill, not the brand: `.hub h3 { margin: 0 }` in the base block outranks a
   single class, so margin-right: auto on the brand would silently lose. */
.hub-header .hub-pill { margin-left: auto; }
.hub-logo-link { display: inline-flex; color: var(--ink); text-decoration: none; }
.hub-logo { height: 26px; width: auto; display: block; }

.hub-main { padding-bottom: var(--space-24); min-width: 0; }

/* --section-gap between sections; 24px under each section heading. */
.hub-section { margin-top: var(--section-gap); }
.hub-section__head { margin-bottom: var(--space-6); }
.hub-section__head .hub-small { margin-top: var(--space-2); }

.hub-footer {
  padding: var(--space-6) 0 var(--space-8);
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  font: 400 14px/22px var(--font-sans);
  color: var(--ink-subtle);
}
.hub-footer span { margin-right: auto; }
.hub-footer a { color: var(--ink-subtle); }

/* ── Notices ──────────────────────────────────────────────────────────────── */

/* role="status" stays in the accessibility tree at all times: a live region
   hidden at parse time is announced unreliably when it is later revealed. Only
   the text and the box come and go. */
.hub-banner { display: none; }
.hub-banner--shown {
  display: block;
  background: var(--notice);
  border: var(--border) solid var(--ink);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-6);
  margin-top: var(--space-6);
  color: var(--ink);
  font: 500 16px/26px var(--font-sans);
}
.hub-live-note {
  font: 400 14px/22px var(--font-sans);
  color: var(--ink-muted);
  margin-top: var(--space-6);
}

/* ── Button ───────────────────────────────────────────────────────────────── */

.hub-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: 600 15px/20px var(--font-sans);
  padding: 10px var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border) solid var(--line-control);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
/* `.hub a` sets the site's link colour and underline at (0,1,1), which outranks a
   lone class. A button that happens to be a link therefore needs the element in the
   selector to keep its own colour and lose the underline. */
.hub a.hub-btn, .hub a.hub-pill { text-decoration: none; }
.hub a.hub-btn, .hub a.hub-btn:hover { color: var(--ink); }
.hub-btn--primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.hub-btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.hub a.hub-btn--primary, .hub a.hub-btn--primary:hover { color: var(--on-accent); }
.hub-btn--secondary { background: var(--surface-raised); }
.hub-btn--secondary:hover { background: var(--surface-hover); }
.hub-btn--small { font: 600 13px/18px var(--font-sans); padding: var(--space-1) var(--space-3); border-width: 1px; }

.hub-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* ── StatusPill ───────────────────────────────────────────────────────────── */

/* Never a dot without the word: the dot is decoration, ::before carries no text
   and the state is always spelled out beside it. The word is ink; only the dot
   carries the state colour. */
.hub-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font: 600 13px/20px var(--font-sans);
  padding: 5px 12px 5px 10px;
  background: var(--surface-raised);
  border: 1.5px solid var(--line-control);
  border-radius: var(--radius-sm);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.hub-pill::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: var(--radius-pill);
  background: var(--ink-faint);
  flex: none;
}
.hub-pill--ok::before   { background: var(--status-ok); }
.hub-pill--warn::before { background: var(--status-warn); }
.hub-pill--down::before { background: var(--status-down); }
a.hub-pill:hover { background: var(--surface-hover); }

/* The status page headline wears the pill's shape at display size. */
.hub-pill--headline {
  font: 900 40px/44px var(--font-display);
  font-stretch: 125%;
  text-transform: uppercase;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  gap: var(--space-4);
  white-space: normal;
}
.hub-pill--headline::before { width: 18px; height: 18px; }

/* ── EndpointField ────────────────────────────────────────────────────────── */

.hub-endpoint {
  display: flex;
  align-items: stretch;
  max-width: 540px;
  background: var(--surface-raised);
  border: var(--border) solid var(--line-control);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.hub-endpoint__verb {
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-right: var(--border) solid var(--line-control);
  background: var(--tag);
  color: var(--ink);
  font: 500 12px/16px var(--font-mono);
  flex: none;
}
.hub-endpoint__url {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  font: 500 17px/26px var(--font-mono);
  color: var(--ink);
  overflow-wrap: anywhere;
}
.hub-endpoint__copy {
  flex: none;
  border: 0;
  border-left: var(--border) solid var(--line-control);
  background: transparent;
  color: var(--ink);
  font: 600 14px/18px var(--font-sans);
  padding: 0 var(--space-4);
  cursor: pointer;
}
.hub-endpoint__copy:hover { background: var(--surface-hover); }

/* ── CodeBlock ────────────────────────────────────────────────────────────── */

.hub-code {
  background: var(--code-surface);
  color: var(--code-ink);
  border-radius: var(--radius-md);
  overflow: hidden;
  min-width: 0;
}
.hub-code__bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: 0 var(--space-3);
  min-height: 48px;
  background: var(--code-bar);
  border-bottom: 1px solid var(--code-line);
}
/* Without JavaScript every control in the bar stays hidden; drop the empty bar
   rather than paint a blank navy stripe over the stacked snippets. */
.hub-code__bar:not(:has(> :not([hidden]):not(.hub-code__spacer))) { display: none; }
.hub-code__tabs { display: flex; gap: var(--space-1); align-self: stretch; }
.hub-code__tab {
  font: 600 13px/20px var(--font-sans);
  padding: 0 var(--space-3);
  border: 0;
  border-bottom: 3px solid transparent;
  background: transparent;
  color: var(--code-muted);
  cursor: pointer;
}
.hub-code__tab:hover { color: var(--code-ink); }
.hub-code__tab[aria-selected="true"] { color: var(--code-ink); border-bottom-color: var(--code-select); }
.hub-code__spacer { margin-left: auto; }
.hub-code__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font: 400 13px/20px var(--font-sans);
  color: var(--code-muted);
  cursor: pointer;
  white-space: nowrap;
}
.hub-code__toggle input { accent-color: var(--code-select); margin: 0; cursor: pointer; }
.hub-code__bar .hub-btn--secondary { background: transparent; border-color: var(--code-muted); color: var(--code-ink); }
.hub-code__bar .hub-btn--secondary:hover { background: var(--code-line); }
/* The ring's inner gap is cream; on navy that reads as a halo, which is the point. */
.hub-code__pane {
  margin: 0;
  padding: var(--space-6);
  font: 400 14px/24px var(--font-mono);
  color: var(--code-ink);
  overflow-x: auto;
  white-space: pre;
}
/* Without JavaScript every pane is visible, stacked; a rule keeps them apart. */
.hub-code__pane + .hub-code__pane { border-top: 1px solid var(--code-line); }
/* The only three syntax colours on the site. */
.hub-code__pane .s { color: var(--code-string); }
.hub-code__pane .f { color: var(--code-muted); }

/* ── Panel ────────────────────────────────────────────────────────────────── */

.hub-panel {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: var(--surface-raised);
  border: var(--border) solid var(--line-control);
  border-radius: var(--radius-md);
  padding: var(--space-6) 20px;
}
.hub-panel > * + * { margin-top: var(--space-3); }
.hub-panel .hub-btn { margin-top: var(--space-4); align-self: start; }

/* ── Metric ───────────────────────────────────────────────────────────────── */

.hub-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-4);
}
.hub-metric__value {
  /* Semi-condensed, not the headings' 125%: a ten-digit ledger index has to fit
     a fifth of the column. */
  font: 800 28px/40px var(--font-display);
  font-stretch: 87.5%;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  color: var(--ink);
  /* Reserved before the first fetch lands, so a figure arriving shifts nothing. */
  min-height: 40px;
}
/* A value that was never measured. Never a 0 and never an em-dash here: both
   read as a reading, and this is the absence of one. */
.hub-metric__value--pending {
  font: 500 15px/40px var(--font-sans);
  color: var(--status-warn);
}
.hub-metric__context { min-height: 22px; }

/* ── DataTable ────────────────────────────────────────────────────────────── */

.hub-table {
  width: 100%;
  border-collapse: collapse;
  font: 400 15px/24px var(--font-sans);
}
.hub-table th {
  text-align: left;
  padding: 0 var(--space-4) var(--space-3) 0;
  font: 600 13px/18px var(--font-sans);
  color: var(--ink-subtle);
  border-bottom: var(--border) solid var(--line-control);
}
.hub-table td {
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-muted);
  vertical-align: top;
}
.hub-table td:first-child { color: var(--ink); font-weight: 600; }
.hub-table th:last-child, .hub-table td:last-child { padding-right: 0; }
.hub-table .num, .hub-table th.num {
  text-align: right;
  font: 500 14px/20px var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  white-space: nowrap;
}
.hub-table th.num { font: 600 13px/18px var(--font-sans); }
.hub-table .pill-cell { text-align: right; white-space: nowrap; }
.hub-table code, .hub code {
  font: 500 13.5px/22px var(--font-mono);
  background: var(--tag);
  color: var(--ink);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
}

/* The limits table leads with the number, at display size. */
.hub-table .hub-rate {
  font: 900 30px/30px var(--font-display);
  font-stretch: 112%;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}
.hub-rate span { font: 600 13px/1 var(--font-sans); color: var(--ink-subtle); }

.hub-table__notes { margin-top: var(--space-4); display: grid; gap: var(--space-2); }

/* ── Front page ───────────────────────────────────────────────────────────── */

/* Copy on the left, the ledger mosaic on the right. The mosaic never sets the
   hero's height: its grid is absolutely positioned inside the figure, so the
   copy decides how tall the row is and the mosaic fills whatever that is. */
.hub-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: var(--space-12);
  padding: var(--space-12) 0;
  border-bottom: 1px solid var(--line);
}
.hub-hero__copy { display: flex; flex-direction: column; justify-content: center; padding: var(--space-8) 0; }
.hub-hero .hub-lead { margin-top: var(--space-8); max-width: 44ch; text-wrap: pretty; }
.hub-hero .hub-endpoint { margin-top: var(--space-8); }
.hub-hero .hub-actions { margin-top: var(--space-6); }

.hub-mosaic {
  position: relative;
  min-height: 420px;
  background: var(--mosaic-ground);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.hub-mosaic__grid {
  position: absolute;
  inset: 0;
  display: grid;
  /* 18 must equal mosaic_cols in index.html.j2, or the newest cell leaves the
     bottom-right corner. unsafe: overflow is clipped from the top on purpose. */
  grid-template-columns: repeat(18, 1fr);
  align-content: unsafe end;
  gap: 3px;
  padding: 3px;
  overflow: hidden;
}
.hub-mosaic__grid i { display: block; aspect-ratio: 1; background: var(--mosaic-old); }
.hub-mosaic__grid i.a { background: var(--mosaic-old-alt); }
.hub-mosaic__grid i.h { background: var(--mosaic-hour); }
.hub-mosaic__grid i.l { background: var(--mosaic-latest); }
.hub-mosaic__key {
  position: absolute;
  top: var(--space-6);
  left: var(--space-6);
  max-width: calc(100% - 2 * var(--space-6));
  background: var(--surface);
  border: var(--border) solid var(--line-control);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-4) var(--space-3);
  font: 500 13px/20px var(--font-sans);
  color: var(--ink);
}
.hub-mosaic__key b { display: block; font-weight: 700; font-size: 14px; margin-bottom: var(--space-1); }
.hub-mosaic__key li { display: flex; align-items: center; gap: var(--space-2); }
.hub-mosaic__key li::before { content: ""; width: 12px; height: 12px; flex: none; }
.hub-mosaic__k--latest::before { background: var(--mosaic-latest); }
.hub-mosaic__k--hour::before   { background: var(--mosaic-hour); box-shadow: inset 0 0 0 1px var(--mosaic-ground); }
.hub-mosaic__k--old::before    { background: var(--mosaic-old); }
.hub-mosaic__note { display: block; margin-top: var(--space-2); color: var(--ink-subtle); font-size: 12px; line-height: 18px; }

/* The body under the hero: a sticky table of contents beside the sections. */
.hub-doc { display: grid; grid-template-columns: var(--nav-width) minmax(0, 1fr); gap: var(--space-16); }
.hub-toc {
  position: sticky;
  top: var(--space-6);
  align-self: start;
  margin-top: var(--section-gap);  /* level with the first section heading */
  display: grid;
  font: 500 14px/20px var(--font-sans);
}
.hub .hub-toc a {
  padding: var(--space-2) 0 var(--space-2) var(--space-3);
  border-left: var(--border) solid var(--line);
  color: var(--ink-subtle);
  text-decoration: none;
}
.hub .hub-toc a:hover { color: var(--ink); border-left-color: var(--ink); }

.hub-qs { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 300px); gap: var(--space-8); align-items: start; }
.hub-qs__notes { display: grid; }
.hub-qs__notes li { padding: var(--space-3) 0; border-top: 1px solid var(--line); }
.hub-qs__notes li:last-child { border-bottom: 1px solid var(--line); }
.hub-qs__notes b { display: block; color: var(--ink); font-weight: 700; }

.hub-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.hub-prose { max-width: var(--measure); display: grid; gap: var(--space-3); }

/* ── Status page ──────────────────────────────────────────────────────────── */

.hub-now { margin-top: var(--space-12); display: grid; gap: var(--space-3); justify-items: start; }
.hub-counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-6); margin-bottom: var(--space-8); }
.hub-counts dt { margin-bottom: var(--space-1); }
.hub-counts dd {
  font: 800 30px/40px var(--font-display);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  min-height: 40px;
}
.hub-counts dd.hub-metric__value--pending { font: 500 15px/40px var(--font-sans); }

.hub-about { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-8); }
.hub-about p { max-width: var(--measure); }
.hub-about p + p { margin-top: var(--space-3); }

/* ── Charts ───────────────────────────────────────────────────────────────── */

.hub-chart { display: block; width: 100%; height: auto; }
/* --ink-subtle, not --ink-faint: axis labels are text and have to clear 4.5:1. */
.hub-chart__t    { fill: var(--ink-subtle); font-family: var(--font-sans); font-size: 12px;
                   font-weight: 500; font-variant-numeric: tabular-nums; }
.hub-chart--narrow .hub-chart__t { font-size: 30px; }
.hub-chart__grid { stroke: var(--line); stroke-width: 1; fill: none; }
.hub-chart__line { fill: none; stroke: var(--chart-bar); stroke-width: 2;
                   stroke-linejoin: round; stroke-linecap: round; }
.hub-chart__area { fill: var(--chart-bar); fill-opacity: .14; stroke: none; }
.hub-chart__bar  { fill: var(--chart-bar); }
/* A missing sample is drawn as a dashed segment, never skipped and never zero: a
   gap in the readings must not look like an outage. */
.hub-chart__gap  { fill: none; stroke: var(--ink-faint); stroke-width: 2; stroke-dasharray: 4 5; }
.hub-chart__mark { fill: var(--chart-mark); stroke: none; }

.hub-chart__foot { margin-top: var(--space-3); display: grid; gap: var(--space-2); }
.hub-key { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.hub-key li { display: inline-flex; align-items: center; gap: var(--space-2); }
.hub-key li::before { content: ""; width: 12px; height: 3px; background: var(--chart-bar); flex: none; }
.hub-key .hub-key__gap::before { background: var(--ink-faint); }

/* ── Responsive ───────────────────────────────────────────────────────────── */

@media (max-width: 1080px) {
  .hub-display { font-size: 68px; line-height: 64px; }
  .hub-doc { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .hub-toc { display: none; }
}

@media (max-width: 880px) {
  .hub-hero { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); padding-top: var(--space-6); }
  .hub-hero__copy { padding: var(--space-6) 0 0; }
  .hub-mosaic { min-height: 360px; }
  .hub-qs { grid-template-columns: minmax(0, 1fr); }
  .hub-grid2, .hub-about { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 639px) {
  .hub-container { padding: 0 var(--space-4); }
  .hub-display { font-size: 44px; line-height: 44px; font-stretch: 112%; }
  .hub-h2 { font-size: 26px; line-height: 30px; }
  .hub-pill--headline { font-size: 26px; line-height: 32px; font-stretch: 112%; }
  .hub-pill--headline::before { width: 14px; height: 14px; }
  .hub-section { margin-top: var(--space-16); }
  .hub-actions .hub-btn { flex: 1 1 auto; }
  /* The brand name and the pill compete for one line; the pill keeps its word. */
  .hub-header__rule, .hub-header__brand { display: none; }
  .hub-mosaic__key { top: var(--space-3); left: var(--space-3); max-width: calc(100% - 2 * var(--space-3)); }

  /* Tables become stacked label/value rows. The header row is dropped rather
     than hidden off-screen, and each cell names itself from data-label. */
  .hub-table, .hub-table tbody, .hub-table tr, .hub-table td { display: block; }
  .hub-table thead { display: none; }
  .hub-table tr { padding: var(--space-4) 0; border-bottom: 1px solid var(--line); }
  .hub-table tbody tr:first-child { border-top: var(--border) solid var(--line-control); }
  .hub-table td { padding: var(--space-1) 0; border-bottom: 0; }
  .hub-table td::before {
    content: attr(data-label);
    display: block;
    font: 600 13px/18px var(--font-sans);
    color: var(--ink-subtle);
    margin-bottom: 2px;
  }
  .hub-table td:first-child::before { content: none; }
  .hub-table .num, .hub-table .pill-cell { text-align: left; }

  .hub-endpoint { display: grid; grid-template-columns: 1fr auto; }
  .hub-endpoint__verb { grid-column: 1; border-right: 0; border-bottom: var(--border) solid var(--line-control); min-height: 40px; }
  .hub-endpoint__copy { grid-column: 2; grid-row: 1; border-left: var(--border) solid var(--line-control); border-bottom: var(--border) solid var(--line-control); }
  .hub-endpoint__url { grid-column: 1 / -1; font-size: 15px; }
}
