@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/Geist-Regular.woff2") format("woff2");
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/Geist-Medium.woff2") format("woff2");
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/Geist-SemiBold.woff2") format("woff2");
}

@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/GeistMono-Regular.woff2") format("woff2");
}

:root {
  color-scheme: dark;
  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", Roboto, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", SFMono-Regular, "JetBrains Mono", Menlo, Consolas, monospace;
  --bg: #171717;
  --surface: #292a2d;
  --surface-2: #1f2023;
  --text: #e3e6eb;
  --muted: #99a3af;
  --hairline: #41414d;
  --soft: rgba(255, 255, 255, 0.04);
  --accent: #a8c7fa;
  --accent-hover: #bdd6ff;
  --accent-ink: #171717;
  --err: #ff8a8a;
  --ok: #7ee2a8;
  --warn: #e4b84f;

  /* Type. One scale, in rem, so every size follows the reader's browser
     setting - the file was entirely px before and ignored it. */
  --text-xs: 0.6875rem;
  --text-sm: 0.75rem;
  --text-md: 0.8125rem;
  --text-base: 0.875rem;
  --text-lg: 0.9375rem;
  --text-xl: 1rem;
  --text-2xl: 1.125rem;
  --text-3xl: 1.375rem;
  --text-4xl: 1.5rem;
  /* The one fluid size: the home hero, which used to step at a breakpoint. */
  --text-hero: clamp(2rem, 1.35rem + 2.2vw, 2.375rem);

  /* Space, on a 2px grid. Enough steps that nothing had to move more than a
     pixel to join the scale, which is what keeps the rhythm as it was. */
  --space-0-5: 0.125rem;
  --space-1: 0.25rem;
  --space-1-5: 0.375rem;
  --space-2: 0.5rem;
  --space-2-5: 0.625rem;
  --space-3: 0.75rem;
  --space-3-5: 0.875rem;
  --space-4: 1rem;
  --space-4-5: 1.125rem;
  --space-5: 1.25rem;
  --space-5-5: 1.375rem;
  --space-6: 1.5rem;
  --space-7: 1.75rem;
  --space-7-5: 1.875rem;
  --space-8-5: 2.125rem;
  --space-9: 2.25rem;
  --space-10-5: 2.625rem;
  --space-14: 3.5rem;
  --space-18: 4.5rem;

  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 6px;

  /* Motion. One curve, three speeds: --dur-fast for a press, --dur for colour
     and opacity, --dur-slow for anything that also moves a border or shadow. */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 80ms;
  --dur: 120ms;
  --dur-slow: 150ms;

  /* Control heights. Three sizes, not the eleven that grew here by hand. */
  --control-h: 38px;
  --control-h-sm: 32px;
  --control-lg: clamp(3.375rem, 2.9rem + 2vw, 3.625rem);
  /* The submit button inside a search field, which also sets the room the
     input has to leave for it. */
  --control-lg-button: clamp(2.5rem, 2.1rem + 1.8vw, 2.75rem);

  --focus: 0 0 0 2px var(--accent);
  --shadow-sm: 0 0 #0000;
  /* The scroll shadow on a sideways-scrolling table. Dark in both themes: it
     reads as depth under the edge of the box, not as a surface colour. */
  --shadow-scroll: rgba(0, 0, 0, 0.22);
  --content-width: 60.625rem;
  --data-width: 75rem;

  /* Derived colour. Every accent- or error-tinted surface and border in the
     file resolves to one of these, so the strength of a tint is decided once
     rather than per selector. They are mixes, so they follow the theme. */
  --tint-accent: color-mix(in srgb, var(--accent) 10%, var(--surface));
  --tint-accent-ghost: color-mix(in srgb, var(--accent) 9%, transparent);
  --edge-accent: color-mix(in srgb, var(--accent) 35%, var(--hairline));
  --edge-accent-strong: color-mix(in srgb, var(--accent) 55%, var(--hairline));
  --tint-err: color-mix(in srgb, var(--err) 8%, var(--surface));
  --edge-err: color-mix(in srgb, var(--err) 30%, var(--hairline));
  --tint-ok: color-mix(in srgb, var(--ok) 16%, transparent);
  --tint-warn: color-mix(in srgb, var(--warn) 18%, transparent);

  /* A surface set back from the one it sits on: the TLD picker's scroll area,
     a filter group, a table's grouping header. Two hand-mixed variants at 60%
     and 62% in opposite directions used to do this job. */
  --surface-sunk: color-mix(in srgb, var(--surface) 60%, var(--bg));
  --surface-raised: color-mix(in srgb, var(--muted) 7%, var(--surface));

  /* How tall a scrollable panel gets before it scrolls: the TLD picker and the
     JSON preview, which used to cap at 330px and 320px for no stated reason. */
  --panel-max-height: 20rem;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --bg: #f5f5f7;
    --surface: #ffffff;
    /* Light mode has one surface colour, where dark has two.
       `--surface-2` is the fill for a control, and a control has to read
       against the page *and* against a card. Dark leaves room for a third
       value between #171717 and #292a2d; light leaves ten steps between
       #f5f5f7 and #ffffff, and the old #f3f3f6 spent them in the wrong
       direction - darker than the page, so the search box, which is the one
       control that sits on the page rather than inside a card, had no visible
       fill at all. White instead: filled against the page, and carried by its
       border and shadow inside a card, which is what light UI does anyway. */
    --surface-2: #ffffff;
    --text: #1d1d1f;
    --muted: #6e6e73;
    --hairline: #e6e6e6;
    --soft: rgba(0, 0, 0, 0.025);
    --accent: #204de1;
    --accent-hover: #1a3fbf;
    --accent-ink: #ffffff;
    --err: #ee4037;
    --ok: #147a3d;
    --warn: #946200;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08), 0 8px 24px rgba(0, 0, 0, 0.06);
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  min-height: 100%;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  line-height: 1.55;
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.page {
  max-width: var(--content-width);
  margin: 0 auto;
  padding-block: clamp(var(--space-8-5), 3vw, var(--space-9)) var(--space-18);
  padding-inline: clamp(var(--space-4), 3vw, var(--space-6));
}

.page-wide {
  max-width: var(--data-width);
}

/* Visible only once focused, so keyboard users can skip the header. Clipped to
   nothing rather than parked at a magic offset: `left: -9999px` widens the
   document's scrollable area, and in a right-to-left flow it lands on screen. */
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 10;
  clip-path: inset(50%);
  border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--text-md);
  font-weight: 600;
  padding: var(--space-2-5) var(--space-3-5);
}

