/* Landing pages — Native Internal Services.
   Implements the Native Pet Website Style Guide: colours, typography,
   components, UI elements and the 24-column grid. Everything below traces to
   a numbered section of that guide; the few things it does not cover (a header
   bar, a footer, card hover states, mobile) are marked EXTENSION and recorded
   as A-194-01..07 in ASSUMPTIONS.md. */

/* ─── Fonts (self-hosted from nativepet.com CDN) ───────────────────────── */

@font-face {
  font-family: "F37 Ginger Soft";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/landing/assets/fonts/F37GingerSoft-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "F37 Ginger Soft";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/landing/assets/fonts/F37GingerSoft-Bold.woff2") format("woff2");
}
@font-face {
  font-family: "Adieu";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/landing/assets/fonts/Adieu-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "Adieu";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/landing/assets/fonts/Adieu-Bold.woff2") format("woff2");
}
/* Adieu Black is not declared: the style guide never specifies it. Headings are
   F37 Ginger Soft regular. The file stays served for anything outside these
   pages that may still reference it (A-194-06). */

/* ─── Reset ─────────────────────────────────────────────────────────────── */

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

/* ─── Tokens — guide section 1 (Colors) + 2 (Typography) + 5 (Margins) ──── */

:root {
  /* Core */
  --np-daily-green: #DEFF5B;
  --np-true-blue:   #155DD7;
  --np-sky-blue:    #E2F5FA;
  --np-white:       #FFFFFF;

  /* Background roles. Every background uses one of these unless it carries a
     cover image. */
  --np-bg-body:   var(--np-white);
  --np-bg-dark:   var(--np-true-blue);
  --np-bg-light:  var(--np-sky-blue);
  --np-bg-accent: var(--np-daily-green);

  /* Secondary. Only when no core colour conveys the hierarchy. */
  --np-light-gray: #FAFAFA;
  --np-gray:       #4C6B9F;
  --np-gray-50:    rgba(76, 107, 159, 0.5);

  /* Product colours. Declared for completeness, used sparsely — nothing on an
     internal tools site is a product, so no rule below reads them. */
  --np-allergy:        #04B26E;
  --np-beef-broth:     #D4AD88;
  --np-bladder:        #EF3340;
  --np-calm:           #698BFF;
  --np-chicken-broth:  #FFEFB6;
  --np-hip-and-joint:  #E9319B;
  --np-omega-oil:      #FF5F45;
  --np-peanut-butter:  #C27C54;
  --np-probiotic:      #1DBBFF;
  --np-pumpkin:        #FFBC2F;
  --np-relief:         #96E943;
  --np-yak-chews:      #46E7F2;
  --np-skin-and-coat:  #F7ADBB;

  /* Families. Headings and body are F37 Ginger Soft; Adieu carries the
     semantic styles (eyebrow, product name) and the buttons. */
  --np-font-body:    "F37 Ginger Soft", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --np-font-display: "Adieu", ui-sans-serif, system-ui, sans-serif;

  /* Type scale */
  --np-t1: 80px;
  --np-t2: 64px;
  --np-t3: 48px;
  --np-t4: 32px;
  --np-p1: 24px;
  --np-p2: 18px;
  --np-p3: 16px;
  --np-p4: 14px;

  /* Margin scale */
  --np-m1: 4px;
  --np-m2: 8px;
  --np-m3: 16px;
  --np-m4: 24px;
  --np-m5: 40px;
  --np-m6: 60px;
  --np-m7: 120px;

  --np-radius:      24px;
  --np-radius-pill: 100px;

  /* Buttons carry a hard offset shadow, not a blur: the same silhouette
     shifted straight down. Measured off the style-guide artboard. */
  --np-btn-drop: 4px;

  --np-header-h: 64px;
  --np-ease: 0.18s ease-out;
}

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

html { min-height: 100%; }

/* A column so a short page still puts the footer on the floor of the window
   rather than partway up it. */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: var(--np-font-body);
  font-size: var(--np-p3);
  line-height: 1.5;
  background: var(--np-bg-body);
  color: var(--np-true-blue);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection { background: var(--np-bg-accent); color: var(--np-true-blue); }

/* The one element that absorbs the leftover height. */
body > main { flex: 1 0 auto; }

/* ─── Grid and containers — guide section 5 ─────────────────────────────── */

/* 24 columns, no gaps. Containers are column spans, not max-widths: the grid
   is viewport relative (A-194-05). */
.np-grid {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
}

.np-container        { grid-column: 3 / -3; }   /* default — 20 of 24 */
.np-container--large { grid-column: 2 / -2; }   /* large   — 22 of 24 */
.np-container--full  { grid-column: 1 / -1; }   /* full    — 24 of 24 */

/* The guide puts 120px inside a section, dropping to 0 on top when the section
   above shares its background. These pages are a short stack of lists rather
   than a long scrolling page, and at 120px the services sat below the fold, so
   the rhythm is compressed to 40px. The "0 on top after the same background"
   rule is unchanged. */
.np-section { padding-block: var(--np-m5); }
.np-section + .np-section { padding-top: 0; }

/* ─── Typography — guide section 2 ──────────────────────────────────────── */

.np-title-1,
.np-title-2,
.np-title-3,
.np-title-4 {
  font-family: var(--np-font-body);
  font-weight: 400;
  text-transform: lowercase;
  color: var(--np-true-blue);
}

.np-title-1 { font-size: var(--np-t1); line-height: 1.15; }
.np-title-2 { font-size: var(--np-t2); line-height: 1.25; max-width: 40ch; }
.np-title-3 { font-size: var(--np-t3); line-height: 1.25; max-width: 40ch; }
.np-title-4 { font-size: var(--np-t4); line-height: 1.25; max-width: 40ch; }

.np-p1 { font-size: var(--np-p1); }
.np-p2 { font-size: var(--np-p2); }
.np-p3 { font-size: var(--np-p3); }
.np-p4 { font-size: var(--np-p4); }

.np-p1, .np-p2, .np-p3, .np-p4 {
  font-weight: 400;
  line-height: 1.5;
  color: var(--np-true-blue);
}

/* Paragraphs keep 1em between each other and between a paragraph and a title. */
.np-prose > * + * { margin-top: 1em; }

/* Eyebrow — Adieu, uppercase, above a title or by itself. */
.np-eyebrow {
  display: block;
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1.25;
  text-transform: uppercase;
  color: var(--np-true-blue);
}

/* Header group — guide section 4. An eyebrow above a heading. */
.np-header-group .np-eyebrow { margin-bottom: 0.5em; }

/* On a dark background the guide flips headings and eyebrows to white and body
   copy to sky-blue. */
.np-on-dark .np-title-1,
.np-on-dark .np-title-2,
.np-on-dark .np-title-3,
.np-on-dark .np-title-4,
.np-on-dark .np-eyebrow { color: var(--np-white); }

.np-on-dark .np-p1,
.np-on-dark .np-p2,
.np-on-dark .np-p3,
.np-on-dark .np-p4 { color: var(--np-sky-blue); }

/* Secondary text, for hierarchy no core colour carries. */
.np-muted { color: var(--np-gray); }

/* ─── Links — guide section 3 ───────────────────────────────────────────── */

