/* NRP onboarding — shared stylesheet for the request form and the admin
   dashboard.

   Tokens mirrored from the NRP design system: nrp-site/DESIGN.md and
   src/components/CustomStyles.astro on origin/main. This service has no
   Tailwind build, so they are copied rather than imported — if the ramp or the
   surface ladder changes upstream, change it here too. One file, so there is
   one place to change.

   Followed here: the teal ramp sampled from the logo (§2), the surface ladder
   (§2), three faces with three jobs (§3), rounded-md controls and rounded-lg
   cards (§5). No spectrum rule anywhere: it is a hero element, and neither of
   these pages has a hero (§6). */
/* ---------------------------------------------------------------------------
   Tokens mirrored from the NRP design system.

   Source of truth: nrp-site/DESIGN.md and src/components/CustomStyles.astro on
   origin/main. This page is served by a different service and has no Tailwind
   build, so the tokens are copied rather than imported. If the ramp or the
   surface ladder changes there, it has to be changed here too — that is the
   cost of the page being standalone, and it is written down so it is not a
   surprise.

   Followed here: the teal ramp sampled from the logo (§2), the surface ladder
   (§2), three faces with three jobs (§3), rounded-md controls and rounded-lg
   cards (§5), and no spectrum rule — the signature is a hero element, and this
   page has no hero, exactly like /contact and /llmtoken (§6).
--------------------------------------------------------------------------- */

@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/static/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Space Grotesk Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 300 700;
  src: url('/static/fonts/space-grotesk-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'JetBrains Mono Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url('/static/fonts/jetbrains-mono-latin-wght-normal.woff2') format('woff2-variations');
}

:root {
  --nrp-font-display: 'Space Grotesk Variable', ui-sans-serif, system-ui, sans-serif;
  --nrp-font-sans: 'Inter Variable', ui-sans-serif, system-ui, sans-serif;
  --nrp-font-mono: 'JetBrains Mono Variable', ui-monospace, SFMono-Regular, Menlo, monospace;

  --nrp-teal-100: #d3f2f8;
  --nrp-teal-300: #6fd3e5;
  --nrp-teal-400: #56bfd9;
  --nrp-teal-600: #1785a4;
  --nrp-teal-700: #136a85;
  --nrp-teal-800: #14566c;
  --nrp-teal-950: #082e3c;

  --nrp-surface-sunken: #f1f4f8;
  --nrp-surface-page: #ffffff;
  --nrp-surface-2: #eef2f6;
  --nrp-surface-3: #e4eaf0;

  --nrp-text-heading: #0b1620;
  --nrp-text-body: #1c2b38;
  --nrp-text-muted: #4f6072;

  --nrp-link: #136a85;
  --nrp-ring: #1785a4;
  --nrp-border-hairline: #d7dfe7;

  /* Not in DESIGN.md — the system has no error role yet. Chosen to clear 4.5:1
     in both modes (#b3261e on white = 5.94:1). Worth promoting to a token
     upstream rather than leaving each form to invent its own red. */
  --nrp-danger: #b3261e;
  /* Same footnote as --nrp-danger: the system has no success role either.
     #1a7f37 on white is 4.83:1, so a completed step is legible rather than a
     decorative green. */
  --nrp-success: #1a7f37;

  --btn-fill: var(--nrp-teal-700);
  --btn-fill-hover: var(--nrp-teal-800);
  --btn-ink: #ffffff;
}

.dark {
  --nrp-surface-sunken: #070c12;
  --nrp-surface-page: #0a1118;
  --nrp-surface-2: #17242f;
  --nrp-surface-3: #1f303d;

  --nrp-text-heading: #f2f6fa;
  --nrp-text-body: #e2e8ee;
  --nrp-text-muted: #9aa8b8;

  --nrp-link: #6fd3e5;
  --nrp-ring: #56bfd9;
  --nrp-border-hairline: #1e2c39;

  --nrp-danger: #ffb4ab;
  --nrp-success: #7ee2a8;

  /* The ramp flips direction on dark backgrounds (§2). */
  --btn-fill: var(--nrp-teal-400);
  --btn-fill-hover: var(--nrp-teal-300);
  --btn-ink: var(--nrp-teal-950);
}

