/* ═════════════════════════════════════════════════════════════════════════
   NADIS Public Site — Base

   Loaded on every pre-login page, immediately after `tokens.css`. Holds the
   reset, the type registers, the section rhythm, and the components that
   appear on more than one page: header, footer, buttons, links, form
   controls, chips, alerts.

   Page-specific styling lives in `home.css` and `auth.css`.

   SPECIFICITY RULE — read before adding anything

   Vertical spacing between sections is owned by ONE selector: `.nx-section`.
   No element selector and no page stylesheet may set top or bottom padding
   on a section. That single rule is why the rhythm holds together; the
   moment two selectors both claim it, one silently wins and the page starts
   drifting by 20px here and there.

   Everything here is a single class. No `.a .b` descendant chains deeper
   than two levels, no `!important`, no ID selectors.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Reset ───────────────────────────────────────────────────────────────
   Deliberately small. The public pages do not load Bootstrap, so there is
   no framework to undo — only browser defaults to normalise.
   ───────────────────────────────────────────────────────────────────────── */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anything scrolled to via an in-page link clears the sticky header. */
  scroll-padding-top: 88px;
}

body {
  margin: 0;
  background: var(--nx-paper);
  color: var(--nx-ink);
  font-family: var(--nx-font);
  font-size: var(--nx-text-body);
  line-height: var(--nx-leading-body);
  font-weight: 400;

  /* Proportional figures in prose — deliberately NOT the app's global
     tabular-nums.

     The signed-in product turns tabular figures on for everything because
     everything there is a column of money. On a page of sentences it is the
     wrong call twice over. Numbers in running text look gappy, and — the
     reason this was changed rather than argued about — Inter's `tnum` also
     widens U+002D to match the figure advance, because in tabular contexts
     that character is a minus sign. Every hyphenated word on the page came
     out spaced: "Multi-specialty", "follow-ups", "lock-in", "mock-up".

     So the ledger voice is applied where figures are DATA — see `.nx-data`
     below and the components that opt in: labels, chips, the Day Line's
     times, the OTP and phone inputs. That is a sharper version of the same
     idea, not a retreat from it.                                           */
  font-variant-numeric: normal;

  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

img, svg, video { display: block; max-width: 100%; }
img, video { height: auto; }

/* `hidden` must actually hide.

   The UA stylesheet says `[hidden] { display: none }`, but ANY class that
   sets `display` beats it on specificity — `.nx-field { display: block }`
   was enough to leave a hidden field sitting on the page in full view. The
   attribute is the browser's own way of saying "not now", every template
   here uses it, and it has to be reliable rather than something each
   component remembers to respect.

   One of the few justified `!important`s: it exists precisely to win. */
[hidden] { display: none !important; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  font-variant-numeric: inherit;
}

/* ── Focus ───────────────────────────────────────────────────────────────
   Visible, consistent, and never removed. `:focus-visible` means a mouse
   click does not paint a ring, but every keyboard Tab does.

   The one exception to "no element selectors": this has to apply to
   everything focusable, including elements that page CSS has not styled yet.
   ───────────────────────────────────────────────────────────────────────── */
:focus-visible {
  outline: var(--nx-focus-width) solid var(--nx-focus);
  outline-offset: var(--nx-focus-offset);
  border-radius: var(--nx-radius-1);
}

/* Inside the dark band the focus blue is too close to the background to
   read, so the ring goes to paper there. */
.nx-on-dark :focus-visible { outline-color: var(--nx-on-band); }


/* ── Skip link ───────────────────────────────────────────────────────────
   First focusable element on every page. Hidden until focused, then it
   parks itself over the header.
   ───────────────────────────────────────────────────────────────────────── */
.nx-skip {
  position: absolute;
  top: var(--nx-space-2);
  left: var(--nx-space-2);
  z-index: var(--nx-z-skiplink);
  padding: var(--nx-space-3) var(--nx-space-4);
  background: var(--nx-ink);
  color: var(--nx-paper);
  border-radius: var(--nx-radius-2);
  font-size: var(--nx-text-small);
  font-weight: 500;
  text-decoration: none;
  transform: translateY(calc(-100% - var(--nx-space-4)));
  transition: transform var(--nx-dur-base) var(--nx-ease-out);
}
.nx-skip:focus { transform: translateY(0); }


/* ═════════════════════════════════════════════════════════════════════════
   TYPE REGISTERS
   ═════════════════════════════════════════════════════════════════════════ */

/* Register 1 — Display. Used sparingly: one per page, plus section openers. */
.nx-display {
  font-size: var(--nx-text-display);
  font-weight: 620;
  letter-spacing: var(--nx-track-display);
  line-height: var(--nx-leading-display);
  max-width: var(--nx-measure-tight);
  text-wrap: balance;
}

.nx-title {
  font-size: var(--nx-text-title);
  font-weight: 620;
  letter-spacing: var(--nx-track-title);
  line-height: var(--nx-leading-title);
  max-width: 26ch;
  text-wrap: balance;
}

.nx-heading {
  font-size: var(--nx-text-heading);
  font-weight: 600;
  letter-spacing: var(--nx-track-heading);
  line-height: 1.35;
}

/* Register 2 — Text. */
.nx-lead {
  font-size: var(--nx-text-lead);
  line-height: 1.5;
  color: var(--nx-ink-muted);
  max-width: 54ch;
  text-wrap: pretty;
}

.nx-body {
  color: var(--nx-ink-muted);
  max-width: var(--nx-measure);
  text-wrap: pretty;
}

.nx-small {
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
}

/* Register 3 — Label. The ledger voice: this is exactly how the signed-in
   product labels a table column. Repeating it here is what joins the two
   halves of the product together. */
.nx-label {
  display: block;
  font-size: var(--nx-text-label);
  font-weight: 500;
  letter-spacing: var(--nx-track-label);
  text-transform: uppercase;
  color: var(--nx-ink-muted);
  font-variant-numeric: tabular-nums lining-nums;
}

/* Figures that are DATA rather than prose: times, counts, prices, codes,
   masked phone numbers, one-time codes. Same setting the signed-in product
   uses on every table cell, so a number looks the same before and after
   login. Apply it to the smallest element that actually holds the figure —
   never to a paragraph, or hyphens in that paragraph get padded out. */
.nx-data { font-variant-numeric: tabular-nums lining-nums; }
.nx-label--blue  { color: var(--nx-blue); }
.nx-label--green { color: var(--nx-green); }

/* Colour helpers — the only place raw colour is applied to text. */
.nx-ink       { color: var(--nx-ink); }
.nx-muted     { color: var(--nx-ink-muted); }
.nx-accent    { color: var(--nx-blue); }
.nx-accent-2  { color: var(--nx-green); }

/* Screen-reader-only. Text that a sighted reader gets from layout or colour
   but a screen reader would otherwise miss. */
.nx-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ═════════════════════════════════════════════════════════════════════════
   LAYOUT
   ═════════════════════════════════════════════════════════════════════════ */

.nx-wrap {
  width: 100%;
  max-width: var(--nx-page-max);
  margin-inline: auto;
  padding-inline: var(--nx-gutter);
}
.nx-wrap--narrow { max-width: 860px; }

/* THE section rhythm rule. Nothing else sets section padding — see the
   note at the top of this file.

   55 / 89 rather than 89 / 144. The larger pair was tried first and put
   nearly 300px between one section's last line and the next section's
   label — which does not read as calm, it reads as unfinished. Two rungs
   down the ladder is enough air to separate ideas while keeping the page
   feeling deliberate. */
.nx-section { padding-block: var(--nx-space-6); }

@media (min-width: 900px) {
  .nx-section { padding-block: var(--nx-space-7); }
}

.nx-section--tight { padding-block: var(--nx-space-6); }
.nx-section--sand  { background: var(--nx-sand); }
.nx-section--dark  { background: var(--nx-band); color: var(--nx-on-band); }

/* Hairline between two same-coloured sections, so they read as separate
   without needing a colour change. */
.nx-section--ruled { border-top: 1px solid var(--nx-rule); }

/* Section opener: label, then title, then optional lead. Owns the gap
   between itself and whatever follows. */
.nx-section-head { margin-bottom: var(--nx-space-6); }
.nx-section-head > .nx-label   { margin-bottom: var(--nx-space-3); }
.nx-section-head > .nx-lead    { margin-top: var(--nx-space-4); }

/* Two-column opener, for heads that have a lead.

   Stacked, the head occupies the left half of a 1240px page and leaves the
   right half empty — while the grid below it runs the full width. The
   heading ends up looking orphaned rather than composed. Setting the title
   and its lead side by side fills the measure and puts a horizontal beat
   under every section, which is the same beat the Day Line establishes.

   Placement is explicit rather than wrapping the label and title in a div,
   so the markup stays flat and any head can opt in by adding one class.
   Below 1000px it collapses back to the stacked order. */
@media (min-width: 1000px) {
  .nx-section-head--split {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    column-gap: var(--nx-space-6);
  }
  .nx-section-head--split > .nx-label { grid-area: 1 / 1; }
  .nx-section-head--split > .nx-title {
    grid-area: 2 / 1;
    /* The 26ch cap is there to stop a title running the full page width
       when it is the only thing in the row. Inside a split head the column
       already constrains it, and applying both left "The records belong to
       the clinic and the patient" broken across four lines. */
    max-width: none;
  }
  .nx-section-head--split > .nx-lead  {
    grid-area: 2 / 2;
    align-self: end;
    margin-top: 0;
    /* Optically aligns the lead's last baseline with the title's. */
    padding-bottom: 0.35em;
  }
}

.nx-grid { display: grid; gap: var(--nx-space-4); }
@media (min-width: 720px)  { .nx-grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 720px)  { .nx-grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .nx-grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 720px)  { .nx-grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .nx-grid--4 { grid-template-columns: repeat(4, 1fr); } }


/* ═════════════════════════════════════════════════════════════════════════
   BUTTONS

   Two only. A page with three button weights has no primary action.
     Primary   — solid ink. One per screen.
     Secondary — hairline outline on paper.
   Plus `.nx-textlink` for "and here is the other thing you could do".
   ═════════════════════════════════════════════════════════════════════════ */

.nx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--nx-space-2);
  /* 48px tall at default font size — comfortably over the 44px touch
     minimum, on phones and on a 10" front-desk tablet alike. */
  min-height: 48px;
  padding: var(--nx-space-3) var(--nx-space-5);
  border: 1px solid transparent;
  border-radius: var(--nx-radius-2);
  font-size: var(--nx-text-small);
  font-weight: 560;
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--nx-dur-fast) var(--nx-ease),
              border-color   var(--nx-dur-fast) var(--nx-ease),
              color          var(--nx-dur-fast) var(--nx-ease),
              transform      var(--nx-dur-fast) var(--nx-ease);
}
/* 1px, not 3. A button that leaps on hover is a toy. */
.nx-btn:active { transform: translateY(1px); }