.np-link {
  display: inline-block;
  font-family: var(--np-font-body);
  font-weight: 700;
  font-size: var(--np-p4);
  line-height: 1.5;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--np-true-blue);
  border-bottom: 1px solid currentColor;
  transition: background var(--np-ease), color var(--np-ease);
}

.np-link:hover { background: var(--np-bg-accent); }

.np-on-dark .np-link { color: var(--np-white); }
.np-on-dark .np-link:hover { background: var(--np-bg-accent); color: var(--np-true-blue); }

/* ─── Buttons — guide section 3 ─────────────────────────────────────────── */

.np-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--np-m2);
  height: 48px;
  min-width: 280px;
  padding-inline: var(--np-m6);
  border-radius: var(--np-radius);
  border: 2px solid transparent;
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: box-shadow var(--np-ease), background var(--np-ease), color var(--np-ease);
}

/* Hover, active and focus collapse the drop to zero: the button reads as
   pressed. */
.np-btn:hover,
.np-btn:active,
.np-btn:focus-visible { box-shadow: none; }

/* Focus needs to be visible on its own, so it also takes the outline the guide
   gives controls (EXTENSION, A-194-02). */
.np-btn:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.np-btn--accent {
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
  border-color: var(--np-true-blue);
  box-shadow: 0 var(--np-btn-drop) 0 var(--np-true-blue);
}

.np-btn--dark {
  background: var(--np-bg-dark);
  color: var(--np-daily-green);
  border-color: var(--np-daily-green);
  box-shadow: 0 var(--np-btn-drop) 0 var(--np-daily-green);
}

.np-btn--light {
  background: var(--np-bg-light);
  color: var(--np-true-blue);
  border-color: var(--np-true-blue);
  box-shadow: 0 var(--np-btn-drop) 0 var(--np-true-blue);
}

.np-on-dark .np-btn--light:focus-visible,
.np-on-dark .np-btn--dark:focus-visible { outline-color: var(--np-white); }

/* Small — part of another UI element, or not the main CTA of a section. No
   border, no drop, tighter padding. */
.np-btn--sm {
  height: 48px;
  min-width: 0;
  padding-inline: var(--np-m4);
  border: none;
  box-shadow: none;
}

/* ─── Controls — guide section 3 ────────────────────────────────────────── */

.np-control {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  border: none;
  border-radius: 50%;
  background: var(--np-bg-light);
  color: var(--np-true-blue);
  cursor: pointer;
  transition: background var(--np-ease), color var(--np-ease);
}

.np-control svg { width: 24px; height: 24px; }

.np-control:hover {
  background: var(--np-bg-dark);
  color: var(--np-sky-blue);
}

.np-control:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.np-control--sm { width: 24px; height: 24px; }
.np-control--sm svg { width: 8px; height: 8px; }

/* ─── Cards — guide section 4 ───────────────────────────────────────────── */

/* Sky-blue, 24px radius, no border and no shadow. A card that touches an edge
   loses the radius on that side. */
.np-card {
  background: var(--np-bg-light);
  border-radius: var(--np-radius);
  overflow: hidden;
}

/* Clickable cards need a hover and a focus the guide does not define
   (EXTENSION, A-194-02). Nothing moves, so there is no layout shift. */
.np-card--link {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: box-shadow var(--np-ease);
}

.np-card--link:hover { box-shadow: inset 0 0 0 2px var(--np-true-blue); }

.np-card--link:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

/* ─── HEADER BAR (EXTENSION, A-194-01) ──────────────────────────────────── */

.np-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--np-bg-dark);
  color: var(--np-white);
  border-bottom: 2px solid var(--np-daily-green);
}

.np-header-inner {
  height: var(--np-header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--np-m4);
}

.np-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--np-m3);
  text-decoration: none;
  color: var(--np-daily-green);
  transition: opacity var(--np-ease);
}

.np-brand:hover { opacity: 0.9; }

.np-brand:focus-visible {
  outline: 2px solid var(--np-white);
  outline-offset: 2px;
}

.np-brand-mark {
  display: block;
  width: 132px;
  height: auto;
}

.np-brand-divider {
  width: 1px;
  height: var(--np-m4);
  background: rgba(222, 255, 91, 0.35);
}

.np-brand-tag {
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--np-white);
}

/* Never squeezed: the nav gives way before the address does. */
.np-header-right {
  display: flex;
  align-items: center;
  gap: var(--np-m3);
  flex: 0 0 auto;
}

/* Who is signed in, on the right of every page's header. */
.np-user {
  font-family: var(--np-font-body);
  font-size: var(--np-p4);
  color: var(--np-sky-blue);
  white-space: nowrap;
}

/* Service nav — the guide's link style, on the dark bar. */

/* Takes what is left between the brand and the address, and scrolls rather
   than pushing either of them out of the measure. */
.service-nav {
  display: flex;
  align-items: center;
  gap: var(--np-m4);
  flex: 1 1 auto;
  min-width: 0;
  justify-content: center;
  overflow-x: auto;
  scrollbar-width: none;
}

.service-nav::-webkit-scrollbar { display: none; }

.service-nav-item {
  display: inline-flex;
  align-items: center;
  gap: var(--np-m2);
  padding: var(--np-m1) var(--np-m2);
  font-family: var(--np-font-body);
  font-weight: 700;
  font-size: var(--np-p4);
  line-height: 1.5;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  color: var(--np-white);
  /* No rule under a nav item. The active service is marked by the accent
     block behind it, and a line under every item on top of that was a second
     mark saying nothing (A-194-38). */
  transition: background var(--np-ease), color var(--np-ease);
}

.service-nav-item:hover {
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
}

.service-nav-item:focus-visible {
  outline: 2px solid var(--np-white);
  outline-offset: 2px;
}

/* Active service. */
body[data-page="dashboards"] .service-nav-item[data-service="dashboards"],
body[data-page="apps"]       .service-nav-item[data-service="apps"],
body[data-page="docs"]       .service-nav-item[data-service="docs"],
body[data-page="tools"]      .service-nav-item[data-service="tools"] {
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
}



/* ─── HERO ──────────────────────────────────────────────────────────────── */

/* The guide allows a background colour or a cover image, so the decorative
   radial glows are gone. The banner takes 60px rather than the 120px a content
   section gets, so what follows it is reachable sooner.

   Every page of this service carries the same cover image: the banner is what
   the pages have in common, and giving one of them a photograph and the rest a
   flat colour read as two different sites (EXTENSION, A-194-34). A dashboard
   and an internal application are not part of this: each is its own product
   with its own page furniture, and neither uses this hero.

   The true-blue wash over the photograph is what keeps white text readable, and
   is not something the guide defines. It sits at 90% because this picture
   carries its own wordmark and strapline on the left, where the page title
   goes: any lighter and the two sets of type read on top of each other. The
   flat colour stays as the fallback under it, so a page still reads correctly
   while the image is loading or if it ever fails to.

   The filename carries a hash of the image's contents, the same treatment the
   stylesheet's URL gets: swapping the picture means a new name, so no cached
   copy of an old banner can ever render again. The first swap proved the
   need — the old picture kept showing out of browser caches on some pages
   while the server served the new file (A-194-40). */
.np-hero {
  background:
    linear-gradient(rgba(21, 93, 215, 0.90), rgba(21, 93, 215, 0.90)),
    url("/landing/assets/hero-b936a771.jpg") center / cover no-repeat,
    var(--np-bg-dark);
  padding-block: var(--np-m5);
}

