/* =========================================================================================
   pleoralicenses UI (uv-pleora-license-management).

   Started from the reference service's app.css (the UVeye internal-tools design language, see
   docs/design/DESIGN.md): #f07828 accent, #091f34 navy, Manrope 400 for display text, Inter Tight
   for body and UI, JetBrains Mono for machine identifiers. The palette is defined in full on bare
   :root, then REDEFINED under prefers-color-scheme and again under [data-theme]; a new token must be
   added to ALL THREE blocks or one mode is left undefined.

   There is no JavaScript on these pages and no inline style (the CSP forbids both): every action is
   a link or a form POST, and widths such as the remaining bar are quantized classes.
   ========================================================================================= */

:root {
  --navy:        #091f34;
  --navy-soft:   rgb(9 31 52 / .70);
  --navy-faint:  rgb(9 31 52 / .46);
  --orange:      #f07828;
  --orange-hi:   #d65f0f;
  --ground:      #fbfcfd;
  --surface:     #eff5fa;
  --border:      #d2e3f0;
  --border-firm: #b9cfe2;
  --ok:          #1f7a55;
  --warn:        #b26a00;
  --danger:      #b3261e;
  --ring:        rgb(240 120 40 / .28);
  --shadow:      0 1px 2px rgb(9 31 52 / .05), 0 8px 24px -12px rgb(9 31 52 / .18);
  color-scheme:  light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --navy:        #eaf1f7;
    --navy-soft:   rgb(234 241 247 / .72);
    --navy-faint:  rgb(234 241 247 / .46);
    --orange:      #ff8c3f;
    --orange-hi:   #ffa463;
    --ground:      #020303;
    --surface:     #0d1a26;
    --border:      #1c3145;
    --border-firm: #2a4459;
    --ok:          #4cc08c;
    --warn:        #e0a44a;
    --danger:      #f2766b;
    --ring:        rgb(255 140 63 / .32);
    --shadow:      0 1px 2px rgb(0 0 0 / .4), 0 8px 24px -12px rgb(0 0 0 / .7);
  }
}

:root[data-theme="dark"] {
  --navy:        #eaf1f7;
  --navy-soft:   rgb(234 241 247 / .72);
  --navy-faint:  rgb(234 241 247 / .46);
  --orange:      #ff8c3f;
  --orange-hi:   #ffa463;
  --ground:      #020303;
  --surface:     #0d1a26;
  --border:      #1c3145;
  --border-firm: #2a4459;
  --ok:          #4cc08c;
  --warn:        #e0a44a;
  --danger:      #f2766b;
  --ring:        rgb(255 140 63 / .32);
  --shadow:      0 1px 2px rgb(0 0 0 / .4), 0 8px 24px -12px rgb(0 0 0 / .7);
}

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--navy-soft);
  font-family: "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.shell {
  min-height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
  padding-inline: 20px;
}

.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-block: 56px 32px;
  gap: 26px;
}

.stage.has-results { justify-content: flex-start; padding-block: 72px 32px; }

/* ---- wordmark ---- */
.mark {
  font-family: Manrope, system-ui, sans-serif;
  font-weight: 400;
  font-size: clamp(2rem, 6vw, 2.9rem);
  letter-spacing: -0.022em;
  color: var(--navy);
  margin: 0;
  text-wrap: balance;
  text-align: center;
}

.mark a { color: inherit; text-decoration: none; }
.mark .dot { color: var(--orange); font-weight: 500; }

.tagline {
  margin: 8px 0 0;
  text-align: center;
  color: var(--navy-faint);
  font-size: .9375rem;
}

/* ---- forms ---- */
/* Scoped: an element selector here would stretch the inline row forms (Disable, Sign out). */
form.stack { width: 100%; max-width: 40rem; display: grid; gap: 14px; }

.field {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--ground);
  border: 1px solid var(--border-firm);
  border-radius: 999px;
  padding: 6px 6px 6px 22px;
  box-shadow: var(--shadow);
  transition: border-color .15s ease, box-shadow .15s ease;
}

.field:focus-within {
  border-color: var(--orange);
  box-shadow: var(--shadow), 0 0 0 4px var(--ring);
}

.field input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: 1.0625rem;
  color: var(--navy);
  padding-block: 12px;
}

.field input::placeholder { color: var(--navy-faint); }

/* The admin setup pages pick a group or a factory from a closed list. */
.field select {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: 1.0625rem;
  color: var(--navy);
  padding-block: 12px;
}

/* The add-pool form pastes a long Pleora URL: a textarea inside the same field chrome. */
.field textarea {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: 1.0625rem;
  color: var(--navy);
  padding-block: 12px;
  resize: vertical;
}

.field textarea::placeholder { color: var(--navy-faint); }

[hidden] { display: none !important; }

.go {
  flex: 0 0 auto;
  height: 44px;
  padding-inline: 28px;
  border: 0;
  border-radius: 999px;
  background: var(--orange);
  color: #fff;
  font-family: "Inter Tight", sans-serif;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: .01em;
  cursor: pointer;
  transition: background .15s ease;
}