::selection { background-color: var(--nrp-teal-100); color: var(--nrp-teal-950); }
.dark ::selection { background-color: var(--nrp-teal-800); color: #fff; }

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background-color: var(--nrp-surface-page);
  color: var(--nrp-text-body);
  font-family: var(--nrp-font-sans);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* ---- Layout ------------------------------------------------------------ */

.masthead {
  border-bottom: 1px solid var(--nrp-border-hairline);
}
.masthead-inner {
  max-width: 72rem; margin: 0 auto; padding: 1rem 1rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
@media (min-width: 640px) { .masthead-inner { padding-inline: 1.5rem; } }
.masthead img { display: block; width: 150px; height: auto; }

.wrap { max-width: 72rem; margin: 0 auto; padding: 2.5rem 1rem 5rem; }
@media (min-width: 640px) { .wrap { padding-inline: 1.5rem; } }
/* Measure cap: body copy at 16px lands in the 65-75ch band around 40rem (§3). */
.col { max-width: 42rem; }

/* ---- Type scale (§3) --------------------------------------------------- */

h1 {
  font-family: var(--nrp-font-display);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  line-height: 1.05; letter-spacing: -0.02em; font-weight: 700;
  color: var(--nrp-text-heading);
  margin: 0 0 1rem;
}
h2 {
  font-family: var(--nrp-font-display);
  font-size: 1.375rem; line-height: 1.3; letter-spacing: -0.01em; font-weight: 600;
  color: var(--nrp-text-heading);
  margin: 0 0 .6rem;
}
h3 {
  font-family: var(--nrp-font-display);
  font-size: 1.125rem; line-height: 1.4; font-weight: 600;
  color: var(--nrp-text-heading);
  margin: 0 0 .35rem;
}
.lead { font-size: 1.125rem; line-height: 1.6; color: var(--nrp-text-muted); margin: 0 0 2.5rem; }
.small { font-size: .875rem; }
.muted { color: var(--nrp-text-muted); }
.mono { font-family: var(--nrp-font-mono); }

a.link {
  color: var(--nrp-link); font-weight: 500;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px;
}
a.link:hover { text-decoration-thickness: 2px; }
a.link:focus-visible { outline: 2px solid var(--nrp-ring); outline-offset: 2px; border-radius: 2px; }

/* ---- Cards (§5) -------------------------------------------------------- */

.card {
  background-color: var(--nrp-surface-2);
  border: 1px solid var(--nrp-border-hairline);
  border-radius: .5rem;
  padding: 1.5rem;
}
.card p:last-child { margin-bottom: 0; }
.card p { margin: 0 0 .75rem; }

/* ---- Form -------------------------------------------------------------- */

form { margin-top: 2.5rem; }

.field { margin-bottom: 1.5rem; }
.pair { display: grid; gap: 1.5rem; }
@media (min-width: 40rem) { .pair { grid-template-columns: 1fr 1fr; } }

label { display: block; font-weight: 600; font-size: .9375rem; color: var(--nrp-text-heading); margin-bottom: .375rem; }
.optional { font-weight: 400; color: var(--nrp-text-muted); }
.hint { font-size: .875rem; color: var(--nrp-text-muted); margin: .375rem 0 0; }

input[type=text], input[type=email], input[type=url], textarea, select {
  width: 100%;
  padding: .625rem .75rem;
  font: inherit; font-size: .9375rem;
  color: var(--nrp-text-body);
  background-color: var(--nrp-surface-page);
  /* A control's boundary needs >=3:1, so the hairline is not legal here (§2).
     text-muted rather than the teal ring, following the EndpointPanel copy
     control: it clears contrast in both modes without making every input on
     the page louder than its own label (§6). */
  border: 1px solid var(--nrp-text-muted);
  border-radius: .375rem;
}
textarea { min-height: 5.5rem; resize: vertical; line-height: 1.6; }
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--nrp-ring);
  outline-offset: 1px;
  border-color: var(--nrp-ring);
}
input::placeholder, textarea::placeholder { color: var(--nrp-text-muted); opacity: .8; }
#requested_namespace { font-family: var(--nrp-font-mono); }

fieldset { border: 0; padding: 0; margin: 0; }
legend {
  font-weight: 600; font-size: .9375rem; color: var(--nrp-text-heading);
  padding: 0; margin-bottom: .75rem;
}
.opt { display: flex; gap: .625rem; align-items: flex-start; margin-bottom: .875rem; }
.opt:last-child { margin-bottom: 0; }
.opt input { margin-top: .3rem; flex: none; width: 1rem; height: 1rem; accent-color: var(--btn-fill); }
.opt label { font-weight: 500; margin: 0; color: var(--nrp-text-body); }
.opt .hint { margin-top: .125rem; }