.np-hero-title { margin-bottom: var(--np-m4); }

/* The page badge. An accent pill, no product colour. */
.np-hero-meta {
  display: inline-flex;
  align-items: center;
  gap: var(--np-m3);
  height: 32px;
  padding-inline: var(--np-m3);
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
  border-radius: var(--np-radius-pill);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1;
  text-transform: uppercase;
}

.np-hero-dot { font-size: var(--np-m2); opacity: 0.55; }

/* ─── MAIN SECTIONS ─────────────────────────────────────────────────────── */

/* The heading and its count sit on one baseline. Aligning their boxes on the
   bottom edge and nudging the count up with padding got within nine pixels of
   it and no closer, because a 32px heading and a 14px count have different
   descenders: `baseline` is the alignment that was wanted (A-194-35). */
.np-section-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--np-m5);
  margin-bottom: var(--np-m4);
}

.np-section-count {
  font-family: var(--np-font-body);
  font-size: var(--np-p4);
  color: var(--np-gray);
  white-space: nowrap;
}

/* ─── ANNOUNCEMENTS ─────────────────────────────────────────────────────── */

/* Announcements read top to bottom, each card as wide as the services grid
   below them: a card spans the full container, and several stack. */
.featured-row {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.featured-card {
  width: 100%;
  background: var(--np-bg-light);
  border-radius: var(--np-radius);
  padding: var(--np-m4);
  display: flex;
  flex-direction: column;
  gap: var(--np-m2);
}

.featured-card h3 {
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p1);
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--np-true-blue);
}

.featured-card p {
  font-size: var(--np-p4);
  color: var(--np-gray);
}

.featured-card ul {
  margin: 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: var(--np-m1);
}

.featured-card li {
  font-size: var(--np-p4);
  color: var(--np-gray);
}

.featured-card li::marker { color: var(--np-true-blue); }

.featured-contact a {
  color: var(--np-true-blue);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.featured-contact a:hover { background: var(--np-bg-accent); }

.featured-empty,
.dashboards-empty {
  font-size: var(--np-p3);
  color: var(--np-gray);
}

.dashboards-empty { padding: var(--np-m5) 0; text-align: center; }

/* ─── CARD GRIDS ────────────────────────────────────────────────────────── */

/* Internal grids use the guide's 60px or 30px gap. */
.dashboards-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 30px;
}

.services-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 30px;
}

.np-card-body {
  padding: var(--np-m3);
  display: flex;
  flex-direction: column;
  gap: var(--np-m2);
  flex: 1;
}

/* The title sits on a dark head, so it reads as a label on the card rather than
   as text inside it. A minimum height holds room for a second line, so heads
   keep the same depth across a row, and the title sits on the floor of the head
   so titles line up whether they wrap or not. */
.np-card-head {
  display: flex;
  align-items: flex-end;
  min-height: 77px;
  padding: var(--np-m3);
  background: var(--np-bg-dark);
}

/* Dashboard and app cards name a thing, so they take the guide's product-name
   style in Adieu uppercase, stepped down to 18px because five cards to a row
   leaves about 215px each. */
.np-card-name {
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p2);
  line-height: 1.25;
  text-transform: uppercase;
  color: var(--np-white);
}

.np-card-desc {
  font-size: var(--np-p4);
  color: var(--np-gray);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.np-card-meta {
  display: flex;
  align-items: center;
  gap: var(--np-m2);
  margin-top: auto;
  padding-top: var(--np-m3);
}

.owner-chip {
  display: inline-flex;
  align-items: center;
  padding: var(--np-m1) var(--np-m2);
  background: var(--np-white);
  color: var(--np-true-blue);
  border-radius: var(--np-radius-pill);
  font-weight: 700;
  font-size: var(--np-p4);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── TABLE (on `/apps/`) ───────────────────────────────────────────────── */

/* The guide has no table, so this is the card taken apart: the header row is
   the card's dark head and the body rows are its light body. */
.np-table-wrap {
  border-radius: var(--np-radius);
  overflow: hidden;
}

.np-table-wrap[hidden] { display: none; }

.np-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

.np-table th {
  padding: var(--np-m3) var(--np-m4);
  background: var(--np-bg-dark);
  color: var(--np-white);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1.25;
  text-transform: uppercase;
}

.np-table th:first-child { width: 25%; }

/* The name is set larger than the description beside it, so aligning the cells
   on their top edges left the two lines of type sitting a couple of pixels
   apart. Baseline alignment puts the first line of every cell on one line, at
   any pair of sizes (A-194-35). */
.np-table td {
  padding: var(--np-m3) var(--np-m4);
  background: var(--np-bg-light);
  color: var(--np-gray);
  font-size: var(--np-p4);
  vertical-align: baseline;
  border-top: 1px solid var(--np-white);
}

.np-table tbody tr:first-child td { border-top: 0; }

/* A run of rows under one heading. On the white background role it reads as a
   band separating the groups, rather than as another entry in the list, which
   is what it looked like sharing the rows' sky-blue. */
.np-table .np-group-row th {
  padding: var(--np-m2) var(--np-m4);
  background: var(--np-white);
  color: var(--np-gray);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p4);
  line-height: 1.5;
  text-transform: uppercase;
  border-top: 0;
}

.np-table tbody tr:first-child th { border-top: 0; }
.np-table .np-group-row + tr td { border-top: 0; }

.np-table-owner { white-space: nowrap; }

.np-table-name {
  display: inline-block;
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p2);
  line-height: 1.25;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--np-true-blue);
  border-bottom: 1px solid transparent;
  transition: background var(--np-ease), border-color var(--np-ease);
}

.np-table-name:hover {
  background: var(--np-bg-accent);
  border-bottom-color: currentColor;
}

.np-table-name:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

/* A row with nowhere to go yet. The name is not a link and carries the same
   pill the disabled services use. */
.np-table tr.is-soon td { color: var(--np-gray); }
.np-table tr.is-soon .np-table-name { color: var(--np-gray); }

/* The pill sits on its own line under the name, always. Beside the name it fit
   after a short one and wrapped after a long one, so two rows of the same list
   were laid out differently for no reason a reader could see (A-194-36). Its
   own line is the only arrangement that holds at every column width, down to a
   phone. */
.np-table tr.is-soon .np-table-name { display: block; }

.np-soon {
  display: inline-block;
  margin-top: var(--np-m2);
  padding: var(--np-m1) var(--np-m3);
  border-radius: var(--np-radius-pill);
  background: var(--np-white);
  color: var(--np-gray);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p4);
  line-height: 20px;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}

/* ─── DOCUMENT PAGE ─────────────────────────────────────────────────────── */

/* A document is long-form reading, so the measure is capped rather than running
   the full 20 columns, and centred inside them: pinned to the left it left a
   wide empty margin on the far side of a large screen (EXTENSION, A-194-19).
   The banner's title sits on the same column, so the page reads as one. */
.np-doc,
.np-doc-head {
  /* The banner's block is a grid item, and auto inline margins would make it
     shrink to its content instead of filling the column first. */
  width: 100%;
  max-width: 90ch;
  margin-inline: auto;
}

.np-doc > * + * { margin-top: 1em; }

