/* ==========================================================================
   Prismatic Data Solutions: components the two prototype pages did not need.
   Colours resolve through the same palette tokens as base.css, so every rule
   here works in all ten palettes. Loaded last.
   ========================================================================== */

/* Three feature groups: three columns, or one. Never two with an orphan. */
.feature-groups--3 { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1000px) {
  .feature-groups--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* A single feature group runs the full measure, so its list splits in two. */
.feature-groups--1 { grid-template-columns: minmax(0, 1fr); }
.check-list--wide { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 760px) {
  .check-list--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-4); }
}

/* Body copy inside a panel card reads as body copy. */
.panel-card > p { color: var(--muted); }
.panel-card > h3 + p { margin-top: var(--s-1); }
.panel-card > p + p { margin-top: var(--s-2); }
.panel-card > p + .check-list { margin-top: var(--s-3); }

/* Panels sitting in a grid list stretch to the row height. */
.xlinks > li > .panel-card,
.xlinks > li > .xlink { height: 100%; }

/* Two cross-link or module cards per row (ten modules on the solutions page:
   2 x 5, no orphan). Below the base breakpoint the base rule takes over. */
@media (min-width: 1081px) {
  .xlinks--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Two footer lockups, one per footer ground. The family ships a separate HTML
   file per palette and simply swaps the cutout; one generated page serves ten
   palettes, so the swap is a rule. Default: the white cutout on a dark footer.
   themes.css turns it round for any palette with a light footer. */
.footer__brand .wordmark-lockup--dark { display: none; }

/* The mega menu foot carries two links now (all solutions, platform). */
.mega__foot a + a { margin-top: var(--s-2); }

/* The contact page: form on the left of its own measure, notes beside it. */
@media (min-width: 901px) {
  .split--form { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
}
.form-grid { display: grid; gap: var(--s-3); margin-top: var(--s-3); }
.field { display: grid; gap: 6px; }
.field label {
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.field input,
.field textarea {
  font: inherit;
  color: var(--text);
  background: rgba(var(--text-rgb), .05);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  padding: 12px 14px;
  width: 100%;
}
.field textarea { resize: none; overflow: hidden; min-height: 9rem; }   /* grows with the message (script); no handle, no scrollbar */
.field input:hover,
.field textarea:hover { border-color: var(--int); }
.field input:focus-visible,
.field textarea:focus-visible { outline: 2px solid var(--int); outline-offset: 1px; }
.field input::placeholder,
.field textarea::placeholder { color: var(--muted); opacity: .8; }
.form-note { margin-top: var(--s-3); font-size: 0.9375rem; color: var(--muted); }
.captcha-holder { margin-block: var(--s-3); min-height: 1px; }
.form-status { margin-top: var(--s-2); font-size: 0.9375rem; color: var(--text); min-height: 1.5em; }
.contact-form .btn { margin-top: var(--s-3); }

/* Notes beside the form, and the culture blocks on the about page, are the
   `.reasons` stack from base.css; only their inline links need a rule. */
.reasons a { color: var(--int); font-weight: 500; text-decoration: none; }
.reasons a:hover { color: var(--int-hi); text-decoration: underline; }

/* Role line under a name on the about page. */
.role {
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--int);
  margin-top: 6px;
}

/* Article pages (trust and security, accessibility): the lede runs the
   measure under the section head, above the panels. */
.article-lede { max-width: 68ch; margin-bottom: var(--s-5); }
.article-lede p { color: var(--muted); font-size: var(--t-1); line-height: 1.5; }

/* ==========================================================================
   Contact form, AWS target only (build_v3.py --target aws). The form posts to
   /api/contact and carries five more fields than the Apache one, so the short
   fields pair up once there is room and the module list, the message and the
   status line run the full measure.
   ========================================================================== */

@media (min-width: 700px) {
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.field--wide { grid-column: 1 / -1; }

/* `display: grid` on .field outranks the user agent's [hidden] rule, so the
   fields the purpose question hides need this to actually disappear (caught
   2026-09-10). Same for the modules fieldset, for symmetry. */
.field[hidden],
.check-set[hidden] { display: none; }

/* The select matches the text inputs. Options carry an opaque background of
   their own: the closed control sits on the well, but the dropdown the
   browser opens is its own surface and would otherwise take the page's text
   colour on a system-white list. */
.field select {
  font: inherit;
  color: var(--text);
  background: rgba(var(--text-rgb), .05);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  padding: 12px 14px;
  width: 100%;
}
.field select:hover { border-color: var(--int); }
.field select:focus-visible { outline: 2px solid var(--int); outline-offset: 1px; }
.field select option { color: var(--text); background: var(--panel); }

/* Modules of interest: a checkbox group, two columns from 600px. */
.check-set { border: 0; margin: 0; padding: 0; min-width: 0; }
.check-set > legend {
  padding: 0;
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.check-group {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px var(--s-3);
  margin-top: 12px;
}
@media (min-width: 600px) {
  .check-group { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.check-opt { display: flex; align-items: flex-start; gap: 10px; }
.check-opt input {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin: .2rem 0 0;
  accent-color: var(--int);
}
.check-opt input:focus-visible { outline: 2px solid var(--int); outline-offset: 2px; }
.check-opt label {
  font: inherit;
  letter-spacing: normal;
  text-transform: none;
  color: var(--text);
  cursor: pointer;
}
/* "Select all modules": inserted by script above the list, set off from it by
   a hairline so it reads as a control over the list, not an eleventh module. */
.check-opt--all {
  margin-top: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.check-opt--all label { color: var(--muted); }
.check-opt--all input:checked + label,
.check-opt--all input:indeterminate + label { color: var(--text); }

/* Inline validation message under a required field, and the field's own
   invalid state. The incident band hue is a decorative tick colour and fails
   AA as text (3.9:1 on the default ground), so the message takes that hue
   mixed half-and-half into the palette's text colour: a lighter red on the
   dark palettes (4.8:1 on the well), a darker one on daylight and parchment
   (11:1 on white). Colour is never the only signal — the message says what to
   do, and focus moves to the field. */
.field-error {
  /* The .field grid already spaces its rows 6px apart; no margin needed. */
  font-size: 0.9375rem;
  color: color-mix(in srgb, var(--h-incident) 50%, var(--text));
}
.field.is-invalid input,
.field.is-invalid textarea {
  border-color: color-mix(in srgb, var(--h-incident) 50%, var(--text));
}

/* Honeypot: off-screen rather than display:none, which some bots skip. */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