/* The same pill as a link (the group page's "Add pool"). */
a.go { display: inline-flex; align-items: center; text-decoration: none; }

.go:hover { background: var(--orange-hi); }
.go:focus-visible { outline: 3px solid var(--navy); outline-offset: 2px; }

.examples {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
}

.examples span { color: var(--navy-faint); font-size: .8125rem; padding-block: 5px; }

/* Anchors, not buttons: with no JavaScript on the page every example is a real navigation. */
.chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--navy-soft);
  border-radius: 999px;
  padding: 5px 13px;
  font: inherit;
  font-size: .8125rem;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}

.chip:hover { border-color: var(--orange); color: var(--navy); }
.chip:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* ---- results ---- */
.results { width: 100%; max-width: 40rem; display: grid; gap: 10px; }
.results:empty { display: none; }

.verdict {
  font-size: .8125rem;
  color: var(--navy-faint);
  letter-spacing: .04em;
  text-transform: uppercase;
  margin: 12px 0 2px;
}

.results > .verdict:first-child { margin-top: 0; }

.hit {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  text-decoration: none;
  color: inherit;
  transition: border-color .15s ease;
}

.hit:hover { border-color: var(--orange); }
.hit:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
.hit .body { flex: 1 1 auto; min-width: 0; }

.hit .pu {
  font-family: Manrope, sans-serif;
  font-size: 1.0625rem;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.hit .where {
  font-size: .8125rem;
  color: var(--navy-faint);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.hit .arrow { flex: 0 0 auto; color: var(--orange); font-size: 1.25rem; line-height: 1; }

/* A stored entry whose FQDN is not on the redirect allowlist. It is SHOWN, so an operator can
   see what is in the index, but it is a <div> rather than an <a>: there is no safe URL to
   offer and the page must never invent one. */
.hit.unlinkable { border-style: dashed; cursor: default; }
.hit.unlinkable:hover { border-color: var(--border); }
.hit .blocked { flex: 0 0 auto; font-size: .75rem; color: var(--warn); }

.state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  font-size: .75rem;
  letter-spacing: .03em;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  color: var(--navy-faint);
  border-color: var(--border);
}

.state.active { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.state.degraded,
.state.unavailable,
.state.error { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.state::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* Fuzzy suggestions: same card, one extra signal. The score is shown because a human deciding
   whether to trust a guess deserves to see how close it actually was. */
.hit .score {
  flex: 0 0 auto;
  font-size: .75rem;
  color: var(--navy-faint);
  font-variant-numeric: tabular-nums;
}

.miss {
  border: 1px dashed var(--border-firm);
  border-radius: 14px;
  padding: 22px;
  text-align: center;
}

.miss p { margin: 0 0 6px; color: var(--navy); }
.miss small { color: var(--navy-faint); }

/* ---- paging: one page of a longer prefix result list ---- */
.pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 4px;
  font-size: .8125rem;
  color: var(--navy-faint);
}

.pager .where { font-variant-numeric: tabular-nums; }
.pager a { color: var(--navy); text-decoration: none; }
.pager a:hover { text-decoration: underline; }
.pager .disabled { opacity: .4; }

.notice {
  width: 100%;
  max-width: 40rem;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  border-radius: 14px;
  padding: 14px 18px;
  font-size: .875rem;
  color: var(--navy);
  background: var(--surface);
}

/* ---- footer ---- */
footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 18px;
  padding-block: 18px 26px;
  font-size: .75rem;
  color: var(--navy-faint);
  font-variant-numeric: tabular-nums;
}

footer b { font-weight: 500; color: var(--navy-soft); }
footer .stale b { color: var(--warn); }

/*
  The build this replica is running. flex-basis:100% makes it claim a whole flex line, so it sits
  on its own beneath the freshness stats however many of those wrapped -- centred by the footer's
  own justify-content, and centred WITHIN the line by text-align for the case where the line is
  wider than the text. Quieter than everything above it on purpose: it answers "which version is
  this environment on?" for whoever is asking, and must not compete with the answer the page
  exists to give.

  It is made quieter by SIZE ALONE, and that is deliberate. --navy-faint is ALREADY translucent
  (alpha .46) in both palettes, so an opacity on top of it multiplies: .46 x .7 composites to
  roughly 2:1 against --ground in light mode, under the floor for LARGE text while being smaller
  than the rest of the footer. Do not reach for opacity here; pick a different colour token if
  this ever needs to change.
*/
footer .version {
  flex-basis: 100%;
  text-align: center;
  margin-block-start: 2px;
  font-size: .7rem;
  color: var(--navy-faint);
  letter-spacing: .02em;
}

/* =========================================================================================
   Extensions for the license pages (DESIGN.md): nav row, wide stage, tables, stat tiles, status
   pills, remaining bars, error notice, link buttons. Everything below reuses the tokens above.
   ========================================================================================= */

/* ---- wide stage for table pages, and the content column ---- */
.stage.wide { align-items: stretch; }
.content { width: 100%; max-width: 40rem; display: grid; gap: 12px; }
.stage.wide .content,
.stage.wide .top { max-width: 72rem; margin-inline: auto; }
.content > .notice, .content > .miss, .content > .results { max-width: none; }

/* ---- nav row: wordmark left, plain text links, email and Sign out at the right ---- */
.top {
  width: 100%;
  max-width: 40rem;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 22px;
}

.mark.small { font-size: 1.5rem; text-align: left; text-decoration: none; }
.nav { display: flex; gap: 18px; flex: 1 1 auto; }
.nav a { color: var(--navy); text-decoration: none; }
.nav a:hover { color: var(--orange-hi); }
.who { display: inline-flex; align-items: baseline; gap: 12px; color: var(--navy-faint); font-size: .875rem; }
.who .email { overflow-wrap: anywhere; }

.crumbs { font-size: .875rem; color: var(--navy-faint); }
.crumbs a { color: var(--navy-soft); text-decoration: none; }
.crumbs a:hover { color: var(--orange-hi); }

.title {
  font-family: Manrope, system-ui, sans-serif;
  font-weight: 400;
  font-size: 1.5rem;
  letter-spacing: -0.015em;
  color: var(--navy);
  margin: 4px 0 0;
}

/* ---- inline forms and buttons ---- */
form.inline { display: inline; margin: 0; }

button.link {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--navy-faint);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

button.link:hover { color: var(--navy); }
button.link.danger { color: var(--danger); }
a.danger { color: var(--danger); }
button.link:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

label.input { display: grid; gap: 6px; }
label.input > span:first-child { font-size: .8125rem; color: var(--navy-faint); letter-spacing: .04em; text-transform: uppercase; }
label.input .field { box-shadow: none; padding-left: 18px; }
label.input .field:has(textarea) { border-radius: 14px; }

.mono, .field input.mono, .field textarea.mono {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8125rem;
  font-variant-numeric: tabular-nums;
}

/* ---- tables: quiet, no zebra, no header fill ---- */
.table-wrap { width: 100%; overflow-x: auto; }

table.grid {
  width: 100%;
  border-collapse: collapse;
  font-size: .9375rem;
  font-variant-numeric: tabular-nums;
}

table.grid th {
  font-size: .8125rem;
  font-weight: 400;
  color: var(--navy-faint);
  letter-spacing: .04em;
  text-transform: uppercase;
  text-align: left;
  padding: 8px 12px 8px 0;
  border-bottom: 1px solid var(--border);
}

table.grid td {
  height: 44px;
  padding: 6px 12px 6px 0;
  border-bottom: 1px solid var(--border);
  color: var(--navy);
  vertical-align: middle;
}

table.grid .num { text-align: right; }
table.grid a { color: var(--navy); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- stat tiles ---- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 10px; }

.tile {
  display: grid;
  gap: 4px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}

.tile .label { font-size: .8125rem; color: var(--navy-faint); letter-spacing: .04em; text-transform: uppercase; }

.tile .value {
  font-family: Manrope, system-ui, sans-serif;
  font-weight: 400;
  font-size: 2rem;
  line-height: 1.2;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.tile .hint { font-size: .8125rem; color: var(--navy-faint); }

/* ---- status pills beyond active/degraded ---- */
.state.exhausted,
.state.invalid { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.state.disabled { color: var(--navy-faint); border-color: var(--border); }

/* ---- group cards: an orphaned group is dashed and faint, like an unlinkable hit ---- */
.hit.orphaned { border-style: dashed; opacity: 1; color: var(--navy-faint); }
.hit.orphaned .pu { color: var(--navy-faint); }

/* ---- remaining bar: quantized widths, no inline style (CSP) ---- */
.bar {
  display: inline-block;
  vertical-align: middle;
  width: 8rem;
  height: 6px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}

.bar .fill { display: block; height: 100%; background: var(--ok); border-radius: 999px; }
.bar.low .fill { background: var(--warn); }
.bar.empty .fill { background: var(--danger); }
.bar-text { margin-left: 8px; font-size: .8125rem; color: var(--navy-faint); font-variant-numeric: tabular-nums; }

.w-0 { width: 0; } .w-5 { width: 5%; } .w-10 { width: 10%; } .w-15 { width: 15%; }
.w-20 { width: 20%; } .w-25 { width: 25%; } .w-30 { width: 30%; } .w-35 { width: 35%; }
.w-40 { width: 40%; } .w-45 { width: 45%; } .w-50 { width: 50%; } .w-55 { width: 55%; }
.w-60 { width: 60%; } .w-65 { width: 65%; } .w-70 { width: 70%; } .w-75 { width: 75%; }
.w-80 { width: 80%; } .w-85 { width: 85%; } .w-90 { width: 90%; } .w-95 { width: 95%; }
.w-100 { width: 100%; }

/* ---- the error variant of the notice (Pleora refused the URL, bad OTP) ---- */
.notice.error { border-color: color-mix(in srgb, var(--danger) 40%, transparent); }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
