/* ===========================================================================
   app.css — DEV-OWNED application styling.

   Ownership boundary:
     style.css    designer-owned. Replaced wholesale on every design handover.
                  Never add developer rules to it — they disappear on the next
                  handover, silently.
     consent.css  dev-owned, cookie consent UI only.
     app.css      dev-owned, everything else the application needs that the
                  design system does not provide: form validation, the readiness
                  score display, the footer legal row.

   This file exists because rules for the items below previously lived in
   style.css and were lost when the incoming design layer replaced it. Symptoms
   were: validation messages rendering as plain black text, and the footer's
   consent controls rendering as grey browser-default buttons on a dark footer.

   Values here deliberately mirror the design system's own tokens. If the design
   system changes, change these with it.
   =========================================================================== */

/* ---- Form validation --------------------------------------------------- */
/* Per-field error text, populated by script.js from the server's error codes.
   Used on contact, readiness check and roundtable seat request. */
.field-error {
  display: block;
  font-size: 0.78rem;
  color: #a4393a;
  margin-top: 4px;
}
.field-error:empty {
  display: none;
}
.fs-form-grid [aria-invalid="true"],
.contact-form [aria-invalid="true"] {
  border-color: #a4393a;
}

/* ---- Custom select (assets/custom-select.js) --------------------------- */
/* Enhances .fs-form-grid/.contact-form <select> into an ARIA combobox so
   hover, keyboard-highlight, selected and disabled states can be styled.
   Values mirror the design system's own select styling in style.css. */
