/* Sightline Capital — component layer.
   Each class corresponds to a repeated pattern in the design prototype. Sizes and
   colours are the prototype's values; see tokens.css for the shared scale. */

/* ── Reset ─────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--gray-100);
  font-family: var(--font-sans);
  color: var(--charcoal);
  line-height: 1.6;
}

a {
  color: var(--navy);
}
a:hover {
  color: var(--blue-accent);
}

::selection {
  background: var(--navy);
  color: var(--white);
}

:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

img,
svg {
  max-width: 100%;
}

h1,
h2,
h3,
h4,
p {
  margin: 0;
}

/* Visually hidden but available to screen readers and to form submission. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Typography ────────────────────────────────────────────────────────── */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  color: var(--gray-600);
  text-transform: uppercase;
}
.eyebrow-lg {
  font-size: 10px;
  letter-spacing: 0.2em;
}
.eyebrow-xs {
  font-size: 8.5px;
  letter-spacing: 0.16em;
}
.eyebrow-login {
  font-size: 10px;
  letter-spacing: 0.22em;
}
.eyebrow-portal {
  font-size: 9.5px;
  letter-spacing: 0.18em;
}

.mono {
  font-family: var(--font-mono);
}

.h1 {
  font-size: 24px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.2;
}
.h1-hero {
  font-size: 30px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.2;
}
.h1-portal {
  font-size: 26px;
  font-weight: 600;
  color: var(--navy);
}
.h2 {
  font-size: 19px;
  font-weight: 600;
  color: var(--navy);
}
.h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--navy);
}

.muted {
  color: var(--gray-600);
}
.text-sm {
  font-size: 12.5px;
}
.text-note {
  font-size: 12px;
  color: var(--gray-600);
  line-height: 1.5;
}

/* ── Patriotic accent bar — max once per page (login card only) ─────────── */
.patriotic-bar {
  height: 4px;
  background: linear-gradient(
    to right,
    var(--navy) 0%,
    var(--navy) 33%,
    var(--white) 33%,
    var(--white) 66%,
    var(--red) 66%,
    var(--red) 100%
  );
}

/* ── Cards ─────────────────────────────────────────────────────────────── */
.card {
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.card-md {
  box-shadow: var(--shadow-md);
}
.card-lg {
  box-shadow: var(--shadow-lg);
}
.card-pad {
  padding: 22px 26px;
}
.card-pad-lg {
  padding: 24px 26px;
}
.card-hero {
  padding: 30px 34px;
}

/* Hover-lift only where the card is actually clickable. */
.card-clickable {
  cursor: pointer;
  border: none;
  text-align: left;
  font-family: var(--font-sans);
  transition: all var(--ease);
}
.card-clickable:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}
.row-clickable {
  transition: all var(--ease);
}
.row-clickable:hover {
  box-shadow: var(--shadow-lg);
}

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  font-family: var(--font-sans);
  font-weight: 500;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--ease);
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  /* Several buttons in the design are links — "Back to your funds", "Enter room".
     Without this they render underlined, which no button in the prototype is. */
  text-decoration: none;
}
.btn:disabled {
  cursor: default;
}

.btn-primary {
  background: var(--navy);
  color: var(--white);
  padding: 12px 22px;
  font-size: 13.5px;
}
.btn-primary:hover:not(:disabled) {
  background: var(--navy-light);
  box-shadow: var(--shadow-md);
}

.btn-outline {
  background: var(--white);
  color: var(--navy);
  border: 2px solid var(--navy);
  padding: 10px 20px;
  font-size: 13.5px;
}
.btn-outline:hover:not(:disabled) {
  background: var(--navy);
  color: var(--white);
}

/* Outlined but hovers to a tint rather than inverting — used where inverting
   next to a primary button would read as two competing CTAs. */
.btn-outline-soft {
  background: var(--white);
  color: var(--navy);
  border: 2px solid var(--navy);
  padding: 10px 18px;
  font-size: 13px;
}
.btn-outline-soft:hover:not(:disabled) {
  background: var(--gray-100);
}

.btn-block {
  width: 100%;
}
.btn-lg {
  padding: 14px 24px;
  font-size: 15px;
}

/* Compact variants used inside table rows. */
.btn-sm {
  padding: 6px 13px;
  font-size: 12px;
  border-radius: var(--radius-btn-sm);
}
.btn-sm-outline {
  background: var(--white);
  color: var(--navy);
  border: 1px solid var(--navy);
}
.btn-sm-outline:hover {
  background: var(--navy);
  color: var(--white);
}
.btn-sm-primary {
  background: var(--navy);
  color: var(--white);
}
.btn-sm-primary:hover {
  background: var(--navy-light);
}

/* Disabled "Package requested" state: gray text, gray border, no hover. */
.btn-spent {
  background: var(--white);
  color: var(--gray-600);
  border: 2px solid var(--gray-300);
  padding: 10px 18px;
  font-size: 13px;
}

.btn-danger-outline {
  background: var(--white);
  color: var(--red);
  border: 1px solid var(--red);
  padding: 5px 12px;
  font-size: 11.5px;
  border-radius: var(--radius-btn-sm);
}
.btn-icon {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  line-height: 1;
}
/* Also used on an anchor: a modal's × is a link back to the screen beneath it, so
   the modal closes without JavaScript. */
.btn-close {
  background: none;
  border: none;
  font-size: 20px;
  color: var(--gray-600);
  cursor: pointer;
  line-height: 1;
  padding: 2px 6px;
  text-decoration: none;
}

/* ── Forms ─────────────────────────────────────────────────────────────── */
.label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--charcoal);
  margin-bottom: 7px;
}
.label-sm {
  font-size: 12.5px;
  margin-bottom: 6px;
}