.nx-btn--primary {
  background: var(--nx-ink);
  color: var(--nx-paper);
}
.nx-btn--primary:hover { background: #000; }

.nx-btn--secondary {
  background: transparent;
  color: var(--nx-ink);
  border-color: var(--nx-rule-strong);
}
.nx-btn--secondary:hover {
  background: var(--nx-sand);
  border-color: var(--nx-ink);
}

/* On the dark band the ink button would disappear, so the polarity flips. */
.nx-on-dark .nx-btn--primary {
  background: var(--nx-on-band);
  color: var(--nx-band);
}
.nx-on-dark .nx-btn--primary:hover { background: #fff; }
.nx-on-dark .nx-btn--secondary {
  color: var(--nx-on-band);
  border-color: var(--nx-band-rule);
}
.nx-on-dark .nx-btn--secondary:hover {
  background: var(--nx-band-raised);
  border-color: var(--nx-on-band-muted);
}

.nx-btn--block { width: 100%; }
.nx-btn--lg { min-height: 54px; padding-inline: var(--nx-space-6); font-size: var(--nx-text-body); }

.nx-btn[disabled],
.nx-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }

/* The arrow nudges on hover. It is the only decorative motion on a control,
   and it is 3px. */
.nx-btn__arrow { transition: transform var(--nx-dur-base) var(--nx-ease-out); }
.nx-btn:hover .nx-btn__arrow { transform: translateX(3px); }

.nx-textlink {
  display: inline-flex;
  align-items: center;
  gap: var(--nx-space-2);
  color: var(--nx-blue);
  font-weight: 500;
  text-decoration: none;
  /* Underline sits below the baseline rather than through the descenders. */
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}
.nx-textlink:hover { color: var(--nx-blue-deep); text-decoration: underline; }
.nx-on-dark .nx-textlink { color: var(--nx-on-band-accent); }
.nx-on-dark .nx-textlink:hover { color: var(--nx-on-band); }

/* Prose links are underlined by default — inside a paragraph, colour alone
   is not enough to mark a link. */
.nx-body a,
.nx-lead a {
  color: var(--nx-blue);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--nx-rule-strong);
}
.nx-body a:hover,
.nx-lead a:hover { color: var(--nx-blue-deep); text-decoration-color: currentColor; }