/* A heading gets more room above it than the paragraph rhythm gives. */
.np-doc > h2 { margin-top: var(--np-m6); }
.np-doc > h3 { margin-top: var(--np-m5); }
.np-doc > .np-table-wrap { margin-top: var(--np-m4); max-width: 480px; }

/* A two-column table inside a document is mostly its first column, unlike the
   three-column index tables. */
.np-doc .np-table th:first-child { width: 60%; }

/* Sub-heading. The guide's product-name style, used as a label inside a
   document. */
.np-subhead {
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p1);
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--np-true-blue);
}

.np-doc-meta {
  font-size: var(--np-p4);
  color: var(--np-gray);
}

.np-list {
  padding-left: var(--np-m4);
  font-size: var(--np-p2);
  line-height: 1.5;
  color: var(--np-true-blue);
}

.np-list li + li { margin-top: 0.5em; }

/* A link inside a sentence keeps the paragraph's size and case: the guide's
   Link is a standalone navigation element, not a word in a line of prose. It
   still takes the accent behind it on hover. */
.np-doc p a:not(.np-link) {
  color: var(--np-true-blue);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  transition: background var(--np-ease);
}

.np-doc p a:not(.np-link):hover { background: var(--np-bg-accent); }

.np-doc-source { margin-top: var(--np-m6); }

/* ─── SERVICE CARDS (on `/`) ────────────────────────────────────────────── */

.service-card {
  display: flex;
  flex-direction: column;
  background: var(--np-bg-light);
  border-radius: var(--np-radius);
  overflow: hidden;
}


.service-card .np-card-body { padding: var(--np-m4); gap: var(--np-m2); }


.service-card .np-card-head { min-height: 128px; padding: var(--np-m4); }

.service-card-title {
  font-family: var(--np-font-body);
  font-weight: 400;
  font-size: var(--np-t4);
  line-height: 1.25;
  text-transform: lowercase;
  color: var(--np-white);
}

.service-card-desc { font-size: var(--np-p4); color: var(--np-gray); }


/* ─── DASHBOARDS HUB CONTROLS ───────────────────────────────────────────── */

.dashboards-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--np-m4);
  margin-bottom: var(--np-m5);
}

/* The search box and the filter button travel together on the right. */
.controls-right {
  display: flex;
  align-items: center;
  gap: var(--np-m2);
  min-width: 0;
}

/* Finding a dashboard by name is the everyday act, so it sits in the open
   rather than inside the filter popover. Same pill language as the controls
   beside it. */
.dash-search {
  height: 48px;
  width: 240px;
  max-width: 100%;
  padding: 0 var(--np-m3);
  border: 1px solid var(--np-gray-50);
  border-radius: var(--np-radius-pill);
  background: var(--np-white);
  font-family: var(--np-font-body);
  font-size: var(--np-p4);
  color: var(--np-true-blue);
}

.dash-search::placeholder { color: var(--np-gray-50); }

.dash-search:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

/* Environment toggle — two small buttons, dark for the current env. */
.env-toggle { display: flex; gap: var(--np-m2); }

.env-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  padding-inline: var(--np-m4);
  border: none;
  border-radius: var(--np-radius);
  background: var(--np-bg-light);
  color: var(--np-true-blue);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--np-ease), color var(--np-ease);
}

.env-btn:hover { background: var(--np-bg-accent); }

.env-btn:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

body[data-env="prod"]    .env-btn[data-env="prod"],
body[data-env="sandbox"] .env-btn[data-env="sandbox"] {
  background: var(--np-bg-dark);
  color: var(--np-daily-green);
}

/* Filters */

.filter-wrap { position: relative; }

.filter-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--np-m2);
  height: 48px;
  padding-inline: var(--np-m4);
  border: none;
  border-radius: var(--np-radius);
  background: var(--np-bg-light);
  color: var(--np-true-blue);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--np-ease), color var(--np-ease);
}

.filter-trigger:hover { background: var(--np-bg-accent); }

.filter-trigger:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.filter-trigger[aria-expanded="true"] {
  background: var(--np-bg-dark);
  color: var(--np-daily-green);
}

.filter-icon { width: 16px; height: 16px; }

.filter-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding-inline: 6px;
  border-radius: var(--np-radius-pill);
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
  font-size: var(--np-p4);
  line-height: 1;
}

.filter-trigger[aria-expanded="true"] .filter-badge {
  background: var(--np-daily-green);
  color: var(--np-true-blue);
}

.filter-badge[hidden] { display: none; }

/* Filter popover — a card. It floats over other cards, so it takes the white
   background role instead of sky-blue: cards carry no shadow, and two
   sky-blue surfaces on top of each other do not read as separate. */

.filter-popover {
  position: absolute;
  top: calc(100% + var(--np-m2));
  right: 0;
  z-index: 60;
  width: 360px;
  max-width: calc(100vw - var(--np-m5));
  background: var(--np-white);
  border-radius: var(--np-radius);
  padding: var(--np-m4);
  display: flex;
  flex-direction: column;
  gap: var(--np-m4);
}

.filter-popover[hidden] { display: none; }

.filter-popover-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--np-m3);
}

.filter-popover-hd h3 {
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p1);
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--np-true-blue);
}

.filter-popover-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 50%;
  background: var(--np-bg-light);
  color: var(--np-true-blue);
  font-size: var(--np-p3);
  line-height: 1;
  cursor: pointer;
  transition: background var(--np-ease), color var(--np-ease);
}

.filter-popover-close:hover { background: var(--np-bg-dark); color: var(--np-sky-blue); }

.filter-popover-close:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.filter-field { display: flex; flex-direction: column; gap: var(--np-m2); }

.filter-field label {
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p3);
  line-height: 1.25;
  text-transform: uppercase;
  color: var(--np-true-blue);
}

.filter-combobox {
  height: 48px;
  padding-inline: var(--np-m4);
  border: 2px solid var(--np-true-blue);
  border-radius: var(--np-radius);
  background: var(--np-white);
  color: var(--np-true-blue);
  font-family: var(--np-font-body);
  font-size: var(--np-p3);
  width: 100%;
}

.filter-combobox::placeholder { color: var(--np-gray-50); }

.filter-combobox:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.filter-hint { font-size: var(--np-p4); color: var(--np-gray); }

.filter-popover-ft { display: flex; justify-content: flex-end; }

/* ─── FOOTER (EXTENSION, A-194-01) ──────────────────────────────────────── */

.np-footer {
  background: var(--np-bg-dark);
  border-top: 2px solid var(--np-daily-green);
  padding-block: var(--np-m4);
}

.np-footer-inner { display: flex; justify-content: center; }

.np-footer-text {
  font-size: var(--np-p3);
  color: var(--np-sky-blue);
  text-align: center;
}

/* An email address is a literal, so this link keeps its own case, and it sits
   inside a sentence so it keeps that sentence's size. */
.np-footer-link { text-transform: none; font-size: inherit; }

/* ─── RESPONSIVE (EXTENSION, A-194-03) ──────────────────────────────────── */

/* The guide only specifies desktop. Below the breakpoints the containers go
   full-bleed with margins from the guide's own scale, the section rhythm drops
   from 120px to 60px, and each title steps down one level. */