.input,
.select,
.textarea {
  width: 100%;
  padding: 13px 14px;
  border: 2px solid var(--gray-300);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--charcoal);
  background: var(--white);
  transition: all var(--ease);
}
.input-sm,
.select-sm {
  padding: 11px 13px;
  font-size: 13.5px;
}
.textarea {
  min-height: 76px;
  font-size: 13.5px;
  resize: vertical;
}
.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: var(--focus-ring);
}
.checkbox {
  accent-color: var(--navy);
  width: 15px;
  height: 15px;
}
.check-row {
  display: flex;
  gap: 9px;
  align-items: center;
  cursor: pointer;
  font-size: 13px;
  color: var(--charcoal);
}
.field {
  margin-bottom: 18px;
}

/* ── Chips ─────────────────────────────────────────────────────────────── */
.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--radius-sm);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.chip-green {
  background: var(--green-bg);
  color: var(--green);
}
.chip-amber {
  background: var(--amber-bg);
  color: var(--amber-text);
}
.chip-gray {
  background: var(--gray-100);
  color: var(--gray-600);
}
.chip-revoked {
  background: var(--gray-100);
  color: var(--red);
}
.chip-outline-navy {
  border: 1px solid var(--navy);
  color: var(--navy);
  background: var(--white);
}
.chip-outline-gray {
  border: 1px solid var(--gray-300);
  color: var(--gray-600);
  background: var(--white);
}
/* Solid navy/green badges (NDA signed, room hero). */
.badge-solid-green {
  display: inline-block;
  padding: 5px 14px;
  background: var(--green);
  color: var(--white);
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
}

/* Mono action chips in the audit log. */
.chip-action {
  display: inline-block;
  padding: 2px 9px;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  border: 1px solid var(--gray-300);
  color: var(--gray-600);
  white-space: nowrap;
}
.chip-action-green {
  border-color: var(--green);
  color: var(--green);
}
.chip-action-red {
  border-color: var(--red);
  color: var(--red);
}

/* Portal room-status chips carry a border in all three states so the row's
   vertical rhythm doesn't shift between INVESTED / UNDER REVIEW / NDA REQUIRED. */
/* ── Fund portal (§4) ──────────────────────────────────────────────────────
   Desktop values are exactly what the screen carried as inline styles before the
   responsive pass; they moved here so the 760px breakpoint can reach them. */
.portal-page {
  min-height: 100vh;
  padding: 52px 24px 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.portal-col {
  width: var(--portal-width);
  max-width: 100%;
}
.portal-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 36px;
}
.portal-user-name {
  font-size: 13px;
  color: var(--charcoal);
  font-weight: 500;
}
.portal-lede {
  font-size: 14.5px;
  color: var(--gray-600);
  margin-bottom: 34px;
}
.portal-group {
  margin-bottom: 32px;
}
.portal-card {
  padding: 20px 24px;
}
.portal-card-line {
  margin-bottom: 5px;
}
.portal-fund {
  font-size: 16px;
  font-weight: 600;
  color: var(--navy);
}
.portal-meta {
  font-size: 12.5px;
  color: var(--gray-600);
}
.portal-news {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--blue-accent);
}
.portal-foot {
  font-size: 12px;
  color: var(--gray-600);
  margin-top: 28px;
  text-align: center;
}
.portal-foot-link {
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
}

.chip-room {
  display: inline-block;
  padding: 2px 9px;
  border-radius: var(--radius-sm);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
}
.chip-room-invested {
  background: var(--green-bg);
  border-color: var(--green-bg);
  color: var(--green);
}
.chip-room-review {
  background: var(--white);
  border-color: var(--navy);
  color: var(--navy);
}
.chip-room-nda {
  background: var(--white);
  border-color: var(--gray-300);
  color: var(--gray-600);
}

/* ── Toggle (40×22 pill, navy when on) ─────────────────────────────────── */
.toggle {
  width: 40px;
  height: 22px;
  border-radius: 11px;
  border: none;
  background: var(--gray-300);
  cursor: pointer;
  position: relative;
  transition: background var(--ease);
  padding: 0;
  flex: none;
}
.toggle[aria-checked='true'] {
  background: var(--navy);
}
.toggle::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--white);
  transition: left var(--ease);
  box-shadow: var(--shadow-toggle-knob);
}
.toggle[aria-checked='true']::after {
  left: 21px;
}
/* A revoked member's download rule is not editable until they are restored. */
.toggle:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}
.toggle-row {
  display: flex;
  align-items: center;
  gap: 14px;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-md);
  padding: 13px 16px;
}
.toggle-row-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--charcoal);
}
.toggle-row-desc {
  font-size: 11.5px;
  color: var(--gray-600);
  margin-top: 2px;
}

/* ── Tables (CSS grid; column templates set per screen) ────────────────── */
.table-wrap {
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow-x: auto;
}
.table-head {
  background: var(--navy);
  color: var(--white);
  display: grid;
  gap: 12px;
  padding: 13px 20px;
  font-size: 12.5px;
  font-weight: 600;
}
.table-head-sm {
  padding: 11px 20px;
  font-size: 12px;
}
.table-row {
  display: grid;
  gap: 12px;
  align-items: center;
  border-bottom: 1px solid var(--gray-200);
  padding: 12px 20px;
}
.table-row-tight {
  padding: 10px 20px;
}
/* Row rendered as a button (documents browser) must not look like one. */
.table-row-btn {
  width: 100%;
  background: var(--white);
  border: none;
  border-bottom: 1px solid var(--gray-200);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  transition: background var(--ease-fast);
}
.table-row-btn:hover {
  background: var(--gray-100);
}
.table-title {
  padding: 18px 20px 0;
}
.cell-truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* ── File-type tile ────────────────────────────────────────────────────── */
.file-tile {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-btn-sm);
  background: var(--gray-100);
  color: var(--navy);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.04em;
  font-weight: 600;
  flex: none;
}
.file-tile-xlsx {
  background: var(--green-bg);
  color: var(--green);
}