/* ═════════════════════════════════════════════════════════════════════════
   CHIPS AND STATUS

   Status is carried by a WORD plus a shape, never by colour alone. A
   colour-blind reader and a greyscale printout both still work.
   ═════════════════════════════════════════════════════════════════════════ */

.nx-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--nx-space-2);
  padding: 5px var(--nx-space-3);
  border-radius: var(--nx-radius-pill);
  background: var(--nx-sand);
  color: var(--nx-ink-muted);
  font-size: var(--nx-text-label);
  font-weight: 500;
  letter-spacing: var(--nx-track-label);
  text-transform: uppercase;
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
}
.nx-chip--blue  { background: var(--nx-blue-tint);  color: var(--nx-blue-deep); }
.nx-chip--green { background: var(--nx-green-tint); color: var(--nx-green-deep); }

.nx-chip__dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
/* "In progress" gets a ring instead of a filled dot — the shape says
   unfinished before the word is read. */
.nx-chip__dot--hollow {
  background: transparent;
  border: 1.5px solid currentColor;
  width: 7px; height: 7px;
}

.nx-on-dark .nx-chip {
  background: var(--nx-band-raised);
  color: var(--nx-on-band-muted);
}
.nx-on-dark .nx-chip--blue  { color: var(--nx-on-band-accent); }
.nx-on-dark .nx-chip--green { color: var(--nx-on-band-growth); }


/* ═════════════════════════════════════════════════════════════════════════
   CARDS
   ═════════════════════════════════════════════════════════════════════════ */

.nx-card {
  padding: var(--nx-space-5);
  background: var(--nx-paper-raised);
  border: 1px solid var(--nx-rule);
  border-radius: var(--nx-radius-3);
}
.nx-card__title { margin-bottom: var(--nx-space-2); }
.nx-card__body  { color: var(--nx-ink-muted); font-size: var(--nx-text-small); }

/* Only cards that are entirely a link get hover movement. A static card
   that lifts on hover is promising an interaction it does not have. */
.nx-card--link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color var(--nx-dur-base) var(--nx-ease),
              box-shadow   var(--nx-dur-base) var(--nx-ease);
}
.nx-card--link:hover {
  border-color: var(--nx-rule-strong);
  box-shadow: var(--nx-shadow-2);
}

.nx-on-dark .nx-card {
  background: var(--nx-band-raised);
  border-color: var(--nx-band-rule);
}
.nx-on-dark .nx-card__body { color: var(--nx-on-band-muted); }


/* ═════════════════════════════════════════════════════════════════════════
   HEADER
   ═════════════════════════════════════════════════════════════════════════ */

.nx-header {
  position: sticky;
  top: 0;
  z-index: var(--nx-z-sticky);
  background: color-mix(in srgb, var(--nx-paper) 88%, transparent);
  border-bottom: 1px solid transparent;
  transition: border-color var(--nx-dur-base) var(--nx-ease),
              background-color var(--nx-dur-base) var(--nx-ease);
}
/* The rule appears only once the page has scrolled, so the header is
   invisible against the hero and defined against content. Class is set by
   js/public/site.js. */
.nx-header.is-stuck {
  border-bottom-color: var(--nx-rule);
  background: color-mix(in srgb, var(--nx-paper) 96%, transparent);
}

/* Browsers without color-mix get a solid bar rather than a transparent one. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .nx-header { background: var(--nx-paper); }
}

/* ── The frosted header, applied only where it is free ────────────────────
   `backdrop-filter` on a STICKY element is the expensive combination: the
   browser has to re-composite the blurred strip every time anything repaints
   beneath it — every scroll frame, every caret blink, every focus ring. On
   integrated graphics that is a common cause of input feeling half a beat
   behind, and it is worst on exactly the pages where it matters most: long
   forms someone is typing into.

   So it is gated rather than deleted. `dynamic-range: high` is not a direct
   test for GPU headroom — no such media query exists — but it is a decent
   proxy: displays reporting HDR are overwhelmingly on machines with the
   compositing budget to spare. Everywhere else the header is simply a
   translucent bar, which is 90% of the look for none of the cost.

   `prefers-reduced-motion` opts out too. Someone asking for less motion is
   often on a machine where motion is expensive, or is sensitive to exactly
   the shimmer a blur produces as content slides under it.

   If the header ever feels sticky-slow again, delete this whole block —
   nothing else depends on it. */
@media (dynamic-range: high) and (prefers-reduced-motion: no-preference) {
  .nx-header {
    backdrop-filter: saturate(150%) blur(12px);
    -webkit-backdrop-filter: saturate(150%) blur(12px);
  }
}

.nx-header__inner {
  display: flex;
  align-items: center;
  gap: var(--nx-space-4);
  min-height: 72px;
}

.nx-brand {
  display: inline-flex;
  align-items: center;
  flex: none;
  margin-right: auto;
  text-decoration: none;
}
.nx-brand__lockup { height: 30px; width: auto; }

/* The mark's one movement: a single calm turn on first arrival, then it is
   still forever. Driven by a class from site.js so it fires once per
   session, not once per page view. */
.nx-brand__lockup.is-arriving { animation: nx-arrive var(--nx-dur-settle) var(--nx-ease-settle) both; }

@keyframes nx-arrive {
  from { transform: rotate(-32deg) scale(0.96); opacity: 0; }
  to   { transform: rotate(0)      scale(1);    opacity: 1; }
}

.nx-nav {
  display: none;
  align-items: center;
  gap: var(--nx-space-5);
}
@media (min-width: 900px) { .nx-nav { display: flex; } }

.nx-nav__link {
  position: relative;
  padding-block: var(--nx-space-2);
  color: var(--nx-ink-muted);
  font-size: var(--nx-text-small);
  font-weight: 500;
  text-decoration: none;
  transition: color var(--nx-dur-fast) var(--nx-ease);
}
.nx-nav__link:hover { color: var(--nx-ink); }

/* Current page is marked by ink weight AND a rule under it — never by
   colour alone. */
.nx-nav__link[aria-current="page"] { color: var(--nx-ink); }
.nx-nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--nx-ink);
  border-radius: 2px;
}