@media (max-width: 1280px) {
  /* The bar cannot hold the wordmark, a service label, four nav items and an
     address at once. The address gives way next. */
  .np-user { display: none; }
  .service-nav { gap: var(--np-m3); }
  :root { --np-t1: 64px; --np-t2: 48px; }
  /* Four and five across need the width. Below it the grids step down. */
  .services-grid { grid-template-columns: repeat(2, 1fr); }
  .dashboards-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 1040px) {
  .dashboards-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  :root {
    --np-t1: 48px;
    --np-t2: 40px;
    --np-t3: 32px;
    --np-t4: 24px;
    --np-header-h: 56px;
  }

  .np-container,
  .np-container--large,
  .np-container--full {
    grid-column: 1 / -1;
    padding-inline: var(--np-m3);
  }

  .np-section  { padding-block: var(--np-m4); }
  .np-hero     { padding-block: var(--np-m4); }

  .np-brand-mark { width: 96px; }
  .np-brand-divider, .np-brand-tag { display: none; }
  .np-header-inner { gap: var(--np-m3); }

  /* Three services no longer fit beside the wordmark on a phone. The nav
     scrolls on its own instead of pushing the page sideways. */
  .service-nav {
    justify-content: flex-start;
    gap: var(--np-m2);
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .service-nav::-webkit-scrollbar { display: none; }
  .service-nav-item { font-size: 12px; }

  .np-section-hd { flex-direction: column; align-items: flex-start; gap: var(--np-m2); margin-bottom: var(--np-m4); }
  .np-section-count { padding-bottom: 0; }

  /* The badge holds up to three segments, which do not fit one line on a
     phone. Let it wrap instead of pushing the page sideways. */
  .np-hero-meta {
    flex-wrap: wrap;
    height: auto;
    min-height: 32px;
    padding-block: var(--np-m2);
    gap: var(--np-m2);
    font-size: var(--np-p4);
  }

  .dashboards-grid,
  .services-grid { grid-template-columns: 1fr; gap: 30px; }

  /* Two columns fit a phone. The owner is the one that gives way. */
  .np-table-owner { display: none; }
  .np-table th, .np-table td { padding: var(--np-m3); }

  /* One card per row means one line of title, so the head hugs it instead of
     holding room for a second line. */
  .np-card-head { min-height: 0; }

  .dashboards-controls { flex-direction: column; align-items: stretch; gap: var(--np-m3); }
  .env-toggle { align-self: flex-start; }
  .controls-right { flex-wrap: wrap; }
  .dash-search { flex: 1 1 auto; width: auto; }
  .env-btn, .filter-trigger { height: 40px; }
  .np-btn { height: 40px; min-width: 0; padding-inline: var(--np-m5); }
  .np-btn--sm { height: 40px; }

  .filter-popover { right: 0; width: min(calc(100vw - var(--np-m5)), 320px); }
}

/* ─── FOLDER ORGANIZATION (dashboards hub) ──────────────────────────────── */

/* Folders are presentation metadata over the same cards: the guide has no
   file-system furniture, so the pieces below reuse its language (sky-blue
   surfaces, Adieu labels, the accent for anything active) rather than adding
   a new one (EXTENSION, A-195-xx). */

.folder-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--np-m4);
  margin-bottom: var(--np-m3);
}

.dash-search {
  height: 48px;
  width: 240px;
  max-width: 100%;
  padding: 0 var(--np-m3);
  border: 1px solid var(--np-gray-50);
  border-radius: var(--np-radius-pill);
  background: var(--np-white);
  font-family: var(--np-font-body);
  font-size: var(--np-p4);
  color: var(--np-true-blue);
}

.dash-search::placeholder { color: var(--np-gray-50); }

.dash-search:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.folder-crumbs {
  display: flex;
  align-items: center;
  gap: var(--np-m1);
  flex-wrap: wrap;
  min-width: 0;
}

.crumb {
  border: 0;
  background: transparent;
  padding: var(--np-m1) var(--np-m2);
  border-radius: var(--np-radius-pill);
  font-family: var(--np-font-display);
  font-weight: 400;
  font-size: var(--np-p4);
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--np-true-blue);
  cursor: pointer;
  transition: background var(--np-ease), color var(--np-ease);
}

.crumb:hover { background: var(--np-bg-accent); }

.crumb:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

/* Where you are is a statement, not a control. */
.crumb.is-here { color: var(--np-gray); cursor: default; }

.crumb-sep { color: var(--np-gray-50); font-size: var(--np-p4); }

/* The outcome of an action, under the bar. Errors keep the site's blue and
   say so in words: the palette has no signalling red that is not a product
   colour. */
.org-note {
  margin: 0 0 var(--np-m3);
  font-size: var(--np-p4);
  color: var(--np-gray);
}

.org-note.is-error { color: var(--np-true-blue); font-weight: 700; }

/* ── Folder cards ── */

.folders-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 30px;
  margin-bottom: var(--np-m4);
}

.folders-grid[hidden] { display: none; }

.folder-card {
  display: flex;
  align-items: center;
  gap: var(--np-m2);
  min-width: 0;
  padding: var(--np-m2) var(--np-m3);
  background: var(--np-bg-light);
  border-radius: var(--np-radius);
  cursor: pointer;
  transition: box-shadow var(--np-ease);
}

.folder-card:hover { box-shadow: inset 0 0 0 2px var(--np-true-blue); }

.folder-card:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.folder-icon { display: inline-flex; color: var(--np-true-blue); flex: 0 0 auto; }
.folder-icon svg { width: 22px; height: 22px; }

.folder-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--np-p4);
  font-weight: 700;
  color: var(--np-true-blue);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.folder-count {
  flex: 0 0 auto;
  padding: var(--np-m1) var(--np-m2);
  background: var(--np-white);
  color: var(--np-true-blue);
  border-radius: var(--np-radius-pill);
  font-weight: 700;
  font-size: var(--np-p4);
  line-height: 1;
}

/* Rename and delete ride the card and show on approach, so the resting card
   is just a folder. Touch has no approach: below 760px they are always on. */
.folder-actions { display: inline-flex; gap: var(--np-m1); flex: 0 0 auto; }
.folder-actions .org-icon-btn { opacity: 0; }
.folder-card:hover .org-icon-btn,
.folder-card:focus-within .org-icon-btn { opacity: 1; }

.org-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: var(--np-radius-pill);
  background: transparent;
  color: var(--np-gray);
  cursor: pointer;
  transition: background var(--np-ease), color var(--np-ease), opacity var(--np-ease);
}

.org-icon-btn svg { width: 15px; height: 15px; }

.org-icon-btn:hover { background: var(--np-bg-accent); color: var(--np-true-blue); }

.org-icon-btn:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
  opacity: 1;
}

/* ── Drag state ── */

.is-dragging { opacity: 0.45; }

/* A target ready to take the drop. Dashed, so it reads as "goes in here"
   rather than as the selected state. */
.folder-card.is-drop,
.crumb.is-drop {
  background: var(--np-bg-accent);
  outline: 2px dashed var(--np-true-blue);
  outline-offset: 2px;
}

/* ── Dashboard cards carry a link overlay and the Move button ──
   The face of the card is one anchor laid over it, so the card itself stays
   a plain element and the button is not markup inside a link. */

.dash-card { position: relative; }

.card-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.card-overlay:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 2px;
}