/* ── KPI band (hairline-divided, inside the hero card) ─────────────────── */
.kpi-band {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--gray-200);
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-top: 26px;
}
.kpi-cell {
  background: var(--white);
  padding: 18px 20px;
}
.kpi-value {
  font-size: 24px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.1;
}
.kpi-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  color: var(--gray-600);
  margin-top: 6px;
}
/* Standalone KPI cards on the activity screen run one step larger, and carry
   their own padding rather than the hairline-divided band's. */
.kpi-card {
  padding: 20px 22px;
}
.kpi-card .kpi-value {
  font-size: 26px;
}
.kpi-card .kpi-label {
  margin-top: 7px;
}

/* ── Callout ───────────────────────────────────────────────────────────── */
.callout-warning {
  background: var(--amber-bg);
  border-left: 4px solid var(--red);
  border-radius: var(--radius-md);
  padding: 16px 20px;
}
.callout-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--charcoal);
  margin-bottom: 4px;
}
.callout-body {
  font-size: 13px;
  color: var(--charcoal);
  line-height: 1.6;
}

/* ── Wire instructions card (§11) ──────────────────────────────────────────
   A navy header strip over label/value rows. `.table-head` is the only other navy
   strip in the file and is a grid at 13px/20px padding, so it does not fit; these
   are the design's own numbers. The card needs `overflow:hidden` for the radius to
   clip the header, which is why .wire-card is not just .card .card-md. */
.wire-card {
  overflow: hidden;
}
.wire-head {
  background: var(--navy);
  color: var(--white);
  padding: 16px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.wire-head-title {
  font-size: 14.5px;
  font-weight: 600;
  flex: 1;
}
/* The lock + VIEW ONLY tag. Deliberately borderless, unlike .viewer-chip.
   The prototype writes rgba(255,255,255,0.7) inline; --on-navy is 0.72 and is what
   every other piece of secondary text on navy in this app uses, so it is used here
   rather than introducing a one-off literal two hundredths away from it. */
.wire-tag {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.12em;
  color: var(--on-navy);
}
.wire-body {
  padding: 10px 24px 22px;
}
/* The design specifies `padding:12px 0` for this control, where `.btn-outline` is
   10px 20px. Full-width, so the horizontal padding is irrelevant and the vertical is
   what sets the 44px height the design draws.

   `line-height: normal` because the two states are different elements: revealing is a
   form submit (`<button>`, which does not inherit the body's 1.6) and hiding is a link
   back to the masked page (`<a>`, which does). Without this the control grows 6px the
   moment it is revealed, which reads as the card twitching. */
.wire-body .btn {
  padding: 12px 0;
  line-height: normal;
}
/* `padding:13px 0` and the hairline are the design's. Line height is deliberately
   left to the app's 1.6 baseline, which the design does not specify for these rows —
   so a row here is ~49px against the ~43px a tighter leading would give. Matching the
   rest of the application's rhythm was preferred to inventing a number the handoff
   does not state. */
.wire-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid var(--gray-200);
}
/* The last row carries no hairline. Scoped to the rows wrapper so the reveal form
   below them cannot change which row is last. */
.wire-rows > .wire-row:last-child {
  border-bottom: none;
}
.wire-label {
  font-size: 13px;
  color: var(--gray-600);
}
.wire-value {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--charcoal);
  text-align: right;
}
/* ABA and account number only — mono so the masked and revealed forms align. */
.wire-value-mono {
  font-family: var(--font-mono);
}

/* ── Subscription packets (§16, #23) ───────────────────────────────────────
   Two screens share these: the investor's packet card and the admin E-signature
   page. Every number is the design's own — see the prototype's §16 markup rather
   than rounding any of them. */

/* The bordered provider chip. Two sizes in the design: 8.5px/`.1em` on the
   investor's card next to the packet heading, and 9.5px/`.1em` in the admin page
   head with a status dot. `.chip-outline-gray` is 11px with no icon slot, so it
   does not fit either. */
.provider-chip {
  display: flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-chip);
  padding: 5px 10px;
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.1em;
  color: var(--charcoal);
  white-space: nowrap;
}

/* `DOCUSIGN CONNECTED` and its two honest alternatives. The border and the dot
   carry the state; there is deliberately no deep-red variant, because deep red is
   for critical, warning, revoked and blocked, and a configuration gap on a
   staff-only screen does not earn a fifth sanctioned use. */
.status-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--green);
  border-radius: var(--radius-btn-sm);
  padding: 8px 14px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: var(--green);
  white-space: nowrap;
}
.status-chip::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  flex: none;
}
.status-chip-warn {
  border-color: var(--amber-text);
  color: var(--amber-text);
}
.status-chip-warn::before {
  background: var(--amber-text);
}
.status-chip-off {
  border-color: var(--gray-300);
  color: var(--gray-600);
}
.status-chip-off::before {
  background: var(--gray-300);
}

/* One document in the investor's packet. `.file-tile` is already the design's 30px
   PDF glyph, so only the row around it is new. */
.packet-row {
  display: flex;
  align-items: center;
  gap: 13px;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-md);
  padding: 12px 15px;
}
.packet-name {
  flex: 1;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--charcoal);
  min-width: 0;
}

/* Two full-width buttons at two different sizes, because the design gives them two
   different sizes: the investor's "Review and sign" is `padding:14px 0;
   font-size:14.5px` and the administrator's "Issue packet" is `13px 0; 14px`.
   Neither is `.btn-primary` (12px/13.5px) or `.btn-lg` (14px 24px/15px), and §1 says
   the fractional sizes are deliberate rather than roundable.

   `line-height: normal` for the reason Sprint 8 discovered on the reveal control:
   the sign button is a `<button>`, which does not inherit the body's 1.6, and the
   executed-copy control beneath it is an `<a>`, which does. Without this the second
   control is six pixels taller than the first and the card visibly changes shape
   the moment a packet completes.

   No `margin-top` on either: the block above each already carries its own bottom
   margin, and adding one here spaced the sign button 32px below the document rows
   where the design draws 20px. The executed-copy link sets its own gap instead. */