.nx-header__actions {
  display: none;
  align-items: center;
  gap: var(--nx-space-3);
  flex: none;
}
@media (min-width: 900px) { .nx-header__actions { display: flex; } }

.nx-header__actions .nx-btn { min-height: 42px; padding-inline: var(--nx-space-4); }

/* ── Mobile menu ─────────────────────────────────────────────────────────
   A disclosure, not a dialog: it pushes nothing, traps nothing, and closes
   on Escape or on any link. Full ARIA wiring is in site.js.
   ───────────────────────────────────────────────────────────────────────── */
.nx-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  flex: none;
  background: transparent;
  border: 1px solid var(--nx-rule);
  border-radius: var(--nx-radius-2);
  cursor: pointer;
}
@media (min-width: 900px) { .nx-menu-btn { display: none; } }

.nx-menu-btn__bars { display: block; width: 18px; height: 12px; position: relative; }
.nx-menu-btn__bars::before,
.nx-menu-btn__bars::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1.5px;
  background: var(--nx-ink);
  border-radius: 2px;
  transition: transform var(--nx-dur-base) var(--nx-ease),
              top       var(--nx-dur-base) var(--nx-ease);
}
.nx-menu-btn__bars::before { top: 1px; }
.nx-menu-btn__bars::after  { top: 9px; }
.nx-menu-btn[aria-expanded="true"] .nx-menu-btn__bars::before { top: 5px; transform: rotate(45deg); }
.nx-menu-btn[aria-expanded="true"] .nx-menu-btn__bars::after  { top: 5px; transform: rotate(-45deg); }

.nx-mobile-nav {
  display: none;
  border-top: 1px solid var(--nx-rule);
  background: var(--nx-paper);
  padding-block: var(--nx-space-3) var(--nx-space-5);
}
.nx-mobile-nav.is-open { display: block; }
@media (min-width: 900px) { .nx-mobile-nav.is-open { display: none; } }

.nx-mobile-nav__link {
  display: block;
  padding: var(--nx-space-3) 0;
  border-bottom: 1px solid var(--nx-rule);
  color: var(--nx-ink);
  font-size: var(--nx-text-body);
  font-weight: 500;
  text-decoration: none;
}
.nx-mobile-nav__link[aria-current="page"] { color: var(--nx-blue); }
.nx-mobile-nav__actions {
  display: grid;
  gap: var(--nx-space-3);
  margin-top: var(--nx-space-4);
}


/* ═════════════════════════════════════════════════════════════════════════
   FOOTER
   ═════════════════════════════════════════════════════════════════════════ */

/* Green, not the band blue — this is where the Nurev identity comes
   forward. Same luminance as --nx-band, so it reads as one dark weight
   across the page rather than two competing darks. */
.nx-footer {
  background: var(--nx-footer);
  color: var(--nx-on-footer);
  padding-block: var(--nx-space-7) var(--nx-space-5);
}

.nx-footer__top {
  display: grid;
  gap: var(--nx-space-6);
  padding-bottom: var(--nx-space-6);
  border-bottom: 1px solid var(--nx-footer-rule);
}
@media (min-width: 800px) {
  .nx-footer__top { grid-template-columns: 1.4fr 1fr 1fr; gap: var(--nx-space-5); }
}

.nx-footer__lockup { height: 34px; width: auto; margin-bottom: var(--nx-space-4); }
.nx-footer__tagline { color: var(--nx-on-footer-muted); font-size: var(--nx-text-small); max-width: 34ch; }

.nx-footer__label { margin-bottom: var(--nx-space-3); color: var(--nx-on-footer-muted); }
.nx-footer__list { display: grid; gap: var(--nx-space-2); }

.nx-footer__link {
  display: inline-block;
  padding-block: 3px;
  color: var(--nx-on-footer);
  font-size: var(--nx-text-small);
  text-decoration: none;
}
.nx-footer__link:hover { color: var(--nx-on-footer-hover); text-decoration: underline; text-underline-offset: 0.2em; }

.nx-footer__meta { color: var(--nx-on-footer-muted); font-size: var(--nx-text-small); }

.nx-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nx-space-3) var(--nx-space-5);
  padding-top: var(--nx-space-5);
  color: var(--nx-on-footer-muted);
  font-size: var(--nx-text-small);
}
.nx-footer__bottom-spacer { margin-left: auto; }


/* ═════════════════════════════════════════════════════════════════════════
   FORMS

   Used by login, signup, OTP and password reset. Every rule here assumes
   the markup pattern:

     <div class="nx-field">
       <label class="nx-field__label" for="x">…</label>
       <input class="nx-input" id="x" name="x" aria-describedby="x-help">
       <p class="nx-field__help" id="x-help">…</p>
       <p class="nx-field__error" id="x-error" hidden>…</p>
     </div>

   Errors are announced, not just coloured: the message carries an icon and
   text, the input gets aria-invalid, and the two are tied by
   aria-describedby. See auth.css and js/public/signup.js.
   ═════════════════════════════════════════════════════════════════════════ */

.nx-fieldset { border: 0; padding: 0; margin: 0; }

.nx-legend {
  display: flex;
  align-items: baseline;
  gap: var(--nx-space-3);
  width: 100%;
  /* 8 above the rule, 13 below it — down from 13 and 21.

     The gap under a section heading used to be larger than the gap between
     the fields it introduced, which reads backwards: the heading appeared
     to belong to the space rather than to the fields under it. Now the
     13px below matches the field rhythm exactly, so a section heading sits
     the same distance from its first field as any two fields sit apart.

     The rule itself already does the separating, so it did not need a
     paragraph of air on top of it as well. */
  padding: 0 0 var(--nx-space-2);
  margin-bottom: var(--nx-space-3);
  border-bottom: 1px solid var(--nx-rule);
}

.nx-field { display: block; }
/* 13, not 21. One rung down the ladder — measured at 21px the fields read as
   separate items rather than as one form, and the signup page has eleven of
   them. Still a clear break between rows, just not a paragraph break. */
.nx-field + .nx-field { margin-top: var(--nx-space-3); }

.nx-field__label {
  display: block;
  margin-bottom: var(--nx-space-2);
  font-size: var(--nx-text-small);
  font-weight: 500;
  color: var(--nx-ink);
}