/* ---- Combobox ---------------------------------------------------------- */
/* The institution type-ahead. Same shape as the namespace editor's on nrp.ai:
   an overlay list of selectable rows, not a bulleted list under the field. */

.combo { position: relative; }

.combo-list {
  position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + .25rem);
  margin: 0; padding: .25rem;
  list-style: none;          /* without this the browser draws bullets */
  background-color: var(--nrp-surface-page);
  border: 1px solid var(--nrp-ring);
  border-radius: .375rem;
  max-height: 16rem; overflow-y: auto;
  box-shadow: 0 6px 20px rgb(11 22 32 / 12%);
}
.dark .combo-list { box-shadow: 0 6px 20px rgb(0 0 0 / 45%); }

.combo-list li {
  display: block;
  padding: .5rem .6rem;
  border-radius: .25rem;
  cursor: pointer;
  font-size: .9375rem; line-height: 1.35;
  color: var(--nrp-text-body);
}
.combo-list li[aria-selected="true"],
.combo-list li:hover {
  background-color: var(--nrp-surface-2);
}
/* The acronym and country sit on their own line so a row reads as one entry
   rather than a run-on sentence. */
.combo-list .meta {
  display: block;
  margin-top: .1rem;
  font-size: .8125rem;
  color: var(--nrp-text-muted);
}
/* The always-present escape hatch: keep what you typed. Separated so it does
   not read as one more registry match. */
.combo-list li.free {
  border-top: 1px solid var(--nrp-border-hairline);
  border-radius: 0 0 .25rem .25rem;
  margin-top: .25rem;
  color: var(--nrp-text-muted);
}

.matched {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .8125rem; color: var(--nrp-link);
}

/* ---- Buttons (§5, §6) -------------------------------------------------- */

.btn-primary {
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-weight: 600;
  padding: .75rem 1.75rem;
  border-radius: .375rem;
  border: 1px solid var(--btn-fill);
  background-color: var(--btn-fill);
  color: var(--btn-ink);
  cursor: pointer;
  transition: background-color .2s ease-in, border-color .2s ease-in;
}
.btn-primary:hover:not(:disabled) { background-color: var(--btn-fill-hover); border-color: var(--btn-fill-hover); }
.btn-primary:focus-visible {
  outline: 2px solid var(--nrp-ring); outline-offset: 2px;
}
.btn-primary:disabled { opacity: .6; cursor: default; }

.toggle-theme {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem;
  border: 1px solid var(--nrp-border-hairline); border-radius: .375rem;
  background: transparent; color: var(--nrp-text-muted); cursor: pointer;
}
.toggle-theme:hover { background-color: var(--nrp-surface-2); color: var(--nrp-text-body); }
.toggle-theme:focus-visible { outline: 2px solid var(--nrp-ring); outline-offset: 2px; }
.toggle-theme svg { width: 1.125rem; height: 1.125rem; }
/* Scoped to <html>: a bare `:not(.dark)` also matches <body>, which hid both
   icons at once. */
html.dark .icon-sun { display: none; }
html:not(.dark) .icon-moon { display: none; }

/* ---- States ------------------------------------------------------------ */

.err { color: var(--nrp-danger); font-size: .875rem; margin: .375rem 0 0; }
.field-invalid input { border-color: var(--nrp-danger); }
.hidden { display: none !important; }

.receipt dt { font-size: .875rem; color: var(--nrp-text-muted); margin-bottom: .25rem; }
.receipt dd {
  margin: 0 0 1rem; font-family: var(--nrp-font-mono); font-size: .9375rem;
  color: var(--nrp-text-body); word-break: break-all;
}
.receipt dd:last-child { margin-bottom: 0; }
#status:focus { outline: none; }

/* Guidance, not an error: quiet surface rather than the danger colour. The
   reader has not done anything wrong, they are simply not the right requester. */
.notice {
  background-color: var(--nrp-surface-sunken);
  border: 1px solid var(--nrp-border-hairline);
  border-left: 3px solid var(--nrp-ring);
  border-radius: .375rem;
  padding: 1rem 1.25rem;
  margin: -0.5rem 0 1.5rem;
}
.notice p { margin: 0; font-size: .9375rem; }