.skip-link:focus-visible {
  clip-path: none;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  margin-bottom: var(--space-1-5);
  font-size: var(--text-4xl);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.2;
}

h2 {
  margin-bottom: var(--space-1-5);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.25;
}

h3 {
  margin-bottom: var(--space-1);
  font-size: var(--text-lg);
  letter-spacing: 0;
}

h2.group,
.group,
.summary-table th,
.change-event-size,
.qb-edit,
.qb-preview > summary,
.qb-sublabel,
.qb-field-block > span,
.qb-conj {
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1.2;
  text-transform: uppercase;
}

h2.group,
.group {
  margin: 0 0 var(--space-3);
}

p {
  margin-bottom: var(--space-3);
}

p.sub,
.muted-line {
  color: var(--muted);
}

p.sub {
  margin: 0 0 var(--space-6);
}

a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition:
    color var(--dur) var(--ease),
    text-decoration-thickness var(--dur) var(--ease);
}

a:hover {
  text-decoration-thickness: 2px;
}

code,
pre,
dd,
.summary-table td {
  font-family: var(--font-mono);
}

code {
  max-width: 100%;
  border-radius: var(--radius-sm);
  background: var(--soft);
  font-size: 0.88em;
  overflow-wrap: anywhere;
  padding: 1px var(--space-1-5);
}

pre {
  overflow-x: auto;
  margin: 0;
  border-radius: var(--radius-md);
  background: var(--soft);
  font-size: var(--text-sm);
  padding: var(--space-3-5) var(--space-4);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Every bordered box on the site. `.stats-grid` overrides the background with
   --hairline, which is what draws the rules between its cells.

   `.summary-table-wrap` is just the box. It has no overflow of its own: a table
   is free to run as far down the page as it needs, and the ones that wrap never
   need to run sideways. */
.card,
.tld-selector,
.summary-table-wrap,
.stats-grid,
.qb-builder,
.qb-preview {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-7);
}

.brand-link > svg {
  flex-shrink: 0;
  color: var(--text);
}

.brand-text {
  flex: 1;
  min-width: 0;
}

.brand-text h1 {
  margin: 0 0 var(--space-1);
}

.brand-text .sub {
  margin: 0;
}

.brand-link {
  color: inherit;
  text-decoration: none;
  transition: opacity var(--dur) var(--ease);
}

.brand-link:hover {
  opacity: 0.72;
  text-decoration: none;
}

body.home-empty .page {
  padding-top: 9vh;
}

body.home-empty .brand {
  flex-direction: column;
  gap: var(--space-4-5);
  margin-bottom: var(--space-9);
  text-align: center;
}

body.home-empty .brand-text h1 {
  font-size: var(--text-hero);
  letter-spacing: 0;
}

body.home-empty .brand-text .sub {
  max-width: 31.25rem;
  margin-right: auto;
  margin-left: auto;
  font-size: var(--text-xl);
}

form {
  margin: 0;
}

label {
  display: grid;
  gap: var(--space-1-5);
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 600;
}

input,
select,
textarea {
  width: 100%;
  min-height: var(--control-h);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  outline: none;
  background: var(--surface-2);
  box-shadow: var(--shadow-sm);
  color: var(--text);
  font: inherit;
  font-size: var(--text-base);
  line-height: 1.35;
  padding: var(--space-2) var(--space-2-5);
  transition:
    border-color var(--dur-slow) var(--ease),
    box-shadow var(--dur-slow) var(--ease),
    background var(--dur) var(--ease);
}

input::placeholder,
textarea::placeholder {
  color: var(--muted);
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--muted);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
summary:focus-visible,
a:focus-visible {
  box-shadow: var(--shadow-sm), var(--focus);
  outline: none;
}

button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--control-h);
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-base);
  font-weight: 600;
  padding: var(--space-2) var(--space-3-5);
  white-space: nowrap;
  transition:
    filter var(--dur) var(--ease),
    transform var(--dur-fast) var(--ease),
    box-shadow var(--dur-slow) var(--ease),
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

button:hover {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
}

button:active {
  transform: scale(0.96);
}

button:disabled {
  cursor: not-allowed;
  filter: grayscale(0.35);
  opacity: 0.55;
}

/* The field and its button share one grid cell, so the button is placed rather
   than pulled out of flow and pushed back with a transform. That transform had
   to be respecified on :active and again under reduced motion, and the input's
   end padding had to be kept in step with the button's width by hand. Both now
   read --control-lg-button, so the button can be resized in one place. */
.search-form {
  display: grid;
  align-items: center;
  margin: 0 0 var(--space-4);
}