.nx-input,
.nx-select {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: var(--nx-space-3);
  background: var(--nx-paper-raised);
  border: 1px solid var(--nx-rule-strong);
  border-radius: var(--nx-radius-2);
  color: var(--nx-ink);
  font-size: var(--nx-text-body);
  transition: border-color var(--nx-dur-fast) var(--nx-ease),
              box-shadow   var(--nx-dur-fast) var(--nx-ease);
}
.nx-input::placeholder { color: var(--nx-ink-faint); }
.nx-input:hover,
.nx-select:hover { border-color: var(--nx-ink-faint); }

.nx-input:focus,
.nx-select:focus {
  outline: none;
  border-color: var(--nx-focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--nx-focus) 18%, transparent);

  /* INSTANT on the way in. The 120ms transition above is right for hover,
     where the pointer is drifting and easing looks considered — and wrong
     for focus, where someone has just clicked and is waiting to type. A
     field that takes 120ms to acknowledge a click does not read as a
     smooth animation; it reads as a slow input.

     Leaving the transition on the base rule means it still eases OUT on
     blur, which is where the softness actually helps. */
  transition: none;
}
/* Keyboard users additionally get the standard ring, so focus is never
   carried by the subtle glow alone. */
.nx-input:focus-visible,
.nx-select:focus-visible {
  outline: var(--nx-focus-width) solid var(--nx-focus);
  outline-offset: var(--nx-focus-offset);
}

.nx-select {
  /* Native chevron removed and redrawn so it matches the ink palette
     rather than the OS blue. */
  appearance: none;
  padding-right: var(--nx-space-6);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%236b6a64' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--nx-space-3) center;
}

.nx-input[aria-invalid="true"],
.nx-select[aria-invalid="true"] { border-color: #8a1c1c; }

.nx-field__help {
  margin-top: var(--nx-space-2);
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
}

.nx-field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-space-2);
  margin-top: var(--nx-space-2);
  font-size: var(--nx-text-small);
  font-weight: 500;
  color: #8a1c1c;   /* --bx-status-red — 7.3:1 on paper */
}
.nx-field__error[hidden] { display: none; }

/* Input with something attached, e.g. the +91 dial prefix or a Show toggle. */
.nx-input-group { display: flex; align-items: stretch; }
.nx-input-group > .nx-input { border-radius: 0 var(--nx-radius-2) var(--nx-radius-2) 0; }

.nx-input-group__prefix {
  display: inline-flex;
  align-items: center;
  padding-inline: var(--nx-space-3);
  background: var(--nx-sand);
  border: 1px solid var(--nx-rule-strong);
  border-right: 0;
  border-radius: var(--nx-radius-2) 0 0 var(--nx-radius-2);
  color: var(--nx-ink-muted);
  font-size: var(--nx-text-small);
  font-weight: 500;
  white-space: nowrap;
}

.nx-input-affix { position: relative; }
.nx-input-affix > .nx-input { padding-right: 76px; }
.nx-input-affix__btn {
  position: absolute;
  top: 50%; right: 6px;
  transform: translateY(-50%);
  min-height: 36px;
  padding-inline: var(--nx-space-3);
  background: transparent;
  border: 0;
  border-radius: var(--nx-radius-1);
  color: var(--nx-blue);
  font-size: var(--nx-text-small);
  font-weight: 500;
  cursor: pointer;
}
.nx-input-affix__btn:hover { background: var(--nx-sand); }

/* Checkbox row. The 20px box is centred against the first line of the label
   rather than the whole block, so a two-line label still lines up. */
.nx-check {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-space-3);
  cursor: pointer;
}
.nx-check__box {
  flex: none;
  width: 20px; height: 20px;
  margin: 2px 0 0;
  accent-color: var(--nx-ink);
  cursor: pointer;
}
.nx-check__label { font-size: var(--nx-text-small); color: var(--nx-ink-muted); }

/* Password policy checklist — mirrors password_check() in
   app/operations/auth/forms.py exactly. Each rule states itself in words;
   the tick is confirmation, not the only signal. */
.nx-rules {
  display: grid;
  gap: var(--nx-space-2);
  margin-top: var(--nx-space-3);
  padding: var(--nx-space-3);
  background: var(--nx-sand);
  border-radius: var(--nx-radius-2);
}
.nx-rules__item {
  display: flex;
  align-items: center;
  gap: var(--nx-space-2);
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
}
.nx-rules__item.is-met { color: var(--nx-green); }
.nx-rules__mark {
  flex: none;
  width: 16px; height: 16px;
  display: grid;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 10px;
  line-height: 1;
}
.nx-rules__item.is-met .nx-rules__mark { background: var(--nx-green); border-color: var(--nx-green); color: #fff; }


/* ═════════════════════════════════════════════════════════════════════════
   ALERTS — flashed messages from Flask
   ═════════════════════════════════════════════════════════════════════════ */

.nx-alerts { display: grid; gap: var(--nx-space-2); }

.nx-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-space-3);
  padding: var(--nx-space-3) var(--nx-space-4);
  border: 1px solid var(--nx-rule);
  border-left: 3px solid var(--nx-ink-faint);
  border-radius: var(--nx-radius-2);
  background: var(--nx-paper-raised);
  font-size: var(--nx-text-small);
  color: var(--nx-ink);
}
/* Flask categories map onto these. An unknown category falls through to the
   neutral base above rather than rendering unstyled. */
.nx-alert--success { border-left-color: var(--nx-green);   background: var(--nx-green-tint); }
.nx-alert--info    { border-left-color: var(--nx-blue);    background: var(--nx-blue-tint); }
.nx-alert--warning { border-left-color: #9a5614;           background: #f6ecdc; }
.nx-alert--error,
.nx-alert--danger  { border-left-color: #8a1c1c;           background: #f8e9e9; }

.nx-alert__icon { flex: none; margin-top: 2px; }


/* ═════════════════════════════════════════════════════════════════════════
   SCROLL REVEAL

   One transition — 12px up and a fade, once, on entry. No stagger beyond a
   single step, no scale, no blur. Elements are visible by default and only
   hidden once JS confirms it can reveal them, so a reader with JS disabled
   or a crawler sees the whole page.
   ═════════════════════════════════════════════════════════════════════════ */

.js-reveal .nx-reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--nx-dur-slow) var(--nx-ease-out),
              transform var(--nx-dur-slow) var(--nx-ease-out);
}
.js-reveal .nx-reveal.is-in { opacity: 1; transform: none; }
.js-reveal .nx-reveal--d1.is-in { transition-delay: 60ms; }
.js-reveal .nx-reveal--d2.is-in { transition-delay: 120ms; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal .nx-reveal { opacity: 1; transform: none; }
}