.packet-cta {
  padding: 14px 0;
  font-size: 14.5px;
  line-height: normal;
}
.packet-issue-cta {
  padding: 13px 0;
  font-size: 14px;
  line-height: normal;
}
/* Appears only once a packet is executed, beneath the binding note. */
.packet-executed-link {
  margin-top: 12px;
}

/* The investor packet card. `card-md`'s shadow and a padding the design states
   directly — `.card-pad-lg` is 24px 26px, which is the *other* card on this screen. */
.packet-card {
  padding: 26px 28px;
}
/* 16px, where `.h3` is 15px. The two headings on this screen are different sizes in
   the design and §1 says not to tidy that. */
.packet-card-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--navy);
  margin: 0;
  flex: 1;
}
/* 12.5px, not `.text-note`'s 12px. Used for both cards' sub-headings. */
.card-subtitle {
  font-size: 12.5px;
  color: var(--gray-600);
  margin: 0 0 18px;
}
/* 11.5px, the smallest of the three note sizes the design uses on these screens. */
.packet-note {
  font-size: 11.5px;
  color: var(--gray-600);
  line-height: 1.5;
  margin-top: 12px;
}

/* "How it works" — 24px navy circles. */
.step-circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  flex: none;
}
.step-body {
  font-size: 13px;
  color: var(--charcoal);
  line-height: 1.55;
}
.ir-contact {
  border-top: 1px solid var(--gray-200);
  margin-top: 18px;
  padding-top: 14px;
  font-size: 12px;
  color: var(--gray-600);
  line-height: 1.5;
}
.ir-contact-link {
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
}

/* The envelopes table. Five columns at the design's own track sizes, and the
   `min-width` is what makes the card's `overflow-x:auto` do anything — below it the
   columns would overlap, which §17 explicitly forbids. */
.envelope-grid {
  grid-template-columns: minmax(130px, 1.4fr) minmax(160px, 1.6fr) 70px 160px 110px;
}
.envelope-table {
  min-width: 720px;
}
/* `AWAITING COUNTERSIGN` at 11px semibold is about 170px wide and the design gives the
   Status column a 160px track, so the chip cannot fit on one line — and the design's own
   chip markup carries no `white-space`, so in the prototype it wraps onto two.
   `.chip` is `nowrap` because that is right everywhere else it is used; here it made the
   longest and most important status the one that got clipped mid-word. Checked against
   the prototype rendered at this width rather than against memory. */
.envelope-grid .chip {
  white-space: normal;
}

/* ── Toast (navy pill, bottom-centre, ~4s) ─────────────────────────────── */
.toast {
  position: fixed;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 120;
  background: var(--navy);
  color: var(--white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-toast);
  padding: 13px 22px;
  font-size: 13.5px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 11px;
}
.toast[hidden] {
  display: none;
}

/* ── Modals ────────────────────────────────────────────────────────────── */
.scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim-modal);
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.modal {
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);
  overflow: hidden;
  max-width: 100%;
}
.modal-head {
  padding: 22px 28px 0;
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.modal-foot {
  padding: 14px 28px 22px;
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  border-top: 1px solid var(--gray-200);
  margin-top: 12px;
}

/* ── Watermark layer (visual only — production burns it into the raster) ── */
.watermark-layer {
  position: absolute;
  inset: -80px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  transform: rotate(var(--watermark-angle));
  pointer-events: none;
  user-select: none;
}
.watermark-line {
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: 0.14em;
  color: var(--watermark-color);
  white-space: nowrap;
  text-align: center;
}

/* ── App shell ─────────────────────────────────────────────────────────── */
.shell {
  display: flex;
  min-height: 100vh;
}
.sidebar {
  width: var(--sidebar-width);
  flex: none;
  background: var(--navy);
  display: flex;
  flex-direction: column;
  padding: 26px 0 20px;
}
.sidebar-label {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.18em;
  color: var(--on-navy-muted);
  margin: 0 26px 10px;
}
.nav {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 0 12px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  background: transparent;
  color: var(--on-navy);
  border: none;
  border-radius: var(--radius-md);
  padding: 11px 14px;
  font-size: 14px;
  font-weight: 400;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  text-decoration: none;
  transition: background var(--ease-fast);
}
.nav-item:hover {
  background: var(--on-navy-hover-bg);
  color: var(--on-navy-strong);
}
.nav-item[aria-current='page'] {
  background: var(--on-navy-active-bg);
  color: var(--on-navy-strong);
  font-weight: 600;
}
.switch-fund {
  display: flex;
  align-items: center;
  gap: 7px;
  background: transparent;
  border: 1px solid var(--on-navy-border);
  border-radius: var(--radius-btn-sm);
  padding: 6px 11px;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 11.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.8);
  text-decoration: none;
  transition: background var(--ease-fast);
}
.switch-fund:hover {
  background: rgba(255, 255, 255, 0.1);
}
.avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--blue-accent);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  flex: none;
}
.main {
  flex: 1;
  min-width: 0;
  padding: 30px 36px 48px;
  max-width: var(--main-max-width);
}

/* ── Page header ───────────────────────────────────────────────────────── */
.page-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.page-head-main {
  flex: 1;
  min-width: 260px;
}

/* ── Grids ─────────────────────────────────────────────────────────────── */
.grid-sections {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
}
.grid-cards-300 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
}
.grid-cards-320 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 20px;
  align-items: start;
}
.grid-cards-340 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 20px;
  align-items: start;
}
.grid-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

/* ── Section card (document sections on room home) ─────────────────────── */
.sec-card-code {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--blue-accent);
  margin-bottom: 8px;
}
.sec-card-name {
  font-size: 15.5px;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 8px;
}