.search-form > * {
  grid-area: 1 / 1;
}

.search-form > input[type="text"] {
  min-height: var(--control-lg);
  border-radius: var(--radius-lg);
  font-size: clamp(var(--text-xl), 0.75rem + 1.2vw, var(--text-2xl));
  padding: var(--space-4) var(--space-5);
  padding-inline-end: calc(var(--control-lg-button) + var(--space-6));
}

.search-form > button[type="submit"] {
  justify-self: end;
  width: var(--control-lg-button);
  height: var(--control-lg-button);
  min-height: var(--control-lg-button);
  margin-inline-end: var(--space-2);
  padding: 0;
}

.examples {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-1-5) var(--space-3);
  margin: 0 0 var(--space-7);
  color: var(--muted);
  font-size: var(--text-md);
}

.examples .label {
  color: var(--muted);
}

/* The pager's numbers are the same quiet bordered chip, so they are drawn by
   the same recipe rather than a second copy of it. */
.example-link,
.sr-pager a,
.sr-pager .sr-here {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-h-sm);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.2;
  padding: var(--space-1-5) var(--space-2-5);
  text-decoration: none;
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease),
    transform var(--dur-fast) var(--ease);
}

/* Hovering a bordered, quiet control tints it toward the accent. */
.example-link:hover,
.sr-pager a:hover,
a.qb-btn:hover,
.qb-btn:hover {
  border-color: var(--edge-accent);
  background: var(--tint-accent);
  color: var(--accent);
}

.example-link:hover,
.sr-pager a:hover {
  text-decoration: none;
}

.example-link:active,
.sr-pager a:active {
  transform: scale(0.97);
}

.avail-bar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: var(--space-4-5) 0 var(--space-3);
}

.avail-results-bar {
  margin-top: var(--space-4);
}

.avail-status {
  color: var(--muted);
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
  padding-top: var(--space-1);
}

.avail-actions {
  display: flex;
  gap: var(--space-2);
}

.avail-actions button,
.tld-actions button {
  min-height: var(--control-h-sm);
  font-size: var(--text-md);
  padding: var(--space-1-5) var(--space-2-5);
}

.tld-selector {
  overflow: hidden;
}

/* The query builder's chip (.qb-chk) at the availability bar's smaller control
   height: radios for the preset, one checkbox for the filter. Sets no
   box-shadow of its own, so the chip's focus ring survives; the padding keeps
   that ring clear of `.tld-selector`'s overflow clip, which is why it can stay
   outset. */
.preset-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1-5) var(--space-3);
  padding: var(--space-2-5);
  border-bottom: 1px solid var(--hairline);
}

.preset-switch {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1-5);
}

/* Pushed away from the presets it composes with rather than joining the row of
   them. It wraps under on a narrow screen, where there is no right edge to sit
   against. */
.preset-filter {
  margin-left: auto;
}

.preset-bar .qb-chk {
  min-height: var(--control-h-sm);
  padding: 0 var(--space-2-5);
}

.preset-bar .qb-chk:has(input:disabled) {
  cursor: not-allowed;
  opacity: 0.5;
}

.tld-selector-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-2-5);
}

.tld-search:not(:focus-visible) {
  box-shadow: none;
}

.tld-search {
  flex: 1 1 14rem;
  min-height: var(--control-h-sm);
}

.tld-count {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

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

.tld-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  max-height: var(--panel-max-height);
  overflow: auto;
  border-top: 1px solid var(--hairline);
  background: var(--surface-sunk);
}

.tld-option {
  display: grid;
  grid-template-columns: auto minmax(5ch, 1fr) max-content;
  align-items: center;
  min-width: 0;
  gap: var(--space-2);
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  color: var(--text);
  cursor: pointer;
  font-size: var(--text-md);
  font-weight: 500;
  padding: var(--space-2) var(--space-2-5);
}

.tld-option:has(input:disabled) {
  cursor: not-allowed;
  opacity: 0.5;
}

.tld-option input,
.avail-filters .f-chk input {
  width: auto;
  min-height: 0;
}

/* A native checkbox does not paint an author border, so the box-shadow ring is
   all it has. Switching the shadow off unfocused keeps the resting look without
   taking the focus indicator with it. */
.tld-option input:not(:focus-visible),
.avail-filters .f-chk input:not(:focus-visible) {
  box-shadow: none;
}

.tld-name {
  min-width: 0;
  font-family: var(--font-mono);
  overflow-wrap: anywhere;
}

.tld-domains {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

.tld-list-empty {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: var(--text-md);
  padding: var(--space-4-5) var(--space-3);
  text-align: center;
}

.avail-filters {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2) var(--space-3);
  min-width: 0;
  font-size: var(--text-md);
}

.avail-filters .f-chk {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--muted);
  cursor: pointer;
}

.avail-filters input[type="search"],
.avail-filters select {
  width: auto;
  min-height: var(--control-h-sm);
  font-size: var(--text-md);
  padding: var(--space-1) var(--space-2);
}

.avail-filters input[type="search"]:not(:focus-visible),
.avail-filters select:not(:focus-visible) {
  box-shadow: none;
}

.avail-filters input[type="search"] {
  min-width: 8.75rem;
}

.availability-table {
  min-width: 0;
}

.availability-table th:last-child,
.availability-table td:last-child {
  width: 16ch;
  white-space: nowrap;
}

.av {
  display: inline-block;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.5;
  padding: 1px var(--space-2);
}

.av-available {
  background: var(--tint-ok);
  color: var(--ok);
}

.av-taken {
  background: var(--soft);
  color: var(--muted);
}