/* ═════════════════════════════════════════════════════════════════════════
   UTILITIES — the complete list. Do not add more without a second use.
   ═════════════════════════════════════════════════════════════════════════ */

.nx-stack   { display: grid; gap: var(--nx-space-4); }
.nx-stack-2 { display: grid; gap: var(--nx-space-2); }
.nx-stack-3 { display: grid; gap: var(--nx-space-3); }
.nx-stack-5 { display: grid; gap: var(--nx-space-5); }

.nx-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nx-space-3);
}
.nx-row--gap-5 { gap: var(--nx-space-5); }

.nx-hr { height: 1px; border: 0; background: var(--nx-rule); }
.nx-on-dark .nx-hr { background: var(--nx-band-rule); }


/* ═════════════════════════════════════════════════════════════════════════
   THE DAY LINE — the site's signature

   A clinic's day, drawn as one hairline with the moments Nadis touches
   marked on it. It appears on the home page, indexes the product page, and
   returns as a quiet fragment in the auth panel — so all three read as one
   system rather than three layouts.

   WHY AN <ol>
   The markup is an ordered list because the order is real information: a
   patient is checked in before they are seen, and billed after. This is the
   one place on the site where a numbered structure is honest. Everywhere
   else, sequence markers would be decoration.

   HOW MEANING IS CARRIED
     blue  + filled circle   what the system does for you
     green + filled diamond  what grows your practice

   Shape and colour always travel together, and every station is labelled in
   words. Printed in greyscale, or read by someone who cannot separate blue
   from green, it still works. A legend states the pairing in text.

   MOTION
   The markers settle left to right once, when the line first scrolls into
   view — 90ms apart, set as --nx-station-delay by site.js. That is the only
   orchestrated animation on the site. Under prefers-reduced-motion the
   settled state is applied instantly and nothing moves.
   ═════════════════════════════════════════════════════════════════════════ */

.nx-dayline { position: relative; }

.nx-dayline__track {
  display: grid;
  gap: var(--nx-space-5);
  position: relative;
}

/* The rule itself. Drawn behind the markers, inset so it starts and ends at
   the first and last dot rather than bleeding off into nothing. */
.nx-dayline__track::before {
  content: "";
  position: absolute;
  background: var(--nx-rule-strong);
  transform-origin: left center;
}

.nx-dayline__station {
  position: relative;
  /* Both properties are set even before the line settles, so the only thing
     the class toggle changes is the end state. */
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--nx-dur-base) var(--nx-ease-out),
              transform var(--nx-dur-base) var(--nx-ease-out);
  transition-delay: var(--nx-station-delay, 0ms);
}

.nx-dayline.is-settled .nx-dayline__station { opacity: 1; transform: none; }

/* Applied together with is-settled when motion is reduced or the observer
   is unavailable: the line is simply already there. */
.nx-dayline.is-instant .nx-dayline__station { transition: none; }

.nx-dayline__time {
  display: block;
  margin-bottom: var(--nx-space-3);
  font-size: var(--nx-text-label);
  font-weight: 500;
  letter-spacing: var(--nx-track-label);
  color: var(--nx-ink-faint);
  /* Times are data — the ledger voice, and it keeps 09:00 and 11:30 the
     same width so the ticks read as a scale. */
  font-variant-numeric: tabular-nums lining-nums;
}

/* One marker, one colour. The shape/colour pair used to encode a second
   category and needed a legend to decode; the day is one continuous thing,
   so the line says so. */
.nx-dayline__marker {
  position: relative;
  z-index: 1;
  display: block;
  width: 11px;
  height: 11px;
  margin-bottom: var(--nx-space-4);
  border-radius: 50%;
  background: var(--nx-blue);
  /* A ring of paper around each marker so the rule appears to pass behind
     it rather than through it. */
  box-shadow: 0 0 0 4px var(--nx-paper);
}

.nx-dayline__name { margin-bottom: var(--nx-space-2); }

.nx-dayline__detail {
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
  max-width: 30ch;
}

/* ── Vertical, up to 780px ───────────────────────────────────────────────
   A day-sheet on a phone reads top to bottom anyway, so the line rotates
   rather than shrinking. No horizontal scrolling, no 8px type.
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 779px) {
  .nx-dayline__track::before {
    left: 5px;
    top: 6px;
    bottom: 6px;
    width: 1px;
  }
  .nx-dayline__station { padding-left: var(--nx-space-5); }
  .nx-dayline__marker {
    position: absolute;
    left: 0;
    top: 4px;
    margin-bottom: 0;
  }
  .nx-dayline__time { margin-bottom: var(--nx-space-1); }
}

/* ── Horizontal, from 780px ──────────────────────────────────────────── */
@media (min-width: 780px) {
  .nx-dayline__track {
    grid-template-columns: repeat(5, 1fr);
    gap: var(--nx-space-4);
  }
  .nx-dayline__track::before {
    /* Vertically centred on the markers: time label height + its margin. */
    top: 41px;
    left: 5px;
    right: 5px;
    height: 1px;
  }
  .nx-dayline__station { padding-right: var(--nx-space-4); }
}

/* ── Compact variant — the auth panel ────────────────────────────────────
   Markers and the rule only, no labels: a signature, not a diagram. The
   station text is still in the DOM for screen readers, hidden visually.
   ───────────────────────────────────────────────────────────────────────── */
.nx-dayline--mini .nx-dayline__track {
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
}
.nx-dayline--mini .nx-dayline__track::before {
  top: 5px; left: 5px; right: 5px; height: 1px;
  background: var(--nx-band-rule);
}
.nx-dayline--mini .nx-dayline__station { padding: 0; }
.nx-dayline--mini .nx-dayline__marker {
  margin: 0;
  box-shadow: 0 0 0 4px var(--nx-band);
}
.nx-dayline--mini .nx-dayline__marker--system { background: var(--nx-on-band-system); }
.nx-dayline--mini .nx-dayline__marker--growth { background: var(--nx-on-band-growth); }


/* ═════════════════════════════════════════════════════════════════════════
   "TALK TO US" PANEL

   A native <dialog>. The UA gives it `position: fixed`, centring, the
   backdrop, the focus trap and Escape — all of which we keep. What is
   overridden is only the look: the default border, padding and background
   are stripped from the <dialog> itself and moved onto the panel inside it,
   so the element that carries the backdrop is not also the element that
   carries the paper.
   ═════════════════════════════════════════════════════════════════════════ */