/* The receipt's heading becomes the page's only <h1> once the form is gone,
   so it is styled by class rather than by tag. */
.as-h2 {
  font-family: var(--nrp-font-display);
  font-size: 1.375rem; line-height: 1.3; letter-spacing: -0.01em; font-weight: 600;
  color: var(--nrp-text-heading);
  margin: 0 0 .6rem;
}

.plate {
  background-color: var(--nrp-surface-sunken);
  border: 1px solid var(--nrp-border-hairline);
  border-radius: .375rem;
  padding: 1rem 1.25rem;
  margin-top: 1.25rem;
}

/* Rejection notice, shown inline under the Decision actions rather than in a
   modal: the admin needs the request's details visible while editing it. */
.compose {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--nrp-border-hairline);
}
.compose textarea { font-family: var(--nrp-font-mono, monospace); font-size: .8125rem; }
.compose .muted { margin: 0 0 .75rem; font-size: .8125rem; }

/* Candidate accounts. An admin checks IdP and email against the opaque
   CILogon username, so all three stay on screen rather than behind a hover. */
.cand-id { font-weight: 500; }
.cand-user { font-size: .75rem; word-break: break-all; margin-top: .125rem; }
.cand-why { font-size: .8125rem; color: var(--nrp-teal-600); margin-top: .375rem; }
.cand-caution { font-size: .8125rem; color: var(--nrp-danger); margin-top: .25rem; }
.cand-invite { border-style: dashed; }

/* The plan doubles as the record of what happened, so each step carries a
   mark and a word. Colour alone would not be readable to everyone. */
.plan li { position: relative; }
.plan .mark {
  position: absolute; left: -1.85rem; top: 0;
  width: 1.4rem; text-align: center; font-weight: 700;
}
.mark-done { color: var(--nrp-success); }
.mark-failed { color: var(--nrp-danger); }
.mark-skipped { color: var(--nrp-text-muted); }
.mark-running { color: var(--nrp-teal-600); }
.plan li.step-done .act { text-decoration: line-through; text-decoration-thickness: 1px; }
.plan li.step-done .act, .plan li.step-skipped .act { color: var(--nrp-text-muted); }
.outcome { margin: .125rem 0 0; font-size: .8125rem; font-weight: 500; }
.outcome-done { color: var(--nrp-success); }
.outcome-failed { color: var(--nrp-danger); }
.outcome-skipped, .outcome-running { color: var(--nrp-text-muted); }
.step-err { color: var(--nrp-danger); }

/* Namespaces created. Cards rather than rows: each one is a thing you click,
   and the path is the headline. */
.ns-controls { padding: 0 0 .75rem; }
.ns-ranges { display: flex; gap: .375rem; flex-wrap: wrap; margin-bottom: .5rem; }
.ns-controls input[type=text] { width: 100%; font-size: .8125rem; padding: .4rem .6rem; }
.ns-count { font-size: .75rem; margin: .5rem 0 0; }
/* Deliberately the same shape as a queue card (.queue button, defined in
   dashboard.html): both are "a thing in the left column you click". */
.ns-card {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font: inherit; color: inherit;
  background-color: var(--nrp-surface-2);
  border: 1px solid var(--nrp-border-hairline);
  border-radius: .5rem; padding: .75rem .875rem;
}
.ns-card:hover { background-color: var(--nrp-surface-3); border-color: var(--nrp-teal-600); }
.ns-card:focus-visible { outline: 2px solid var(--nrp-ring); outline-offset: 2px; }
.ns-card[aria-current="true"] {
  border-color: var(--nrp-ring); background-color: var(--nrp-surface-3);
}
.ns-path { display: inline-block; font-size: .8125rem; font-weight: 500; word-break: break-all; }
.ns-meta { display: block; font-size: .75rem; color: var(--nrp-text-muted); margin-top: .1875rem; }

/* Event detail. Recorded from the start and never shown, which made the
   history a list of verbs with no objects. */
.log-detail li { display: block; }
.ev-detail { margin-top: .25rem; font-size: .8125rem; color: var(--nrp-text-muted); }
.ev-pair { margin-right: .75rem; }
.ev-pair b { font-weight: 500; }
.ev-error { color: var(--nrp-danger); display: block; margin-bottom: .125rem; }
.outcome-retry { color: var(--nrp-danger); }
.pill-chosen { background: var(--nrp-teal-100); color: var(--nrp-teal-950); }