.av-unknown {
  background: var(--tint-warn);
  color: var(--warn);
}

.av-checking {
  color: var(--muted);
}

.avail-empty td {
  color: var(--muted);
  padding: var(--space-5-5) var(--space-3);
  text-align: center;
}

/* The home page is centred - the mark, the wordmark, the search box, the row
   of examples - so the panel and everything in it is too. What sat wrong before
   was the contents, not the box: left-aligned figures set in sans. */
.stats-panel {
  max-width: 680px;
  margin: var(--space-7-5) auto 0;
  text-align: center;
}

.stats-topline {
  margin-bottom: var(--space-3-5);
  color: var(--muted);
  font-size: var(--text-md);
}

.stats-topline span {
  color: var(--text);
}

.stats-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  overflow: hidden;
  /* The gap shows through as the rule between cells. */
  background: var(--hairline);
}

.stat-cell {
  display: block;
  /* Three across when they fit, then two with the last one filling the row,
     then one. The basis is the wrap point; grow is what closes the gap. */
  flex: 1 1 12rem;
  min-width: 0;
  background: var(--surface);
  color: inherit;
  padding: var(--space-4) var(--space-3-5);
  text-decoration: none;
  transition:
    background var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.stat-cell:hover {
  background: var(--soft);
  color: inherit;
  text-decoration: none;
}

/* Inset, because `.stats-grid` clips an outset ring against its own corners. */
.stat-cell:focus-visible {
  position: relative;
  z-index: 1;
  outline: none;
  box-shadow: inset 0 0 0 2px var(--accent);
}

/* Mono, like every other figure on the site - the table cells, the selected
   count, the example links. */
.stat-value {
  color: inherit;
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  line-height: 1.1;
}

/* Muted under the number rather than level with it: the number is the thing
   being read, and two lines of full-strength text at different sizes read as
   two competing lines rather than one figure and its name. */
.stat-label {
  margin-top: var(--space-1);
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.25;
}

.tlds-table-wrap {
  margin-top: var(--space-4-5);
}

.tlds-table th:first-child,
.tlds-table td:first-child {
  width: 10ch;
  white-space: nowrap;
}

/* Wide enough for the longest suffix in the index without wrapping. The cells
   are 12px mono, so a character is ~7.2px: `.higashihiroshima.hiroshima.jp` is
   30 of them, plus the lock's slot and the cell's own padding. At 25ch even
   `.fujisawa.kanagawa.jp` went to two lines. */
.tlds-table th:nth-child(2),
.tlds-table td:nth-child(2) {
  width: 36ch;
}

.tlds-table th:nth-child(3),
.tlds-table td:nth-child(3),
.tlds-table th:nth-child(4),
.tlds-table td:nth-child(4) {
  width: 16ch;
  text-align: right;
  white-space: nowrap;
}

.tlds-table th:last-child,
.tlds-table td:last-child {
  text-align: right;
}

.tld-rank,
.tld-domain-count,
.tld-share {
  font-variant-numeric: tabular-nums;
}

.tld-rank {
  color: var(--muted);
}

.tld-cell {
  min-width: 0;
}

/* Plain inline, so the dot and the name sit in one line box and read as the
   single string ".com". As grid items they were separate boxes, which put a
   line break between them in the rendered text and made Ctrl+F for ".com" find
   nothing. */
.tld-link {
  max-width: 100%;
  color: var(--text);
  text-decoration: none;
}

.tld-link:hover {
  color: var(--accent);
  text-decoration: none;
}

/* A long name wraps rather than being cut off with an ellipsis. Truncating hid
   data and needed the grid that broke find-in-page. */
.tld-link span:last-child {
  overflow-wrap: anywhere;
}

.tld-ascii {
  display: block;
  margin-top: var(--space-0-5);
  color: var(--muted);
  font-size: var(--text-xs);
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* The sprite is a definition, not a picture: no space, and nothing for a
   find-in-page to land on. */
.icon-sprite {
  display: none;
}

/* A lock says "you cannot register here" without a word that could be read as
   "this shut down". Sized off the scale at 1rem against the row's 0.9375rem
   text, so it reads without growing the row. */
.tld-closed {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-right: var(--space-1);
  color: var(--err);
  vertical-align: middle;
}

.tld-closed svg {
  width: 0.8rem;
  height: 0.8rem;
  fill: currentColor;
}

/* The pointer affordance. Set in the same recipe as every other raised surface
   on the site - `.card` and its siblings - and at the table's own size, so it
   does not shout over the rows it is explaining.

   What it says is also the badge's `title` and is spelled out again in the note
   above the table, so nothing here is the only copy of the meaning. A tooltip
   that was would be unreachable on touch and to keyboard users. */
.tld-closed::after {
  content: attr(data-tip);
  position: absolute;
  left: calc(100% + var(--space-2));
  top: 50%;
  z-index: 2;
  width: max-content;
  max-width: 24rem;
  padding: var(--space-2) var(--space-3);
  transform: translateY(-50%);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  line-height: 1.5;
  white-space: normal;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease);
}

.tld-closed:hover::after {
  opacity: 1;
}

/* A pointer that cannot hover gets nothing but a flicker on tap, so the tooltip
   stays out of its way and the note above the table carries the meaning. */
@media (hover: none) {
  .tld-closed::after {
    content: none;
  }
}

.tld-dot {
  opacity: 0.5;
}

.source-badges {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1-5);
  justify-content: flex-end;
}

.source-badge {
  display: inline-flex;
  align-items: center;
  min-height: 1.375rem;
  border-radius: var(--radius-sm);
  background: var(--soft);
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  line-height: 1.2;
  padding: var(--space-1) var(--space-2);
}