.nx-connect {
  width: min(430px, calc(100vw - 2 * var(--nx-space-4)));
  max-height: calc(100dvh - 2 * var(--nx-space-4));
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--nx-ink);
  overflow: visible;
}

.nx-connect::backdrop {
  /* The slate from the trust band, not neutral black — even the dim behind
     a panel belongs to the palette. */
  background: rgba(18, 48, 63, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

/* Opening: a 6px rise and a fade. No scale, no spring. The panel arrives;
   it does not perform. Both collapse to nothing under reduced motion via
   the global rule in tokens.css. */
.nx-connect[open]           { animation: nx-connect-in var(--nx-dur-base) var(--nx-ease-out); }
.nx-connect[open]::backdrop { animation: nx-fade-in    var(--nx-dur-base) var(--nx-ease-out); }

@keyframes nx-connect-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes nx-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.nx-connect__panel {
  position: relative;
  padding: var(--nx-space-5);
  background: var(--nx-paper-raised);
  border: 1px solid var(--nx-rule);
  border-radius: var(--nx-radius-4);
  box-shadow: var(--nx-shadow-3);
}

.nx-connect__close,
.nx-dialog__close {
  position: absolute;
  top: var(--nx-space-3);
  right: var(--nx-space-3);
  display: grid;
  place-items: center;
  /* 40px, so it is a real target on a phone rather than a 16px glyph. */
  width: 40px; height: 40px;
  background: transparent;
  border: 0;
  border-radius: var(--nx-radius-2);
  color: var(--nx-ink-muted);
  cursor: pointer;
  transition: background-color var(--nx-dur-fast) var(--nx-ease),
              color var(--nx-dur-fast) var(--nx-ease);
}
.nx-connect__close:hover,
.nx-dialog__close:hover { background: var(--nx-sand); color: var(--nx-ink); }

/* Room for the close button so a long title never runs under it. */
.nx-connect__panel > .nx-label { padding-right: 44px; margin-bottom: var(--nx-space-3); }

.nx-connect__title {
  font-size: 1.5rem;
  font-weight: 620;
  letter-spacing: var(--nx-track-title);
  line-height: 1.2;
  margin-bottom: var(--nx-space-3);
}

.nx-connect__desc {
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
  margin-bottom: var(--nx-space-5);
}

.nx-connect__actions { display: grid; gap: var(--nx-space-2); }

.nx-connect__foot {
  margin-top: var(--nx-space-4);
  padding-top: var(--nx-space-4);
  border-top: 1px solid var(--nx-rule);
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
}
.nx-connect__foot a { color: var(--nx-blue); text-underline-offset: 0.18em; }


/* ═════════════════════════════════════════════════════════════════════════
   SHARED PAGE BLOCKS

   Both of these started life on the home page and were moved here the
   moment the product page needed them. Named for what they are, not for
   where they first appeared — `.nx-trust__item` styling an AI capability
   card would have been a small lie that costs someone ten minutes later.
   ═════════════════════════════════════════════════════════════════════════ */

/* Heading beside a body of text — the support and platform sections. */
.nx-split { display: grid; gap: var(--nx-space-5); }

@media (min-width: 900px) {
  .nx-split {
    grid-template-columns: 1fr 1.6fr;
    gap: var(--nx-space-6);
    align-items: start;
  }
}

/* Content inside a `.nx-section--dark` band.

   `.nx-band__head` deliberately sets NO max-width. It did — 62ch — and
   because this block is appended at the end of the file it beat the
   `.nx-section-head--split` grid defined above, squeezing both columns to
   about 300px. "The records belong to the clinic and the patient" came out
   over four lines. The measure is already controlled where it belongs:
   `.nx-title` caps itself, `.nx-lead` caps itself, and inside a split head
   the grid column is the constraint. */
.nx-band__label { color: var(--nx-on-band-accent); }
.nx-band__lead  { color: var(--nx-on-band-muted); }

.nx-band__item  { display: grid; align-content: start; gap: var(--nx-space-3); }
.nx-band__title { color: var(--nx-on-band); }
/* The chip is content-width, not column-width. */
.nx-band__item > .nx-chip { justify-self: start; }

.nx-band__note {
  margin-top: var(--nx-space-5);
  color: var(--nx-on-band-muted);
  max-width: 60ch;
}


/* ═════════════════════════════════════════════════════════════════════════
   PAGE HERO

   Home, Product and About all open the same way, so this is shared rather
   than duplicated three times. The promise line and the button row are used
   only by the home page today; they stay here because they belong to the
   hero, not because every page needs them.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Hero ─────────────────────────────────────────────────────────────────
   Left-weighted and generous. The one place on the site where the display
   register is set at full size.
   ───────────────────────────────────────────────────────────────────────── */
.nx-hero { padding-block: var(--nx-space-7) var(--nx-space-6); }

@media (min-width: 900px) {
  .nx-hero { padding-block: var(--nx-space-8) var(--nx-space-7); }
}

.nx-hero__eyebrow { margin-bottom: var(--nx-space-4); }

.nx-hero__title {
  /* Wider than the default display measure so "Run your clinic." holds one
     line at every size, and the break lands where the markup puts it. */
  max-width: 18ch;
  margin-bottom: var(--nx-space-4);
}

.nx-hero__lead { margin-bottom: var(--nx-space-6); }

.nx-hero__actions { gap: var(--nx-space-3); margin-bottom: var(--nx-space-5); }

.nx-hero__promise {
  display: flex;
  align-items: center;
  gap: var(--nx-space-2);
  font-size: var(--nx-text-small);
  color: var(--nx-ink-muted);
}
.nx-hero__promise-dot {
  flex: none;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--nx-green);
}


/* ═════════════════════════════════════════════════════════════════════════
   TERMS AND PRIVACY MODAL

   Wider and taller than the "Talk to us" panel because it holds a document
   rather than a question. Three parts, and only the middle one scrolls:

     head   title + close      pinned
     body   the document       scrolls
     foot   the single button  pinned

   Pinning the button matters. A legal document in a dialog that scrolls as
   one block puts "Okay" below several screens of text, so on a phone the
   only way out is Escape or the × — and someone reading terms on a phone at
   a front desk should never have to hunt for the way forward.
   ═════════════════════════════════════════════════════════════════════════ */

.nx-legal {
  width: min(640px, calc(100vw - 2 * var(--nx-space-4)));
  max-height: min(760px, calc(100dvh - 2 * var(--nx-space-5)));
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--nx-ink);
}