/* ── Document tree ─────────────────────────────────────────────────────── */
.tree {
  width: var(--tree-width);
  flex: none;
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 12px 8px;
}
.tree-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  padding: 9px 10px;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  text-decoration: none;
  transition: background var(--ease-fast);
}
.tree-row:hover {
  background: var(--gray-100);
}
.tree-row[aria-current='true'] {
  background: var(--gray-100);
}
.tree-row[aria-current='true'] .tree-name {
  font-weight: 600;
}
.tree-caret {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--gray-600);
  width: 10px;
  flex: none;
}
.tree-name {
  flex: 1;
  font-size: 13px;
  font-weight: 400;
  color: var(--charcoal);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tree-count {
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--gray-600);
}
.tree-row-nested {
  padding-left: 32px;
}

/* ── Auth screens ──────────────────────────────────────────────────────── */
.auth-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  gap: 22px;
}
.auth-card {
  width: var(--auth-card-width);
  max-width: 100%;
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.auth-card-body {
  padding: 40px 44px 32px;
}
.auth-card-foot {
  border-top: 1px solid var(--gray-200);
  padding: 16px 44px;
  background: var(--gray-100);
  text-align: center;
  font-size: 12.5px;
  color: var(--gray-600);
}
.auth-registration {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  color: var(--gray-600);
  text-align: center;
  line-height: 1.9;
}
.auth-notice {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  font-size: 12px;
  color: var(--gray-600);
  line-height: 1.5;
}
.auth-notice svg {
  flex: none;
  margin-top: 1px;
}

/* OTP boxes. The design specifies six 48×56 boxes; the emailed code is seven
   characters, so the box shrinks to 44×54 with an 8px gap (7×44 + 6×8 = 356px)
   to stay inside the 450px card's 362px inner width. */
.otp-row {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-bottom: 14px;
}
.otp-box {
  width: 44px;
  height: 54px;
  border: 2px solid var(--gray-300);
  border-radius: var(--radius-md);
  text-align: center;
  font-family: var(--font-sans);
  font-size: 22px;
  font-weight: 600;
  color: var(--navy);
  background: var(--white);
  text-transform: uppercase;
  padding: 0;
}
.otp-box:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: var(--focus-ring);
}

/* ── Room footer (configurable per-room legal disclaimer) ──────────────── */
.room-footer {
  border-top: 1px solid var(--gray-200);
  margin-top: 32px;
  padding-top: 16px;
  font-size: 11.5px;
  color: var(--gray-600);
  line-height: 1.6;
  max-width: 900px;
}

/* ── Bar chart ─────────────────────────────────────────────────────────── */
.chart {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 110px;
}
.chart-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  height: 100%;
  justify-content: flex-end;
}
.chart-bar {
  width: 100%;
  max-width: 34px;
  background: var(--navy);
  border-radius: 4px 4px 0 0;
}
.chart-bar-latest {
  background: var(--blue-accent);
}
.chart-label {
  font-family: var(--font-mono);
  font-size: 8.5px;
  color: var(--gray-600);
}