.source-badge-empty {
  color: var(--muted);
}

.page-title,
.card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.page-title > *,
.card-head > * {
  min-width: 0;
}

.page-title {
  margin: 0 0 var(--space-4-5);
}

.domain-card h2 {
  overflow-wrap: anywhere;
}

/* Sits inside the heading rather than beside it, so that when a long name
   wraps the icon follows the last line instead of stranding itself out to the
   right of the first. Sized in `em` to track the heading, and set on the
   baseline, where 0.72em reaches cap height and the glyph lines up with the
   letters it follows. The padding is hit area only - it is outside the box the
   baseline is measured from, so it widens the target to about 27px without
   moving the drawing. */
.visit-site {
  display: inline-block;
  margin-left: var(--space-1);
  padding: 0.25em;
  color: var(--muted);
  line-height: 1;
  text-decoration: none;
}

.visit-site:hover,
.visit-site:focus-visible {
  color: var(--accent);
}

.visit-site svg {
  display: inline-block;
  width: 0.72em;
  height: 0.72em;
  vertical-align: baseline;
}

/* Right-hand side of the domain header. `.card-head` is already a flex row
   with `space-between`, so this needs no positioning - only a refusal to
   shrink, since the name beside it is `min-width: 0` and would otherwise take
   the space from here instead of wrapping. 56px, which matches the height of
   the two headings beside it. */
.site-favicon {
  flex: none;
  width: var(--space-14);
  height: var(--space-14);
  border-radius: var(--radius-md);
}

.page-title p,
.card-head p,
.muted-line {
  margin: var(--space-1) 0 0;
}

.card {
  margin: 0 0 var(--space-4);
  padding: clamp(var(--space-4), 3vw, var(--space-4-5)) clamp(var(--space-4), 4vw, var(--space-5));
}

.result-card {
  display: grid;
  gap: var(--space-3-5);
  margin-top: var(--space-4-5);
}

.crumbs {
  margin: var(--space-4-5) var(--space-0-5) calc(var(--space-1-5) * -1);
  color: var(--muted);
  font-size: var(--text-sm);
}

.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.crumbs a {
  color: inherit;
  text-decoration: none;
}

.crumbs a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* Separator drawn in CSS rather than typed into the markup, so a copied trail
   is just the names. It hangs off the list item, not the link: as a pseudo
   element of the link it sat inside the anchor and picked up its hover
   underline, so hovering ".limo" also underlined the "/" beside it. */
.crumbs li + li::before {
  content: "/";
  margin-right: var(--space-2);
  opacity: 0.7;
}

.result {
  display: grid;
  gap: var(--space-3-5);
  margin-top: var(--space-4-5);
}

.result .card,
.result .result-card {
  margin: 0;
}

.result-actions {
  margin: calc(var(--space-0-5) * -1) var(--space-0-5) 0;
  color: var(--muted);
  font-size: var(--text-md);
}

.result-actions a {
  color: inherit;
}

.card-error {
  border-color: var(--edge-err);
  background: var(--tint-err);
}

.err {
  color: var(--err);
}

.card-error .err {
  margin: 0;
}

dl {
  display: block;
  margin: 0;
  font-size: var(--text-base);
}

.card dl {
  margin: 0 calc(var(--space-2-5) * -1);
}

/* Label beside value until the value has nowhere left to go, then stacked -
   which is what the 460px breakpoint used to do at a fixed width. The wrap
   point is the sum of the two flex bases, so it follows the text rather than
   the viewport. */
dl .row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1-5) var(--space-5);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-2-5);
  transition: background var(--dur) var(--ease);
}

dl .row:hover {
  background: var(--tint-accent-ghost);
}

dl .row > dt {
  flex: 0 0 8.125rem;
}

dl .row > dd {
  /* The wrap point: once the value cannot hold 12rem beside the label, the two
     stack. */
  flex: 1 1 12rem;
}

dt {
  color: var(--muted);
  overflow-wrap: anywhere;
}

dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.empty-state {
  color: var(--muted);
  font-size: var(--text-base);
  padding: var(--space-3-5) var(--space-0-5);
  text-align: center;
}

.summary-table-wrap {
  margin-top: var(--space-3);
}

/* Sideways scrolling inside the box, for a table that cannot be made to fit.
   The gradient pairs are a scroll shadow, so this only belongs where scrolling
   can actually happen. Anything carrying it is not a sticky-header candidate: a
   scroll container with no height cap gives `position: sticky` nothing to stick
   to. `.tlds-table-wrap` spells the same block out inside the one breakpoint,
   because a rule cannot gain a selector from inside a media query. */
.table-x-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background-image:
    linear-gradient(to right, var(--surface), transparent),
    linear-gradient(to left, var(--surface), transparent),
    linear-gradient(to right, var(--shadow-scroll), transparent),
    linear-gradient(to left, var(--shadow-scroll), transparent);
  background-repeat: no-repeat;
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-size: 32px 100%, 32px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* Sticky against the viewport, which needs no scroll container between the
   header and the page. That is why the wrap no longer has one. */
.tlds-table th,
.availability-table th,
.change-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--hairline);
}

.summary-table td a {
  color: var(--accent);
  text-decoration: none;
}

.summary-table td a:hover {
  text-decoration: underline;
}

/* No horizontal floor: cells wrap and the table grows downwards rather than
   pushing a sideways scrollbar onto the page. */
.summary-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.data-group-card,
.dns-record-card {
  gap: var(--space-2-5);
}