.cselect { position: relative; }
.cselect select {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  opacity: 0;
  pointer-events: none;
}
.cselect-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  font: inherit;
  font-size: 0.96rem;
  text-align: left;
  background: #fff;
  color: var(--ink, #000);
  border: 1.5px solid var(--line, #C6CDEE);
  border-radius: var(--radius, 10px);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.cselect-btn .cselect-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cselect-btn .cselect-val.cselect-val-empty { color: var(--muted, #767B93); }
.cselect-btn .cselect-chev {
  flex: none; width: 12px; height: 8px;
  color: var(--ink-2, #4A4F66);
  transition: transform 0.18s ease;
}
.cselect-btn:hover { border-color: var(--gf-royal, #1C39BB); }
.cselect-btn:focus-visible {
  outline: 0;
  border-color: var(--gf-royal, #1C39BB);
  box-shadow: 0 0 0 4px rgba(28, 57, 187, 0.16);
}
.cselect-btn:disabled { cursor: not-allowed; opacity: 0.55; }
.cselect.open .cselect-btn {
  border-color: var(--gf-royal, #1C39BB);
  box-shadow: 0 0 0 4px rgba(28, 57, 187, 0.16);
}
.cselect.open .cselect-btn .cselect-chev { transform: rotate(180deg); }

.cselect-panel {
  position: absolute;
  left: 0; right: 0; top: calc(100% + 6px);
  z-index: 20;
  margin: 0; padding: 6px;
  list-style: none;
  background: #fff;
  border: 1px solid var(--line, #C6CDEE);
  border-radius: 12px;
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(11, 23, 75, .12), 0 4px 8px rgba(11, 23, 75, .06));
  max-height: 264px;
  overflow-y: auto;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transform-origin: top center;
  pointer-events: none;
  transition: opacity 0.14s ease, transform 0.14s ease;
}
.cselect.open .cselect-panel { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  .cselect-panel, .cselect-btn .cselect-chev { transition: none; }
}

.cselect-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 0.94rem;
  color: var(--ink, #000);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cselect-opt .cselect-tick { flex: none; width: 14px; height: 14px; color: var(--gf-royal, #1C39BB); opacity: 0; }
.cselect-opt[aria-selected="true"] { font-weight: 600; }
.cselect-opt[aria-selected="true"] .cselect-tick { opacity: 1; }
.cselect-opt.is-active { background: var(--soft, #F4F5FC); }
.cselect-opt[aria-disabled="true"] { color: var(--muted, #767B93); cursor: not-allowed; }
.cselect-opt[aria-disabled="true"].is-active { background: transparent; }

/* ---- Readiness check result -------------------------------------------- */
.fs-score-num {
  font-weight: 700;
  color: var(--ink, #000);
}
.fs-score-max,
.fs-score-band {
  color: var(--muted, #767B93);
}

/* ---- Footer legal row -------------------------------------------------- */
/* The row mixes <a> (Privacy, Terms, Cookies, AML Obligations) with <button>
   (Consent preferences, Do Not Sell or Share). They must be indistinguishable.
   Mirrors the design system's `.site-footer a`. */
.site-footer .legal-link {
  font: inherit;
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.7);
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  text-align: inherit;
  cursor: pointer;
  transition: color 0.15s;
}
.site-footer .legal-link:hover,
.site-footer .legal-link:focus-visible {
  color: #fff;
}

/* ---- Design-system reference page -------------------------------------- */
.card-dark {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.12);
}
.card-dark h3,
.card-dark h4 { color: #fff; }
.card-dark p  { color: #cfd8e8; }

/* ---- Legal documents in print ------------------------------------------ */
/* On screen these clauses read "…which is accessible here", with "here" a
   link. On paper a link is invisible, and an incorporation-by-reference
   clause that names no location is worse than useless. Expanding the href
   restores the reference — and because the href is built from env.baseUrl,
   what prints is the URL for the environment the page was served from. */
@media print {
  .legal-doc a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }
}

/* ---- Classes emitted by bin/docx_to_html.py ---------------------------- */
/* The converter emits these on every generated legal page. If you remove a
   rule here, remove the emission too — tests/legal-integrity.spec.js fails the
   build when the converter emits a class nothing styles. That check exists
   because these were silently orphaned once already. */
.gf-doc-table-wrap {
  overflow-x: auto;
}
.gf-doc-rule {
  border: 0;
  border-top: 1px solid var(--line, #d9dee8);
  margin: 2rem 0;
}

/* ---- Visy landing page — PROVISIONAL, 2026-09-24 -------------------------
   JP's 24 September rewrite introduced these classes and shipped no CSS for
   them. Without rules the page still renders — unstyled, which is the silent
   ADR-0015 failure — so these exist to make it presentable, not to design it.

   THEY ARE MELISSA'S TO OWN. When she supplies rules in style.css, delete this
   block rather than leaving two definitions to disagree. Values mirror the
   design system's tokens deliberately.

   Two of JP's classes are NOT here: ps-subnav and ps-subnav-links were renames
   of .subnav / .links, which the design system already ships and script.js
   already binds, so the markup was remapped instead of restyled.
   ------------------------------------------------------------------------ */

/* Page scope hook. Carries no rules of its own — it exists so anything added
   for this page can be scoped rather than leaking site-wide. */
.sn-page { }

/* Removes .lede's 60ch measure where a lede introduces a full-width block. */
.stretch { max-width: none; }

/* Icon cards. .card supplies the frame; these only place the icon. */
.sn-card { display: flex; flex-direction: column; }
.sn-icon {
  width: 40px; height: 40px;
  margin-bottom: 14px;
  /* SVG icons ship at their own colour; nothing to tint here. */
}

/* App screenshot gallery. auto-fit rather than a fixed 3-up: five pages on
   this site already overflow below 520px and this must not become a sixth. */
.app-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 26px;
}
.app-frame {
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
/* The three screenshots are 457-467px wide, so they differ slightly. Forcing
   width:100% normalises them to the column rather than to their own pixels. */
.app-frame > img {
  display: block;
  width: 100%;
  height: auto;
  border-bottom: 1px solid var(--line);
}
.app-frame-body { padding: 18px 20px 22px; }
.app-frame-body h4 { margin: 0 0 6px; }
.app-frame-body p { margin: 0; color: var(--ink-2); font-size: 0.95rem; }

/* ---- Legal document sub-lists, 2026-09-29 ------------------------------
   Legal's numbered sub-items carry their nesting ONLY as a Word left indent
   — the (i)–(v) items under PDS 4.1.1 sit at 2160 twips. The converter used
   to drop it, so every level rendered flush with the top-level (a)–(h) and
   the hierarchy was invisible in a published contract, where which item sits
   under which is the whole point.

   An em, not the 1.5in Word specifies: these pages are read on phones, five
   of our pages already overflow at 390px, and an absolute inch does not
   survive a narrow screen. The indent only has to read as "one level in".

   THE SELECTOR IS LONGER THAN IT LOOKS IT NEEDS TO BE, on purpose.
   `.legal-doc .gf-doc-indent` is (0,2,0) and LOSES to the designer's
   `.legal-doc > .container-narrow > p` at (0,2,1), which sets the `margin`
   shorthand and so resets margin-left to 0. The rule applied, matched, and did
   nothing — measured as computed margin-left: 0px while looking correct in the
   file. Matching the real structure takes it to (0,3,1). Same trap as
   docs/knowledge/verifying-a-css-rule-actually-applies.md: check the computed
   value, not that the rule is present.
   ---------------------------------------------------------------------- */
.legal-doc > .container-narrow > p.gf-doc-indent { margin-left: 2.2em; }

@media (max-width: 560px) {
  /* Halved rather than removed: the nesting still has to be legible, but a
     full indent plus a hanging "(iii)" eats a phone's measure. */
  .legal-doc > .container-narrow > p.gf-doc-indent { margin-left: 1.1em; }
}