/* ── Utilities ─────────────────────────────────────────────────────────── */
.flex {
  display: flex;
}
.items-center {
  align-items: center;
}
.items-start {
  align-items: flex-start;
}
.items-baseline {
  align-items: baseline;
}
.justify-between {
  justify-content: space-between;
}
.justify-end {
  justify-content: flex-end;
}
.flex-1 {
  flex: 1;
}
.flex-none {
  flex: none;
}
.flex-col {
  flex-direction: column;
}
.flex-wrap {
  flex-wrap: wrap;
}
.gap-6 {
  gap: 6px;
}
.gap-8 {
  gap: 8px;
}
.gap-10 {
  gap: 10px;
}
.gap-12 {
  gap: 12px;
}
.gap-14 {
  gap: 14px;
}
.gap-16 {
  gap: 16px;
}
.gap-18 {
  gap: 18px;
}
.gap-20 {
  gap: 20px;
}
.ml-auto {
  margin-left: auto;
}
.mt-auto {
  margin-top: auto;
}
.divider {
  border-top: 1px solid var(--gray-200);
}
.stack-10 {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.stack-12 {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.stack-14 {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ── Document viewer ───────────────────────────────────────────────────── */
.viewer-scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim-viewer);
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 26px 20px;
  overflow: auto;
}
.viewer-col {
  width: var(--viewer-width);
  max-width: 100%;
}
.viewer-bar {
  background: var(--navy-dark);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 18px;
}
.viewer-bar-top {
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.viewer-bar-bottom {
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  padding: 9px 18px;
  justify-content: center;
}
.viewer-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--white);
  flex: 1;
}
.viewer-meta {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
.viewer-chip {
  display: flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--on-navy-border);
  border-radius: var(--radius-chip);
  padding: 5px 10px;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
.viewer-download {
  display: flex;
  align-items: center;
  gap: 7px;
  background: var(--white);
  border-radius: var(--radius-chip);
  padding: 6px 12px;
  text-decoration: none;
  white-space: nowrap;
}
.viewer-download:hover {
  background: var(--gray-100);
}
.viewer-close {
  color: var(--white);
  font-size: 20px;
  line-height: 1;
  padding: 2px 6px;
  text-decoration: none;
}
.viewer-close:hover {
  color: var(--white);
  opacity: 0.7;
}
.viewer-versions {
  background: var(--gray-100);
  border-bottom: 1px solid var(--gray-200);
  padding: 8px 18px;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
/* ── Worksheet tabs ────────────────────────────────────────────────────────
   Shown only for a converted spreadsheet, where each sheet is exactly one page.
   The tabs are ordinary in-page links; the active highlight is added by
   public/js/viewer.js and its absence costs nothing. */
.viewer-sheets {
  background: var(--gray-100);
  border-bottom: 1px solid var(--gray-200);
  padding: 7px 18px;
  display: flex;
  align-items: center;
  gap: 6px;
  overflow-x: auto;
  /* A workbook can carry a great many sheets; the strip scrolls rather than
     wrapping into a block that pushes the document off screen. */
  flex-wrap: nowrap;
  scrollbar-width: thin;
}
.viewer-sheets .eyebrow {
  flex: none;
  margin-right: 6px;
}
.viewer-sheet-tab {
  flex: none;
  padding: 3px 9px;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  color: var(--navy);
  text-decoration: none;
  border: 1px solid var(--gray-200);
  border-radius: 3px;
  background: var(--white);
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.viewer-sheet-tab:hover {
  border-color: var(--navy);
}
/* A sheet hidden in the workbook is exported into the PDF anyway, so it is
   labelled rather than omitted — dashed, to read as "not part of the visible
   workbook". See services/documents/workbook.ts. */
.viewer-sheet-tab-hidden {
  border-style: dashed;
  color: var(--gray-600, #666666);
  font-style: italic;
}
.viewer-sheet-tab[aria-current='true'] {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--white);
  font-weight: 600;
}
.viewer-pages {
  background: var(--white);
}
.viewer-page-frame + .viewer-page-frame {
  border-top: 1px solid var(--gray-200);
}
/* Anchored by the sheet tabs, so a jump should not tuck the page under the
   sticky top bar. */
.viewer-page-frame {
  scroll-margin-top: 8px;
}
/* A worksheet page is as wide as the sheet, not as wide as the column: the frame
   pans instead of scaling the numbers down to nothing. */
.viewer-page-frame-sheet {
  overflow-x: auto;
  overflow-y: hidden;
}
/* Selection and dragging are switched off on the page images. This is deterrence,
   not a control — the real protection is that the bytes are a watermarked raster
   and the source file has no URL at all. */
.viewer-page {
  display: block;
  width: 100%;
  height: auto;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.viewer-page-sheet {
  /* Natural size, not fitted to the column: `SinglePageSheets` makes the PDF page
     as large as the sheet's used range, so scaling it down is what would make the
     numbers unreadable. Centred, because a narrow sheet — a one-column summary —
     would otherwise sit against the left edge of an empty row. */
  width: auto;
  max-width: none;
  margin: 0 auto;
}
.viewer-footnote {
  font-size: 8.5px;
  letter-spacing: 0.14em;
  color: var(--on-navy-muted);
  text-align: center;
}

/* ── Upload / admin forms ──────────────────────────────────────────────── */
.file-input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--charcoal);
}
.file-input::file-selector-button {
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--navy);
  border-radius: var(--radius-btn-sm);
  padding: 7px 14px;
  margin-right: 12px;
  cursor: pointer;
}
.form-error {
  background: var(--amber-bg);
  border-left: 4px solid var(--red);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  font-size: 13px;
  color: var(--charcoal);
  line-height: 1.5;
}

/* The date range and Export CSV, side by side in the page header (#39). Wraps as a
   unit so the two dates never separate from the button that applies them. */
.range-controls {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
}
.range-controls .input-sm[type='date'] {
  width: 148px;
}

/* ── Q&A (§9, §10) ──────────────────────────────────────────────────────────
   Question and answer bodies are the first free-form investor text in the system.
   Line breaks are preserved here, in CSS, and never by substituting <br> into the
   markup: `pre-wrap` needs no raw-HTML path, and a newline-to-<br> pass would be
   exactly the raw-HTML path #21 asks us not to introduce. `break-word` because a
   pasted URL or an unbroken string must not widen the card past its column.
   ───────────────────────────────────────────────────────────────────────── */
.qa-body {
  white-space: pre-wrap;
  overflow-wrap: break-word;
  color: var(--charcoal);
}

/* The gray panel the answer sits in, under its SIGHTLINE CAPITAL · DATE label. */
.qa-answer {
  background: var(--gray-100);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  margin-top: 12px;
}

/* What the room was shown, for the one person entitled to check it: the asker. */
.qa-published-note {
  border-top: 1px solid var(--gray-200);
  margin-top: 12px;
  padding-top: 10px;
}

/* The private original on the confirmation step — never published, and styled so it
   does not read as the thing being published. */
.qa-original {
  background: var(--gray-100);
  border-left: 3px solid var(--gray-300);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  margin-bottom: 16px;
}

/* The preview is the published card. Outlined in navy so it reads as a specimen of
   what the room receives rather than as another form field. */
.qa-preview {
  border: 1px solid var(--navy);
  padding: 18px 22px;
  box-shadow: none;
}

.textarea-answer {
  min-height: 60px;
  padding: 12px 13px;
  font-size: 13px;
  margin-bottom: 11px;
}

/* The deep-red outlined open counter. Deep red is reserved for critical, warning,
   revoked and blocked — an unanswered investor question is the design's own call on
   which of those it is, and the counter is the only place it is spent on this screen. */
.counter-open {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--red);
  border: 1px solid var(--red);
  border-radius: var(--radius-sm);
  padding: 5px 11px;
  white-space: nowrap;
  flex: none;
}

/* One pending full-package request (#31). */
.pkg-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  border-top: 1px solid var(--gray-200);
  padding-top: 10px;
}
.pkg-row:first-child {
  border-top: none;
  padding-top: 0;
}

/* A confirmation that cannot be read in full is not a confirmation, so the modal
   scrolls inside the viewport rather than overflowing it. */
.modal-scroll {
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}

/* ── NDA gate: DocuSign-style signing chrome ───────────────────────────────
   Its own full-page chrome rather than the app shell or the auth card: the
   investor is not inside the room yet, and the design deliberately borrows the
   visual language of a signing service so the handoff to DocuSign does not feel
   like leaving the site. Every value is from the prototype's `NDA gate` screen. */
.nda-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--gray-100);
}
.nda-bar {
  background: var(--white);
  border-bottom: 1px solid var(--gray-200);
  padding: 14px 28px;
  display: flex;
  align-items: center;
  gap: 18px;
}
.nda-bar-divider {
  width: 1px;
  height: 30px;
  background: var(--gray-200);
  flex: none;
}
.nda-bar-id {
  flex: 1;
  /* Lets the mono line below ellipsise instead of forcing the bar wider. */
  min-width: 0;
}
.nda-bar-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--navy);
}
/* One line, as the design draws it. A long fund name is truncated rather than
   allowed to wrap — squeezed between the logo and the badge it would otherwise
   break at every word and turn the bar into a column. */