.dns-record-table-wrap {
  margin-top: 0;
}

.dns-records th:first-child,
.dns-records td:first-child,
.dns-records th:nth-child(3),
.dns-records td:nth-child(3) {
  width: 10ch;
  white-space: nowrap;
}

.dns-records th:nth-child(2),
.dns-records td:nth-child(2) {
  width: 26ch;
}

.dns-values {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2-5);
}

.dns-values span {
  overflow-wrap: anywhere;
}

.change-card {
  gap: var(--space-2-5);
}

.change-table-wrap {
  margin-top: 0;
}

/* Scoped to the column heads and body rows: the event heading is also a
   first-child th, and must not pick up a column width. */
.change-table thead th:first-child,
.change-table tbody td:first-child {
  width: 20ch;
  white-space: nowrap;
}

/* Each refresh is its own tbody headed by its timestamp, so the date is stated
   once per event and never looks like a blank cell. The header spans the table
   and opts out of the uppercase label treatment the column heads use. */
/* The flex row lives inside the cell. Setting `display: flex` on the th itself
   drops it out of table layout, and its colspan stops applying. */
.change-at-line {
  display: flex;
  gap: var(--space-3);
  justify-content: space-between;
}

.change-table .change-at {
  border-top: 1px solid var(--hairline);
  background: var(--surface-raised);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}

.change-table tbody:first-of-type .change-at {
  border-top: 0;
}

.change-event-size {
  font-weight: 400;
}

.change-from {
  color: var(--muted);
}

.change-more {
  margin: 0;
  color: var(--muted);
  font-size: var(--text-md);
}

.change-more a {
  color: inherit;
}

.summary-table th,
.summary-table td {
  border-bottom: 1px solid var(--hairline);
  padding: var(--space-2) var(--space-2-5);
  text-align: left;
  vertical-align: top;
}

.summary-table td {
  overflow-wrap: anywhere;
  line-height: 1.45;
}

.summary-table td small {
  display: block;
}

.summary-table td small {
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
}

.summary-table tr:last-child td {
  border-bottom: 0;
}

.summary-table tbody tr:hover {
  background: var(--tint-accent-ghost);
}

.qb-app {
  display: grid;
  gap: var(--space-3-5);
}

/* The builder is wrapped in a GET form so Run is a submit. The form is a
   grouping element, not a layout one: `contents` keeps the builder, the
   actions and the preview as grid items of `.qb-app`, which is where the gap
   between them comes from. */
.qb-form {
  display: contents;
}

/* Grid items default to `min-width: auto`, whose content-based minimum is the
   min-content width of the results table (nowrap cells make that enormous).
   Without this the item outgrows its track and the scroll wrapper inside it
   never gets the chance to scroll. Same reasoning for the lookup result cards. */
.qb-app > *,
.result > * {
  min-width: 0;
}

.qb-loading,
.qb-note {
  color: var(--muted);
  font-size: var(--text-base);
  padding: var(--space-1) var(--space-0-5);
}

.qb-builder,
.qb-preview {
  overflow: hidden;
}

.qb-builder > summary,
.qb-preview > summary {
  display: flex;
  align-items: baseline;
  gap: var(--space-2-5);
  cursor: pointer;
  list-style: none;
  padding: var(--space-3) var(--space-4);
}

.qb-builder > summary::-webkit-details-marker,
.qb-preview > summary::-webkit-details-marker {
  display: none;
}

.qb-builder > summary::before,
.qb-preview > summary::before {
  display: inline-block;
  content: ">";
  opacity: 0.7;
  font-size: var(--text-xs);
  /* `transform` does not apply to a non-replaced inline box, so without the
     inline-block above the caret never turned and open looked like closed. */
  transition: transform var(--dur) var(--ease);
}

.qb-builder[open] > summary::before,
.qb-preview[open] > summary::before {
  transform: rotate(90deg);
}

/* `overflow: hidden` on the details clips an outset ring, so this one is inset. */
.qb-builder > summary:focus-visible,
.qb-preview > summary:focus-visible {
  box-shadow: inset 0 0 0 2px var(--accent);
  outline: none;
}

.qb-builder > summary:hover,
.qb-preview > summary:hover {
  background: var(--soft);
}

/* The only view of the active filters while the builder is collapsed, which is
   its state on every results page, so it wraps rather than being cut off. */
.qb-expr {
  flex: 1;
  min-width: 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.qb-hint {
  color: var(--muted);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

.qb-builder-body {
  display: grid;
  gap: var(--space-3-5);
  border-top: 1px solid var(--hairline);
  padding: var(--space-4);
}

.qb-sublabel {
  margin: var(--space-0-5) 0 calc(var(--space-1-5) * -1);
}

.qb-line {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4-5);
}

.qb-field-block {
  display: grid;
  gap: var(--space-1-5);
}

.qb select,
.qb input[type="text"],
.qb input[type="number"] {
  width: auto;
  min-height: var(--control-h);
  padding: var(--space-2) var(--space-2-5);
  font-size: var(--text-md);
}

.qb select {
  min-width: 8.25rem;
}

.qb-limit {
  max-width: min(5.75rem, 100%);
}

.qb-fields-block {
  flex: 1 1 22.5rem;
}

.qb-fields {
  width: 100%;
  min-width: 0;
}

.qb-sortlist {
  display: grid;
  gap: var(--space-2);
}

.qb-sort-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.qb-filter {
  display: grid;
}

.qb-group {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface-sunk);
  padding: var(--space-2-5) var(--space-3);
}