.card-move-btn {
  position: absolute;
  top: var(--np-m2);
  right: var(--np-m2);
  z-index: 2;
  background: rgba(255, 255, 255, 0.16);
  color: var(--np-white);
  opacity: 0;
}

.dash-card:hover .card-move-btn,
.dash-card:focus-within .card-move-btn { opacity: 1; }

.card-move-btn:hover { background: var(--np-bg-accent); color: var(--np-true-blue); }

/* ── The confirmation dialog ──
   Nothing moves, appears or disappears without passing through this. */

.org-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--np-m4);
  background: rgba(21, 93, 215, 0.32);
}

.org-backdrop[hidden] { display: none; }

.org-dialog {
  width: 100%;
  max-width: 460px;
  padding: var(--np-m4);
  background: var(--np-white);
  border-radius: var(--np-radius);
  box-shadow: 0 16px 48px rgba(21, 93, 215, 0.24);
}

.org-dialog-title {
  margin: 0 0 var(--np-m2);
  font-family: var(--np-font-body);
  font-weight: 700;
  font-size: var(--np-p1);
  color: var(--np-true-blue);
}

.org-dialog-lines p {
  margin: 0 0 var(--np-m1);
  font-size: var(--np-p4);
  color: var(--np-gray);
}

.org-dialog-field {
  display: block;
  margin-top: var(--np-m3);
  font-size: var(--np-p4);
  color: var(--np-gray);
}

/* An author display beats the UA's [hidden] rule, so hidden must win again
   explicitly — same pattern as .np-table-wrap[hidden]. */
.org-dialog-field[hidden] { display: none; }

.org-dialog-field span { display: block; margin-bottom: var(--np-m1); }

.org-dialog-field input,
.org-dialog-field select {
  width: 100%;
  height: 44px;
  padding: 0 var(--np-m2);
  border: 1px solid var(--np-gray-50);
  border-radius: 10px;
  background: var(--np-white);
  font-family: var(--np-font-body);
  font-size: var(--np-p3);
  color: var(--np-true-blue);
}

.org-dialog-field input:focus-visible,
.org-dialog-field select:focus-visible {
  outline: 2px solid var(--np-true-blue);
  outline-offset: 1px;
}

.org-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--np-m2);
  margin-top: var(--np-m4);
}

/* ── Responsive, following the dashboard grid's own steps ── */

@media (max-width: 1280px) {
  .folders-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 1040px) {
  .folders-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  .folders-grid { grid-template-columns: 1fr; }
  .folder-bar { flex-direction: column; align-items: stretch; gap: var(--np-m2); }
  /* No hover on touch: the controls are simply there. */
  .folder-actions .org-icon-btn,
  .card-move-btn { opacity: 1; }
}
/* ── Documentation figures (trees, flows, steps, inline code) ─────────────
   Components for the Native Brain documentation pages. Palette and spacing
   come from the existing tokens only. */

.np-fig { margin-top: var(--np-m4); }

/* Small label above a figure */
.np-fig-label {
  font-size: var(--np-p4);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--np-gray);
  margin-top: var(--np-m4);
}

/* Inline code (commands, paths) */
.np-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.85em;
  background: var(--np-bg-light);
  border-radius: 6px;
  padding: 0.15em 0.45em;
  overflow-wrap: anywhere;
}

/* Tree: a root card with a trunk and one card per branch */
.np-tree-root {
  display: inline-block;
  background: var(--np-bg-dark);
  color: var(--np-white);
  border-radius: 12px;
  padding: var(--np-m3) var(--np-m4);
}
.np-tree-root .np-tree-kicker {
  display: block;
  font-family: adieu, "Arial Black", sans-serif;
  font-size: var(--np-p2);
  text-transform: lowercase;
}
.np-tree-root .np-tree-note {
  display: block;
  font-size: var(--np-p4);
  opacity: 0.85;
  margin-top: var(--np-m1);
}
.np-tree-branches {
  list-style: none;
  margin: 0 0 0 var(--np-m4);
  padding: 0;
  border-left: 2px solid var(--np-gray-50);
}
.np-tree-branches li {
  position: relative;
  padding: var(--np-m2) 0 var(--np-m2) var(--np-m4);
}
.np-tree-branches li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: var(--np-m3);
  height: 2px;
  background: var(--np-gray-50);
}
.np-tree-card {
  display: block;
  background: var(--np-bg-light);
  border-radius: 12px;
  padding: var(--np-m3);
  text-decoration: none;
  color: var(--np-true-blue);
}
a.np-tree-card:hover { background: var(--np-bg-accent); }
.np-tree-card .np-tree-title {
  display: block;
  font-weight: 700;
  font-size: var(--np-p2);
}
.np-tree-card .np-tree-desc {
  display: block;
  font-size: var(--np-p3);
  color: var(--np-gray);
  margin-top: var(--np-m1);
}
.np-tree-card .np-tree-more {
  display: inline-block;
  font-size: var(--np-p4);
  font-weight: 700;
  margin-top: var(--np-m2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Flow: pills joined by arrows, wrapping on small screens */
.np-flow {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: 0;
  margin: var(--np-m3) 0 0;
  row-gap: var(--np-m2);
}
.np-flow li {
  background: var(--np-bg-light);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: var(--np-p3);
  color: var(--np-true-blue);
}
.np-flow li + li { margin-left: 28px; position: relative; }
.np-flow li + li::before {
  content: "\2192";
  position: absolute;
  left: -22px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--np-gray);
}
.np-flow .np-flow-end { background: var(--np-bg-accent); }

/* Chips: what a capability covers */
.np-chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--np-m2);
  padding: 0;
  margin: var(--np-m2) 0 0;
}
.np-chips li {
  border: 1px solid var(--np-gray-50);
  border-radius: 999px;
  padding: 5px 13px;
  font-size: var(--np-p4);
  color: var(--np-gray);
  background: var(--np-white);
}

/* Steps: numbered setup instructions */
.np-steps {
  list-style: none;
  counter-reset: np-step;
  padding: 0;
  margin: var(--np-m3) 0 0;
}
.np-steps li {
  counter-increment: np-step;
  position: relative;
  padding-left: 44px;
  font-size: var(--np-p2);
  line-height: 1.5;
  color: var(--np-true-blue);
}
.np-steps li + li { margin-top: var(--np-m3); }
.np-steps li::before {
  content: counter(np-step);
  position: absolute;
  left: 0;
  top: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--np-bg-dark);
  color: var(--np-white);
  display: grid;
  place-items: center;
  font-size: var(--np-p4);
  font-weight: 700;
}

/* ─── NATIVE INVESTORS REPORTING ────────────────────────────────────────────
   The sign-in card and the report stamps. The style guide covers a site people
   read, not one they log into, so the form pieces below are an EXTENSION built
   from its own language: sky-blue surface, Adieu labels, the standard control
   height and radius (A-220-12). Everything else on this site reuses the guide
   unchanged. */

.nir-signin {
  max-width: 520px;
  margin-inline: auto;
  text-align: center;
}

/* The section heading sits on one line above a centred card, so the
   space-between layout the internal hub needs would push it to the edge. */
.nir-signin .np-section-hd { justify-content: center; }

.nir-lede {
  font-size: var(--np-p2);
  color: var(--np-gray);
  margin-bottom: var(--np-m6);
}