.nda-bar-meta {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  color: var(--gray-600);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nda-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-btn-sm);
  padding: 7px 12px;
  flex: none;
}
.nda-badge-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--charcoal);
  white-space: nowrap;
}
.nda-steps {
  background: var(--navy);
  padding: 10px 28px;
  display: flex;
  gap: 26px;
  align-items: center;
  flex-wrap: wrap;
}
.nda-step {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  color: var(--on-navy-faint);
}
.nda-step-active {
  color: var(--on-navy-strong);
}
.nda-steps-note {
  margin-left: auto;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.75);
}
.nda-scroll {
  flex: 1;
  overflow: auto;
  padding: 36px 24px;
}
.nda-doc {
  width: var(--nda-page-width);
  max-width: 100%;
  margin: 0 auto;
  background: var(--white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 56px 64px;
  box-sizing: border-box;
}
.nda-doc-title {
  font-size: 21px;
  font-weight: 600;
  color: var(--navy);
  margin: 0 0 4px;
  letter-spacing: 0.02em;
}
.nda-doc-subtitle {
  font-size: 12.5px;
  color: var(--gray-600);
  margin: 0 0 26px;
}
.nda-clauses {
  font-size: 13px;
  line-height: 1.7;
  color: var(--charcoal);
}
.nda-clauses p {
  margin: 0 0 14px;
}
.nda-clause-number {
  color: var(--navy);
}
/* The signature panel. Empty on purpose until DocuSign returns an adopted
   signature — the prototype shows it pre-filled because it mocks the state
   after adoption, and the cursive face it used came from Google Fonts, which
   §3 of the build plan removed rather than leak an LP's page views. */
.nda-sign {
  border: 2px solid var(--navy);
  border-radius: var(--radius-md);
  padding: 20px 24px;
  display: flex;
  align-items: center;
  gap: 20px;
  background: var(--gray-100);
  margin-top: 26px;
}
.nda-sign-tag {
  background: var(--navy);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  flex: none;
}
.nda-sign-body {
  flex: 1;
  min-width: 0;
}
.nda-sign-space {
  height: 34px;
}
.nda-sign-rule {
  border-top: 1px solid var(--charcoal);
  margin-top: 6px;
  padding-top: 6px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.nda-sign-name {
  font-size: 11.5px;
  color: var(--gray-600);
}
.nda-sign-date {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--gray-600);
  white-space: nowrap;
}
.nda-foot {
  background: var(--white);
  border-top: 1px solid var(--gray-200);
  padding: 16px 28px;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  position: sticky;
  bottom: 0;
}
.nda-consent {
  display: flex;
  gap: 9px;
  align-items: center;
  cursor: pointer;
  font-size: 13px;
  color: var(--charcoal);
}
.nda-consent input {
  accent-color: var(--navy);
  width: 15px;
  height: 15px;
  flex: none;
}
.nda-foot-actions {
  margin-left: auto;
  display: flex;
  gap: 12px;
  align-items: center;
}
/* ══ The responsive pass (§17, #24) ═══════════════════════════════════════════
   One breakpoint, at 760px, extending the block Sprint 4 opened for the NDA chrome
   rather than adding a second one to keep in agreement with it.

   Three things this pass deliberately does NOT do.

   **It does not change a painted dimension.** §17 asks for 44px touch targets and the
   design draws a 40×22 toggle, a ~31px `.btn-sm` and a 15px checkbox. Those are not in
   conflict once paint and hit area are separated: every control below keeps its drawn
   size to the pixel and grows a transparent `::before` to 44×44. `tokens.css` says not
   to round these numbers and this does not.

   **It does not hide navigation behind a disclosure.** A `<details>` menu was built and
   measured first, and rejected on evidence: Chrome 131+ wraps details content in a
   `::details-content` box, which becomes the flex item and breaks the sidebar's
   bottom-anchored user block (`margin-top:auto` stops reaching the sidebar's height),
   and the closed state could not be confirmed to hide its panel across engines. The
   navigation instead wraps into rows and stays visible — no script, which this app's
   strict `script-src` requires anyway, and nothing behind a tap.

   **It does not restyle the viewer's controls.** The download link renders exactly when
   `canDownload` permits it and nowhere else; the phone gets the same chrome, wrapped. */
@media (max-width: 760px) {
  /* ── Shell: the sidebar becomes a navy band above the content ─────────── */
  .shell {
    flex-direction: column;
  }
  .sidebar {
    width: 100%;
    flex: none;
    padding: 16px 0 12px;
  }
  .sidebar-label {
    margin-bottom: 12px;
  }
  /* Horizontal and wrapping: five investor items (eight admin ones) all stay on
     screen at 390px, where one scrolling row would put the last of them out of
     sight behind no affordance. */
  .nav {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 5px 6px;
    padding: 0 18px;
  }
  .nav-item {
    min-height: 44px;
    padding: 11px 13px;
  }
  .main {
    padding: 20px 18px 40px;
    max-width: 100%;
  }

  /* ── Fund portal — the mockup at `.dc.html:739-765` ───────────────────── */
  .portal-page {
    padding: 28px 18px 40px;
  }
  .portal-head {
    margin-bottom: 20px;
    flex-wrap: wrap;
    gap: 12px;
  }
  /* The component writes its width inline, so the breakpoint cannot reach it any
     other way. Same reason `@media print` below carries one. */
  .portal-logo {
    width: 104px !important;
  }
  .h1-portal {
    font-size: 21px;
  }
  .portal-lede {
    font-size: 13px;
    margin-bottom: 20px;
  }
  .eyebrow-portal {
    font-size: 9px;
    letter-spacing: 0.16em;
  }
  .portal-group {
    margin-bottom: 20px;
  }
  /* The mockup replaces the chip and the action with a chevron. Both are kept, and
     that is a deliberate deviation: the chip is the only place a room says
     `NDA REQUIRED` before it is opened, and a chevron gives an LP no way to tell a
     room they can enter from one that will stop them at a gate. The card wraps to
     two lines instead of dropping either. */
  .portal-card {
    padding: 15px 16px;
    gap: 12px;
    min-height: 44px;
    flex-wrap: wrap;
  }
  /* The action takes its own row rather than standing beside the name. Sharing the row
     leaves the name about 190px, which wraps "Sightline Direct Opportunities II, LP"
     onto four lines — checked in a 390px frame, not assumed. Full width also makes the
     action a target the mockup's chevron never was. */
  .portal-card > .flex-1 {
    flex: 1 1 100%;
  }
  .portal-card .btn {
    flex: 1 1 auto;
    text-align: center;
  }
  .portal-fund {
    font-size: 14.5px;
  }
  .portal-meta {
    font-size: 11.5px;
  }

  /* ── Documents: the tree is a list above the table, not a 270px stub ──── */
  .tree {
    width: 100%;
    flex: none;
  }

  /* ── Viewer: bar wraps, counter drops under the title (`.dc.html:789`) ── */
  .viewer-scrim {
    padding: 0;
  }
  .viewer-bar {
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 12px 14px;
  }
  .viewer-bar-top {
    border-radius: 0;
  }
  .viewer-name {
    flex: 1 1 100%;
    order: 1;
  }
  .viewer-meta {
    order: 2;
  }
  .viewer-chip,
  .viewer-download {
    order: 3;
  }
  .viewer-close {
    order: 0;
    margin-left: auto;
  }
  .viewer-versions {
    padding: 8px 14px;
  }

  /* ── Grids: 4-up and 2-up collapse ───────────────────────────────────── */
  .grid-kpis {
    grid-template-columns: repeat(2, 1fr);
  }
  .grid-2 {
    grid-template-columns: 1fr;
  }
  /* A grid, not a flex row — and its 1px gap over a gray background is what draws the
     hairlines between cells, so only the column count changes. At four columns the band
     was clipped by its own `overflow: hidden` rather than wrapping. */
  .kpi-band {
    grid-template-columns: repeat(2, 1fr);
  }
  .kpi-cell {
    padding: 16px;
  }
  /* The header action takes its own row. `.page-head` already wraps, but the title block
     carries `min-width: 260px`, so at 390px it shrank instead and the eyebrow was clipped
     mid-word by the button beside it. */
  .page-head-main {
    flex: 1 1 100%;
    min-width: 0;
  }

  /* ── Auth: seven OTP boxes have to fit 390px ──────────────────────────
     7×44 + 6×8 = 356px of boxes inside 88px of card padding needs 444px, against
     the ~342px a 390px phone leaves after the page's own 24px gutters. */
  .auth-card-body {
    padding: 28px 20px;
  }
  .auth-card-foot {
    padding: 16px 20px;
  }
  .otp-row {
    gap: 5px;
  }

  /* iOS Safari zooms the page when a focused field is under 16px, which strands the
     rest of the form off-screen. The design's 14px is kept everywhere it is read and
     raised only where it is typed into. */
  .input,
  .select,
  .textarea,
  .input-sm,
  .select-sm {
    font-size: 16px;
  }

  /* ── 44px hit areas, without moving a painted edge ────────────────────
     A transparent overlay centred on the control, so the drawn size is untouched and
     only the target grows. `position:relative` scopes it; each of these already sits
     in a flex row, and an absolutely positioned child changes no layout.

     Buttons and links only. `<input>` is a replaced element and does not render
     generated content, so a checkbox cannot be enlarged this way — its label is the
     real target and is sized directly below. */
  .toggle,
  .btn-icon,
  .btn-close,
  .btn-sm,
  .btn-danger-outline,
  .switch-fund,
  .viewer-close {
    position: relative;
  }
  .toggle::before,
  .btn-icon::before,
  .btn-close::before,
  .btn-sm::before,
  .btn-danger-outline::before,
  .switch-fund::before,
  .viewer-close::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    /* Never smaller than the control it fronts, so a wide button stays fully
       clickable rather than being narrowed to 44px. */
    min-width: 100%;
    min-height: 100%;
    transform: translate(-50%, -50%);
  }

  /* Clicking the label toggles the box, so the row is the tap target and the 15px
     box keeps its drawn size. */
  .check-row,
  .nda-consent {
    min-height: 44px;
  }
  /* Height rather than an overlay: a text field's height is not a drawn mark in the
     way the toggle pill is, and a field that is 40px tall and 44px tappable would
     swallow taps meant for the label above it. */
  .input-sm,
  .select-sm {
    min-height: 44px;
  }
  .file-input::file-selector-button {
    min-height: 44px;
  }
  /* Rows are already wide enough; only their height falls short. */
  .table-row-tight,
  .row-clickable,
  .tree-row {
    min-height: 44px;
  }

  .nda-bar,
  .nda-steps,
  .nda-foot {
    padding-left: 18px;
    padding-right: 18px;
  }
  /* The badge takes its own row rather than crushing the envelope reference. */
  .nda-bar {
    flex-wrap: wrap;
    gap: 12px;
  }
  .nda-bar-id {
    flex-basis: 100%;
    order: 3;
  }
  .nda-bar-divider {
    display: none;
  }
  .nda-doc {
    padding: 32px 24px;
  }
  .nda-steps-note {
    margin-left: 0;
    flex-basis: 100%;
  }
  .nda-foot-actions {
    margin-left: 0;
    width: 100%;
  }
  .nda-sign {
    flex-wrap: wrap;
    gap: 14px;
  }
}

/* ── Print: never allow a clean print of a watermarked page ────────────── */
@media print {
  body {
    display: none !important;
  }
}