.qb-cond {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.qb-conj {
  margin: var(--space-2) 0 var(--space-2) var(--space-0-5);
  font-weight: 400;
}

.qb-field {
  flex: 1 1 40%;
  min-width: 0;
}

.qb-op {
  flex: 0 1 22%;
  min-width: 0;
}

.qb-value {
  flex: 2 1 45%;
  min-width: 0;
}

.qb-and {
  margin-top: var(--space-2-5);
}

.qb-or-div {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  margin: var(--space-3) 0;
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
}

.qb-or-div::before,
.qb-or-div::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--edge-accent);
}

.qb-or {
  justify-self: start;
  margin-top: var(--space-2-5);
}

.qb-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2-5);
  padding: 0 var(--space-0-5);
}

/* The server-rendered pager uses anchors so paging works without JavaScript;
   they take the same styling as the buttons the script draws. */
a.qb-btn,
.qb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  text-decoration: none;
  white-space: nowrap;
  min-height: var(--control-h-sm);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--text-sm);
  padding: var(--space-1-5) var(--space-3);
}

.qb-btn-off {
  opacity: 0.45;
  pointer-events: none;
}

.qb-del {
  padding-right: var(--space-2-5);
  padding-left: var(--space-2-5);
}

.qb-del:hover {
  border-color: var(--edge-err);
  background: var(--tint-err);
  color: var(--err);
}

.qb-run {
  min-height: var(--control-h);
  padding-right: var(--space-4-5);
  padding-left: var(--space-4-5);
}

.qb-status {
  margin-left: auto;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.qb-preview pre {
  max-height: var(--panel-max-height);
  overflow: auto;
  border-top: 1px solid var(--hairline);
  border-radius: 0;
}

.qb-results {
  min-height: 2.5rem;
}

/* One table per resource, so the groups need separating. */
.qb-result-group + .qb-result-group {
  margin-top: var(--space-5-5);
}

.qb-resources {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1-5);
}

/* A chip rather than a bare checkbox, so the whole label is the hit target and
   a checked resource reads as selected at a glance. */
.qb-chk {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--muted);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  min-height: var(--control-h);
  padding: 0 var(--space-3);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.qb-chk:hover {
  border-color: var(--edge-accent);
  color: var(--text);
}

.qb-chk:has(input:checked) {
  border-color: var(--edge-accent-strong);
  background: var(--tint-accent);
  color: var(--text);
}

.qb-chk input {
  width: auto;
  min-height: 0;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

/* The ring belongs on the chip, not on the box inside it, so keyboard focus
   outlines the thing that looks clickable. */
.qb-chk input:not(:focus-visible) {
  box-shadow: none;
}

.qb-chk:has(input:focus-visible) {
  box-shadow: var(--focus);
}

.qb-results-meta {
  margin-bottom: var(--space-2);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.qb-error {
  border: 1px solid var(--edge-err);
  border-radius: var(--radius-md);
  background: var(--tint-err);
  color: var(--err);
  font-size: var(--text-md);
  padding: var(--space-3) var(--space-3-5);
  white-space: pre-wrap;
  word-break: break-word;
}

.qb-results-table {
  width: auto;
  min-width: 100%;
}

.qb-results-table th,
.qb-results-table td {
  overflow-wrap: normal;
  white-space: nowrap;
  word-break: normal;
}

/* No max-width and no ellipsis. Clipping a cell at 340px left its full value
   reachable only through the `title`, which is invisible on touch and to
   keyboard users, so it does not count as an escape.
   Cells stay `nowrap`, so a long one widens the table and the scroll container
   above reaches it. */
.qb-results-table td {
  font-size: var(--text-sm);
}


.qb-pager {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  margin-top: var(--space-3-5);
}

.qb-pager-top {
  margin-top: 0;
  margin-bottom: var(--space-2-5);
}


.fade-in {
  animation: fade-in var(--dur-slow) var(--ease) both;
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.site-footer {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2-5) var(--space-4-5);
  margin-top: var(--space-8-5);
  border-top: 1px solid var(--hairline);
  color: var(--muted);
  font-size: var(--text-md);
  padding-top: var(--space-3-5);
}

.site-footer > * {
  min-width: 0;
  max-width: 100%;
}

.footer-nav,
.nav-links {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3-5);
}

.footer-nav {
  justify-content: flex-end;
}

.nav-links a {
  color: var(--accent);
}

@media (max-width: 680px) {
  /* A field name is one long token; below this it has to be allowed to break
     or it pushes the other two columns off the page. */
  .change-table thead th:first-child,
  .change-table tbody td:first-child {
    white-space: normal;
  }

  /* Five numeric columns do not fit a phone, and the longest TLD is a
     24-character punycode label that Chrome will not break when sizing an
     auto-layout column. Scroll the table inside its own box rather than let it
     push the page sideways. Above this width it fits and needs no container,
     which is what keeps the header sticky there. */
  .tlds-table-wrap {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    background-image:
      linear-gradient(to right, var(--surface), transparent),
      linear-gradient(to left, var(--surface), transparent),
      linear-gradient(to right, var(--shadow-scroll), transparent),
      linear-gradient(to left, var(--shadow-scroll), transparent);
    background-repeat: no-repeat;
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-size: 32px 100%, 32px 100%, 12px 100%, 12px 100%;
    background-attachment: local, local, scroll, scroll;
  }

  .brand {
    align-items: flex-start;
  }

  body.home-empty .page {
    padding-top: var(--space-10-5);
  }

  .avail-filters input[type="search"],
  .avail-filters select {
    flex: 1 1 9.375rem;
  }

  .qb-status {
    flex-basis: 100%;
    margin-left: 0;
  }
}

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

  button:active,
  .example-link:active {
    transform: none;
  }
}