.nir-form {
  display: flex;
  flex-direction: column;
  gap: var(--np-m2);
  padding: var(--np-m6);
  background: var(--np-bg-light);
  border-radius: var(--np-radius);
}

.nir-label {
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
  text-align: left;
}

.nir-input {
  height: 48px;
  padding-inline: var(--np-m4);
  border: 2px solid var(--np-white);
  border-radius: var(--np-radius);
  background: var(--np-white);
  font-family: var(--np-font-body);
  font-size: var(--np-p2);
  color: var(--np-true-blue);
}
.nir-input:focus {
  outline: none;
  border-color: var(--np-true-blue);
}

.nir-form .np-btn { margin-top: var(--np-m3); min-width: 0; }

.nir-status {
  margin-top: var(--np-m5);
  font-size: var(--np-p2);
  color: var(--np-gray);
}
.nir-status--ok    { color: var(--np-true-blue); }
.nir-status--error { color: var(--np-omega-oil); }

/* The sign-in wait: the paws stand alone and centred, so the left margin
   that spaces them from a button elsewhere would push them off centre. */
.nir-waiting {
  display: flex;
  justify-content: center;
  margin-top: var(--np-m6);
}
.nir-waiting .thinking { margin-left: 0; }
/* display:flex would otherwise outrank the hidden attribute. */
.nir-waiting[hidden] { display: none; }

/* The data date on a report card, and the empty state. */
.nir-stamp {
  margin-top: var(--np-m3);
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
}

.nir-subhead {
  margin: var(--np-m7) 0 var(--np-m4);
  font-family: var(--np-font-display);
  font-size: var(--np-p3);
  text-transform: uppercase;
  color: var(--np-gray);
}

.nir-empty { color: var(--np-gray); font-size: var(--np-p2); }

/* Sign out sits where the internal site puts the signed-in address. */

/* ─── FOLDERS ON THE REPORTS PAGE ───────────────────────────────────────────
   The folder bar, cards, crumbs and drag states come from the internal hub's
   own rules further up this file (.folder-card, .folder-count, .crumb,
   .is-drop, .is-dragging), so a folder looks the same on both sites. Only the
   two things this page adds are below. */

.nir-org-actions { display: flex; gap: var(--np-m3); }

.nir-org-actions .np-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* The data date on a report card, and the empty state. */
.nir-stamp {
  margin-top: var(--np-m3);
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
}

.nir-empty { color: var(--np-gray); font-size: var(--np-p2); }

.nir-link {
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}
.nir-link:hover { color: var(--np-true-blue); }

.service-nav {
  display: flex;
  align-items: center;
  gap: var(--np-m4);
  flex: 1 1 auto;
  min-width: 0;
  justify-content: center;
  overflow-x: auto;
  scrollbar-width: none;
}

.service-nav::-webkit-scrollbar { display: none; }

.service-nav-item {
  display: inline-flex;
  align-items: center;
  gap: var(--np-m2);
  padding: var(--np-m1) var(--np-m2);
  font-family: var(--np-font-body);
  font-weight: 700;
  font-size: var(--np-p4);
  line-height: 1.5;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  color: var(--np-white);
  /* No rule under a nav item. The active service is marked by the accent
     block behind it, and a line under every item on top of that was a second
     mark saying nothing (A-194-38). */
  transition: background var(--np-ease), color var(--np-ease);
}

.service-nav-item:hover {
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
}

.service-nav-item:focus-visible {
  outline: 2px solid var(--np-white);
  outline-offset: 2px;
}

/* The current section. Marked from the page, so the header's own markup is
   identical everywhere. */
body[data-page="reports"] .service-nav-item[data-service="reports"] {
  background: var(--np-bg-accent);
  color: var(--np-true-blue);
}

/* ─── USERS (admins only) ───────────────────────────────────────────────────*/

.nir-gear-wrap { position: relative; display: inline-flex; }

.nir-gear {
  font-size: 18px;
  line-height: 1;
  color: var(--np-sky-blue);
  text-decoration: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
}
.nir-gear:hover { color: var(--np-daily-green); }

/* The admin screens hang off the gear rather than sitting in the header: they
   are for one person in the building, and the header belongs to the investors. */
.nir-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 30;
  min-width: 150px;
  /* No vertical padding, and the box clips: an item's hover fill is a
     rectangle, and without this it painted past the rounded corners. */
  overflow: hidden;
  background: var(--np-white);
  border-radius: var(--np-radius);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}
.nir-menu a,
.nir-menu button {
  display: block;
  width: 100%;
  padding: var(--np-m2) var(--np-m4);
  font-family: var(--np-font-body);
  font-size: var(--np-p3);
  /* Stated, not inherited: a button does not take the body's line height the
     way a link does, and Sign out came out four pixels shorter than the rows
     above it. */
  line-height: 1.5;
  text-align: left;
  color: var(--np-true-blue);
  text-decoration: none;
  background: none;
  border: 0;
  cursor: pointer;
}
.nir-menu a:hover,
.nir-menu button:hover { background: var(--np-bg-light); }

/* Leaving is not one more place to go, so it sits under a rule. */
.nir-menu-rule {
  height: 1px;
  margin: var(--np-m2) 0;
  border: 0;
  background: var(--np-bg-light);
}

/* ─── USAGE ─────────────────────────────────────────────────────────────────*/

.nir-tabs {
  display: flex;
  gap: var(--np-m2);
  margin-bottom: var(--np-m5);
  border-bottom: 2px solid var(--np-bg-light);
}
.nir-tab {
  padding: var(--np-m2) var(--np-m4);
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
}
.nir-tab:hover { color: var(--np-true-blue); }
.nir-tab.is-on { color: var(--np-true-blue); border-bottom-color: var(--np-true-blue); }
.nir-panel[hidden] { display: none; }

.nir-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--np-m3);
  margin-bottom: var(--np-m5);
}
.nir-ctl { display: flex; flex-direction: column; gap: 6px; }
.nir-ctl span {
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
}
.nir-input--sm { height: 38px; font-size: var(--np-p3); padding-inline: var(--np-m3); }

.nir-chart-lede {
  font-size: var(--np-p3);
  color: var(--np-gray);
  margin-bottom: var(--np-m4);
}

/* Bars in CSS. One chart does not justify carrying a charting library, and a
   count over time is a row of heights. */
/* Everything fits. A chart that scrolls sideways hides the shape it exists to
   show, so the bars share the width they have: the gap narrows as they get
   thinner, and a year of days is a year of days you can see at once. */
.nir-chart {
  display: flex;
  align-items: flex-end;
  gap: var(--bar-gap, 4px);
  height: 220px;
  /* Room above for the counts, below for the axis, and at the sides for the
     first and last labels, which are centred on bars at the very edge and
     would otherwise hang past the chart and push the page. */
  padding: var(--np-m4) 24px 22px;
}
.nir-bar-col {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
}
.nir-bar {
  width: 100%;
  background: var(--np-true-blue);
  border-radius: 3px 3px 0 0;
  min-height: 0;
}
/* A date is wider than the bar it belongs to, so neither the label nor the
   count is allowed to set the column's width — they are centred over it and
   left out of the layout. Otherwise the widest label decides how wide every
   bar is, and the chart pushes past the page. */