.nx-legal::backdrop {
  background: rgba(18, 48, 63, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.nx-legal[open]           { animation: nx-connect-in var(--nx-dur-base) var(--nx-ease-out); }
.nx-legal[open]::backdrop { animation: nx-fade-in    var(--nx-dur-base) var(--nx-ease-out); }

.nx-legal__panel {
  display: grid;
  /* head and foot size to content; the body takes the rest and scrolls. */
  grid-template-rows: auto minmax(0, 1fr) auto;
  max-height: inherit;
  background: var(--nx-paper-raised);
  border: 1px solid var(--nx-rule);
  border-radius: var(--nx-radius-4);
  box-shadow: var(--nx-shadow-3);
  overflow: hidden;
}

/* Blue header, white type — the same surface as every other dark band on
   the site, so a legal document opened from a footer link still looks like
   it belongs to Nadis rather than to the browser. */
.nx-legal__head {
  display: flex;
  align-items: flex-start;
  gap: var(--nx-space-4);
  padding: var(--nx-space-5) var(--nx-space-5) var(--nx-space-5);
  background: var(--nx-band);
  color: var(--nx-on-band);
  border-bottom: 0;
}
/* The close button is absolutely positioned for the connect panel; here it
   is a flex item, so that positioning has to be undone. */
.nx-legal__head .nx-dialog__close { position: static; margin-left: auto; flex: none; }

.nx-legal__title {
  /* Sized against the panel rather than against body copy: at 1.375rem it
     read as a label on a coloured bar instead of as the title of a
     document. Fluid so it still fits a 360px phone. */
  font-size: clamp(1.5rem, 1.25rem + 0.9vw, 1.875rem);
  font-weight: 620;
  letter-spacing: var(--nx-track-title);
  line-height: 1.15;
}
.nx-legal__updated {
  margin-top: var(--nx-space-1);
  font-size: var(--nx-text-small);
  color: var(--nx-on-band-muted);
}

.nx-legal__body {
  padding: var(--nx-space-5);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Shown while a document's `status` in site_info.py is not "final". Loud on
   purpose — this is the thing standing between a skeleton and a published
   legal agreement. */
.nx-legal__draft {
  padding: var(--nx-space-3) var(--nx-space-4);
  margin-bottom: var(--nx-space-5);
  background: #f6ecdc;
  border-left: 3px solid #9a5614;
  border-radius: var(--nx-radius-2);
  font-size: var(--nx-text-small);
  color: #6d3d0e;
}

.nx-legal__intro {
  margin-bottom: var(--nx-space-5);
  color: var(--nx-ink-muted);
  max-width: 62ch;
}

.nx-legal__section + .nx-legal__section { margin-top: var(--nx-space-5); }
.nx-legal__section-title { margin-bottom: var(--nx-space-2); }

.nx-legal__p {
  font-size: var(--nx-text-small);
  line-height: 1.65;
  color: var(--nx-ink-muted);
  max-width: 68ch;
}
.nx-legal__p + .nx-legal__p { margin-top: var(--nx-space-3); }

/* Obligation lists — "the Facility is responsible for: …".

   These run long: one clause of eight, twice over. Set tighter than prose
   so the whole obligation reads as a single block rather than eight
   separate statements, and marked so the eye can count them. */
.nx-legal__list {
  margin: var(--nx-space-2) 0 0;
  padding-left: var(--nx-space-3);
  font-size: var(--nx-text-small);
  line-height: 1.5;
  color: var(--nx-ink-muted);
  max-width: 68ch;
}
/* `li { list-style: none }` is reset globally at the top of this file, so
   the marker has to be put back on the item — not on the list. */
.nx-legal__list li {
  list-style: disc;
  margin-left: var(--nx-space-2);
  padding-left: var(--nx-space-1);
}
.nx-legal__list li::marker { color: var(--nx-blue); }
.nx-legal__list li + li { margin-top: var(--nx-space-1); }
.nx-legal__p + .nx-legal__list { margin-top: var(--nx-space-2); }
.nx-legal__list + .nx-legal__p { margin-top: var(--nx-space-3); }

/* A contact block. Line breaks carry the meaning, so the lines are set
   tighter than prose to read as one address rather than five statements. */
.nx-legal__block { line-height: 1.5; }

.nx-legal__foot {
  display: flex;
  justify-content: flex-end;
  padding: var(--nx-space-4) var(--nx-space-5);
  border-top: 1px solid var(--nx-rule);
  background: var(--nx-paper-raised);
}

@media (max-width: 560px) {
  /* Full-width button on a phone — the one action, at thumb width. */
  .nx-legal__foot .nx-btn { width: 100%; }
}


/* The close button is shared with the "Talk to us" panel, which sits on
   paper. On the legal modal's blue header it needs the light polarity. */
.nx-legal__head .nx-dialog__close { color: var(--nx-on-band-muted); }
.nx-legal__head .nx-dialog__close:hover {
  background: var(--nx-band-raised);
  color: var(--nx-on-band);
}
.nx-legal__head .nx-dialog__close:focus-visible { outline-color: var(--nx-on-band); }

/* Pending: in progress, a target, an alignment rather than a certification.
   The one place amber appears. On the dark band it is #f0b95e at 8.5:1; on
   paper it drops to #9a5614, which is the same value the signed-in product
   uses for money outstanding — "pending" looks the same either side of the
   login. */
.nx-chip--pending {
  background: var(--nx-amber-tint);
  color: var(--nx-amber-ink);
}
.nx-on-dark .nx-chip--pending {
  background: var(--nx-amber-fill);
  color: var(--nx-amber);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--nx-amber) 22%, transparent);
}


/* ═════════════════════════════════════════════════════════════════════════
   THE COLOURED FULL STOP

   Site-wide version of the treatment the auth panels use: the full stop
   ending a display line carries the accent. Colour on punctuation costs
   nothing if it is not perceived — delete it and the sentence is unchanged
   — which is why it is safe here and not on words that carry meaning.

   TWO VALUES, and the light one is not optional. #f0b95e is the amber that
   sings on the dark band; on warm paper it measures 1.7:1 and reads as a
   printing fault rather than as a choice. On light surfaces it drops to
   --nx-amber-ink (5.4:1) — the same amber family, and the same value the
   signed-in product uses for money outstanding.
   ═════════════════════════════════════════════════════════════════════════ */
.nx-stop--amber { color: var(--nx-amber-ink); }
.nx-on-dark .nx-stop--amber { color: var(--nx-amber); }