/* Search stats
   ------------------------------------------------------------------------ */

/* The filters stack above the tables rather than sitting in a bar: there are
   two of them and they read as a sentence, label then options. */
.stats-filter {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
}

.stats-filter-options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1-5);
}

/* The chosen filter, marked by the same attribute that tells a screen reader.
   Same three tokens as a checked `.qb-chk`, so a selection looks like every
   other selection on the site. */
a.qb-btn[aria-current] {
  border-color: var(--edge-accent-strong);
  background: var(--tint-accent);
  color: var(--text);
}

.stats-browser h3 {
  margin: var(--space-5-5) 0 0;
}

/* Figures read down their column, so they align right and take the mono
   numerals every other figure on the site uses. */
.stats-table th:not(:first-child),
.stats-table td:not(:first-child) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* The label column takes the slack, so widening the page spreads the labels
   rather than pushing the figures apart. Capping the table instead would only
   move the empty space outside it. */
.stats-table th:first-child,
.stats-table td:first-child {
  width: 40%;
}

/* Nothing here wraps: a date or a label broken across two lines makes every
   row a different height and the column impossible to scan. Five columns
   cannot be made to fit a narrow phone, so the wrap carries `.table-x-scroll`
   and the scrolling stays inside the box rather than becoming the page's. */
.stats-table th,
.stats-table td {
  white-space: nowrap;
}

/* A period's own figures, with its breakdown beneath. Set forward so the
   group reads as one block rather than as five unrelated rows. */
.stats-table .stats-total > td {
  background: var(--surface-raised);
}

.stats-table .stats-total:hover > td {
  background: var(--tint-accent-ghost);
}

/* The per-type rows sit under the period they break down. */
.stats-table .stats-sub td:first-child {
  padding-left: var(--space-5);
}

.stats-table .stats-sub td {
  color: var(--muted);
}

/* The slash belongs to neither figure, so it sits back from both. */
.stats-pair-sep {
  padding: 0 var(--space-1);
  color: color-mix(in srgb, var(--muted) 45%, transparent);
}

/* A zero is the absence of a figure rather than one to read. Faded through
   the colour, not `opacity`, which would take the cell's background with it
   and punch a hole in the row behind it. */
.stats-table .stats-zero {
  color: color-mix(in srgb, var(--muted) 55%, transparent);
}

/* `.summary-table` drops the rule under its last row, and with one tbody per
   period that is every period holding a single row. Put it back, and take it
   off only under the genuine last one, where the totals' own line follows. */
.stats-table tbody tr:last-child td {
  border-bottom: 1px solid var(--hairline);
}

.stats-table tbody:last-of-type tr:last-child td {
  border-bottom: 0;
}

/* The totals row is a summary of the column, not another entry in it. */
.stats-table tfoot td {
  border-top: 1px solid var(--hairline);
  border-bottom: 0;
}

/* Search results
   ------------------------------------------------------------------------- */

/* The term is the page's subject, the way a domain is on a lookup page, so it
   is the heading - and like that one it wraps rather than running off. */
.sr-term {
  overflow-wrap: anywhere;
}

.sr-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Hairlines inside the one card rather than a card each: forty bordered boxes
   is forty boxes to read past, where a list is one. Matches the rhythm of the
   `dl .row` groups the lookup card stacks. */
.sr-item {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--hairline);
}

/* The icon's own column. A tile rather than nothing underneath, because most
   names have no icon to serve and a ragged left edge reads as broken where a
   quiet placeholder reads as "no icon".

   `--hairline` rather than a surface colour: this one is always inside a card,
   so it has to differ from `--surface` in both modes, which is the opposite of
   what a control's fill needs. It is the same use `.stats-grid` makes of it -
   a quiet fill rather than a line. */
.sr-icon {
  flex: none;
  width: var(--space-6);
  height: var(--space-6);
  margin-top: var(--space-0-5);
  border-radius: var(--radius-sm);
  background: var(--hairline);
}

/* Grid items and flex items both default to a content-based minimum, which a
   long email in a value would push the whole row wider than the card. */
.sr-body {
  flex: 1 1 auto;
  min-width: 0;
}

.sr-item:first-child {
  padding-top: var(--space-1);
}

.sr-item:last-child {
  padding-bottom: var(--space-1);
  border-bottom: 0;
}

/* The name leads. One step above the body, which is where `h2` starts from two
   steps higher: a result is a preview of a record page, not a page of its own,
   and twenty headings at full size is a wall. */
.sr-name {
  font-size: var(--text-xl);
}

/* The record's own summary, under the name: registrar, date, sources. */
.sr-meta {
  margin: var(--space-1) 0 0;
  color: var(--muted);
  font-size: var(--text-md);
}

/* Why the row is here. Mono and accented like every other read value on the
   site; the weight stays with the wordmark. */
.sr-value {
  color: var(--accent);
  font-family: var(--font-mono);
}

/* A centred strip of numbers, laid out like the `examples` row on the landing
   page - the same shape of thing, a row of small links the reader picks from. */
.sr-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-1-5) var(--space-2);
  margin-top: var(--space-6);
}

/* Where the reader is: the chip, marked rather than removed, so the strip does
   not change width as they page through it. */
.sr-pager .sr-here {
  border-color: var(--edge-accent-strong);
  background: var(--tint-accent);
  color: var(--accent);
}

/* The jump over the pages the strip does not reach. Not a control. */
.sr-gap {
  color: var(--muted);
  padding: 0 var(--space-0-5);
}