.nir-bar-value {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 4px;
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  color: var(--np-true-blue);
  white-space: nowrap;
}
.nir-bar-label {
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--np-gray);
  white-space: nowrap;
}
/* Labels thin out rather than disappear: every bar keeps its slot on the axis,
   and only some of them are written, so the axis still says where you are.
   The full date of any bar is in its tooltip. */
.nir-bar-col.is-quiet .nir-bar-label,
.nir-bar-col.is-quiet .nir-bar-value { display: none; }

.nir-empty {
  font-size: var(--np-p3);
  color: var(--np-gray);
  padding: var(--np-m5) 0;
}

.nir-foot-note {
  margin-top: var(--np-m5);
  font-size: var(--np-p4);
  color: var(--np-gray);
}

/* Somebody with access who has never signed in: on the list, visibly quieter. */
.nir-table tr.is-quiet td { color: var(--np-gray); }

.nir-field { display: flex; flex-direction: column; gap: var(--np-m2); margin-bottom: var(--np-m4); }

/* Dialogs. Adding somebody, and confirming anything that changes access: both
   are deliberate acts, so neither happens from a single click on the page. */
.nir-dialog {
  border: 0;
  border-radius: var(--np-radius);
  padding: var(--np-m6);
  /* 440 left 320px of content, which the longest action row (Cancel plus
     "Use these dates") overflows by 28px, splitting the pair onto two
     lines. 480 holds every dialog this site has on one line. */
  width: min(480px, calc(100vw - var(--np-m5) * 2));
  background: var(--np-white);
  color: var(--np-true-blue);
  /* The page reset zeroes every margin, which also removes the auto margins a
     modal dialog centres itself with. Put them back here only. */
  margin: auto;
}

/* Fields fill the dialog, and their border has to be visible against white:
   the form's own border colour is white, which only reads on the sky-blue
   panel it was written for. */
.nir-dialog .nir-input {
  width: 100%;
  border-color: var(--np-bg-light);
}
.nir-dialog::backdrop { background: rgba(21, 93, 215, 0.35); }
.nir-dialog h2 { margin-bottom: var(--np-m4); }
.nir-dialog-text { font-size: var(--np-p2); color: var(--np-gray); margin-bottom: var(--np-m5); }
.nir-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--np-m5);
  margin-top: var(--np-m5);
}

/* Nothing in this row may shrink below its own label. The button was the only
   item with min-width 0, so every squeeze landed on it alone: the working
   indicator holds its place even while invisible, and a dialog narrower than
   indicator + Cancel + button squashed the button to its own height, which a
   24px radius renders as a circle with the label hanging outside it. Wrapping
   is the honest answer when the row genuinely does not fit. */
.nir-dialog-actions > * { flex: 0 0 auto; }
.nir-dialog .np-btn { min-width: 0; white-space: nowrap; }

select.nir-input { appearance: none; }

.nir-hint { font-size: var(--np-p4); color: var(--np-gray); }

.nir-table { width: 100%; border-collapse: collapse; }
.nir-table th,
.nir-table td {
  text-align: left;
  padding: var(--np-m3) var(--np-m4);
  border-bottom: 1px solid var(--np-bg-light);
  font-size: var(--np-p3);
  color: var(--np-true-blue);
}
.nir-table th {
  font-family: var(--np-font-display);
  font-size: var(--np-p4);
  text-transform: uppercase;
  color: var(--np-gray);
}
.nir-row--revoked td { color: var(--np-gray-50); }
.nir-muted { color: var(--np-gray-50); }

@media (max-width: 720px) {
  .nir-access-form { grid-template-columns: 1fr; }
}

/* The role select inside a table row: shorter than the form fields, so a row
   still reads as a row. */
.nir-input--inline {
  height: 32px;
  padding-inline: var(--np-m2);
  font-size: var(--np-p4);
  border-color: var(--np-bg-light);
}

/* The constraint on a field, said under the field rather than at the foot of
   the page: it matters at the moment somebody picks the role. */
.nir-hint--field { margin-top: var(--np-m2); }

/* ─── THE WAIT INDICATOR ────────────────────────────────────────────────────
   Lifted from the Concept Generator so a wait looks the same across
   nativepet.org: paw prints laid down one after another, turned so the toes
   point the way the walk is going and set either side of the line, which is
   what a track actually looks like.

   It is placed when the page loads and only switched on, so starting a wait
   adds nothing to the layout and the line it sits on does not move. */

.thinking {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-left: 14px;
  color: var(--np-gray);
  font-size: var(--np-p4);
  vertical-align: middle;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease;
}

.thinking.is-on { opacity: 1; }

.tracks { display: inline-flex; align-items: center; gap: 6px; height: 34px; }

.paw {
  width: 18px;
  height: 18px;
  fill: var(--np-true-blue);
  opacity: 0;
  animation: step 2.2s ease-in-out infinite;
  /* Nothing animates until a wait actually starts: paused is the honest
     resting state. */
  animation-play-state: paused;
}

.thinking.is-on .paw,
.thinking.is-on .thinking-dots span { animation-play-state: running; }

/* Each print is turned about a quarter turn, so the toes lead. The small
   differences between them keep it from looking stamped. */
.paw:nth-child(1) { animation-delay: 0s;    transform: translateY(7px)  rotate(84deg); }
.paw:nth-child(2) { animation-delay: 0.25s; transform: translateY(-7px) rotate(96deg); }
.paw:nth-child(3) { animation-delay: 0.5s;  transform: translateY(7px)  rotate(88deg); }
.paw:nth-child(4) { animation-delay: 0.75s; transform: translateY(-7px) rotate(93deg); }
.paw:nth-child(5) { animation-delay: 1s;    transform: translateY(7px)  rotate(86deg); }

.thinking-dots { display: inline-flex; }

.thinking-dots span {
  opacity: 0.25;
  animation: dot-fade 1.2s ease-in-out infinite;
  animation-play-state: paused;
}

.thinking-dots span:nth-child(2) { animation-delay: 0.2s; }
.thinking-dots span:nth-child(3) { animation-delay: 0.4s; }

@keyframes step {
  0%        { opacity: 0; }
  8%        { opacity: 1; }
  70%       { opacity: 1; }
  85%, 100% { opacity: 0; }
}

@keyframes dot-fade {
  0%, 55%, 100% { opacity: 0.25; }
  25%           { opacity: 1; }
}

/* Anyone who has asked not to be shown motion gets the track standing still. */
@media (prefers-reduced-motion: reduce) {
  .paw, .thinking-dots span { animation: none; opacity: 1; }
}

/* Inside a dialog the indicator sits with the buttons. */
/* In a dialog the working indicator takes no room until it is working. Held
   in the flow it reserved its full width while invisible, which in a 320px
   dialog left nothing for the button. On, it sits at the left of the row, and
   wraps onto its own line when the row cannot hold all three. */
.nir-dialog-actions .thinking { display: none; margin: 0; }
.nir-dialog-actions .thinking.is-on {
  display: inline-flex;
  /* Its own line, so appearing never splits Cancel from the button. */
  flex: 1 0 100%;
  justify-content: flex-start;
}

/* A sign-in answer that repeats the same sentence still has to read as a new
   answer, so it fades in each time it is set. */
.nir-status--fresh { animation: nir-fade-in 220ms ease-out; }

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

@media (prefers-reduced-motion: reduce) {
  .nir-status--fresh { animation: none; }
}
