/* ============================================================================
   INSTITUT CIVRA — INSTITUTIONAL PUBLIC SITE (P12-T0A / P12-T0B)
   ----------------------------------------------------------------------------
   The Tribune layer of the public institutional pages. Deliberately separate
   from app.css (back office) and from respondent-tribune.css (tunnel), and
   deliberately NOT loaded together with either of them: this sheet owns its
   own primitives instead of inheriting a cascade it never validated.

   Containment rule, asserted by PublicSiteStyleGuardTest: EVERY top-level
   selector starts with .ps-page — the same mechanical guarantee the
   respondent sheet gets from .r-page. This lot cannot reach a back-office or
   respondent surface even by accident.

   Purity rules, also asserted: only --civ-* semantic tokens (never the
   --_civ-* primitives, never a V1 colour alias of the deprecated tokens.css
   layer, which is why the shell does not link it), no raw hex, no url(), no
   @import, no !important, no theme switching. Light only (decision D01):
   the ink surfaces here are surfaces, not a dark theme.

   Mobile-first: the base rules are the 320–390 layout; the two media
   queries widen it at --civ-bp-md (768px) and --civ-bp-lg (1024px). The
   breakpoints are written as literals because @media cannot read a custom
   property; their values are the token values. The navigation switches from
   the native disclosure to the horizontal bar at LG, not MD.

   Type floor: every piece of useful text on this site is at least 16px, which
   is stricter than the Tribune scale — the 14px action role and the 12px
   kicker role are recomposed locally at the body size and the sub-16px roles
   are banned from this sheet.

   No script is loaded on this site, so no rule here may depend on a class a
   controller would add: the menu, the FAQ and the table alternatives are
   native <details> elements and are styled through [open].

   MOTION (P12-T0B) — every duration, delay and animation NAME is read from a
   local custom property declared on .ps-page and re-pointed, at the same
   selector, inside the single prefers-reduced-motion block at the bottom.
   That indirection is the point: a rule like `.ps-page .ps-cards > *` is more
   specific than `.ps-page *`, so a wildcard override in the media query would
   LOSE the cascade — re-pointing the inherited custom properties cannot lose,
   because the winning declaration is the same one either way. Under reduced
   motion the animation names become `none` and every duration becomes 0ms.
   No animation carries information, none loops, and every animated element is
   fully readable with no animation at all: the keyframes only ever move an
   element FROM a transparent/offset state TO the element's own normal styles.
   ========================================================================== */

/* ---------------------------------------------------------------- page ---- */

.ps-page {
  /* Motion contract of this sheet — see the header note and the single
     prefers-reduced-motion block at the bottom, which re-points all five. */
  --ps-enter-name: ps-rise;
  --ps-grow-name: ps-grow;
  --ps-enter: var(--civ-motion-slow);
  --ps-stagger: 60ms;
  --ps-fast: var(--civ-motion-fast);
  --ps-base: var(--civ-motion-base);

  /* Type floor of this site: every piece of useful text is at least 16px.
     The Tribune --civ-font-role-action (14px) and --civ-font-role-kicker
     (12px) sit below it, so the two faces are recomposed here from the same
     weights and families at the body size. PublicSiteStyleGuardTest bans the
     sub-16px roles from this sheet outright. */
  --ps-font-action: var(--civ-weight-bold) var(--civ-text-body) / var(--civ-leading-heading) var(--civ-font-heading);
  --ps-font-caps: var(--civ-weight-black) var(--civ-text-body) / var(--civ-leading-heading) var(--civ-font-heading);

  margin: 0;
  background-color: var(--civ-color-surface-page);
  color: var(--civ-color-text-default);
  font: var(--civ-font-role-body);
  -webkit-text-size-adjust: 100%;
}

.ps-page *,
.ps-page *::before,
.ps-page *::after {
  box-sizing: border-box;
}

.ps-page p,
.ps-page h1,
.ps-page h2,
.ps-page h3,
.ps-page ul,
.ps-page ol,
.ps-page dl,
.ps-page dd,
.ps-page table {
  margin: 0;
}

.ps-page ul,
.ps-page ol {
  padding: 0;
  list-style: none;
}

.ps-page a {
  color: var(--civ-color-text-link);
}

/* One focus treatment for the whole site: the Tribune ring, 3px with a 2px
   offset, never removed and never replaced by a colour change alone. */
.ps-page a:focus-visible,
.ps-page summary:focus-visible,
.ps-page [tabindex]:focus-visible {
  outline: var(--civ-focus-width) solid var(--civ-color-focus-ring);
  outline-offset: var(--civ-focus-offset);
  border-radius: var(--civ-radius-xs);
}

/* On the ink surfaces the teal ring would sink into the background, so the
   ring token is re-pointed rather than the outline rule duplicated. */
.ps-page .ps-section--ink,
.ps-page .ps-footer,
.ps-page .ps-error {
  --civ-color-focus-ring: var(--civ-color-focus-ring-dark);
}

/* ----------------------------------------------------------- skip link ---- */

.ps-page .ps-skip {
  position: absolute;
  left: -100vw;
  top: 0;
  z-index: var(--civ-z-modal);
  display: inline-flex;
  align-items: center;
  min-height: var(--civ-target-min);
  padding: var(--civ-space-3) var(--civ-space-4);
  background-color: var(--civ-color-action-primary-bg);
  color: var(--civ-color-action-primary-text);
  font: var(--ps-font-action);
  text-decoration: none;
}

/* No transition on the skip link: it must appear the instant it takes focus,
   and it is deliberately excluded from every entry animation. */
.ps-page .ps-skip:focus {
  left: var(--civ-space-2);
  top: var(--civ-space-2);
}

/* -------------------------------------------------------------- banner ---- */

/* Permanent and non-dismissible: no control, no [hidden], nothing a script
   could toggle. It is the synthetic marker of the whole site, so it never
   animates and never waits for anything. */
.ps-page .ps-banner {
  padding-block: var(--civ-space-3);
  padding-inline: max(var(--civ-space-4), calc((100% - 1240px) / 2));
  background-color: var(--civ-color-marker-synthetic-bg);
  border-bottom: 1px solid var(--civ-color-marker-synthetic-border);
  color: var(--civ-color-marker-synthetic-text);
}

.ps-page .ps-banner__text,
.ps-page .ps-banner__scope {
  max-width: 96ch;
  font: var(--civ-font-role-body);
  color: var(--civ-color-marker-synthetic-text);
}

.ps-page .ps-banner__scope {
  margin-top: var(--civ-space-1);
}

/* -------------------------------------------------------------- header ---- */

.ps-page .ps-header {
  background-color: var(--civ-color-surface-page);
  border-bottom: 1px solid var(--civ-color-border-default);
}

.ps-page .ps-header__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--civ-space-3);
  max-width: 1240px;
  margin: 0 auto;
  padding: var(--civ-space-4);
}

.ps-page .ps-brand {
  display: block;
  color: var(--civ-color-text-default);
  text-decoration: none;
}

.ps-page .ps-brand__name {
  display: block;
  font: var(--civ-weight-black) var(--civ-text-h3) / var(--civ-leading-tight) var(--civ-font-display);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

.ps-page .ps-brand__baseline {
  display: block;
  margin-top: var(--civ-space-1);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
}

/* Desktop navigation: absent below the LG breakpoint — display:none also
   removes it from the accessibility tree, so it never doubles the mobile
   disclosure below. It switches at 1024 rather than 768 because five entries
   at this site's 16px floor do not fit beside the wordmark at 768. */
.ps-page .ps-nav {
  display: none;
}

.ps-page .ps-navlist {
  display: flex;
  flex-direction: column;
  gap: var(--civ-space-1);
}

.ps-page .ps-navlist__link {
  display: flex;
  align-items: center;
  min-height: var(--civ-target-min);
  padding: var(--civ-space-2) var(--civ-space-3);
  border-bottom: 2px solid transparent;
  color: var(--civ-color-text-default);
  font: var(--ps-font-action);
  text-decoration: none;
  transition: border-bottom-color var(--ps-fast) var(--civ-motion-ease), color var(--ps-fast) var(--civ-motion-ease);
}

.ps-page .ps-navlist__link:hover {
  border-bottom-color: var(--civ-color-border-strong);
}

/* Current page: a border AND a weight change, never colour alone. */
.ps-page .ps-navlist__link[aria-current="page"] {
  border-bottom-color: var(--civ-color-border-strong);
  font-weight: var(--civ-weight-black);
}

/* --------------------------------------------------------- mobile menu ---- */

.ps-page .ps-menu {
  border-top: 1px solid var(--civ-color-border-subtle);
}

.ps-page .ps-menu__toggle {
  display: flex;
  align-items: center;
  gap: var(--civ-space-2);
  min-height: var(--civ-target-min);
  padding: var(--civ-space-3) var(--civ-space-4);
  color: var(--civ-color-text-default);
  font: var(--ps-font-action);
  cursor: pointer;
  list-style: none;
}

/* The native marker is replaced by the SVG icon carried in the summary. */
.ps-page .ps-menu__toggle::-webkit-details-marker {
  display: none;
}

.ps-page .ps-menu__toggle::marker {
  content: "";
}

.ps-page .ps-menu__panel {
  padding: 0 var(--civ-space-4) var(--civ-space-4);
}

/* ------------------------------------------------------------ chevrons ---- */

/* The disclosure marker. Decorative (aria-hidden in the partial): the open
   state is already exposed by the native <details>, so the rotation carries no
   information and may be animated. Under reduced motion it simply snaps. */
.ps-page .ps-chevron {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
  color: var(--civ-color-text-link);
  transition: transform var(--ps-fast) var(--civ-motion-ease), color var(--ps-fast) var(--civ-motion-ease);
}

.ps-page details[open] > summary .ps-chevron {
  transform: rotate(90deg);
}

/* ---------------------------------------------------------------- main ---- */

.ps-page .ps-main {
  display: block;
}

.ps-page .ps-main:focus-visible {
  outline: var(--civ-focus-width) solid var(--civ-color-focus-ring);
  outline-offset: var(--civ-focus-offset);
}

/* Full-bleed bands holding a 1240px measure, WITHOUT a wrapper element and
   without centring each child on its own.
   `margin: 0 auto` on every child was the first attempt and it was wrong: a
   child with a narrower measure of its own (a lead at 66ch, a card at 640px)
   centres itself inside the band instead of aligning with the heading above
   it, which pushed the hero lead to the right of a large hole. The fluid
   inline padding keeps the band full width, bounds the measure, and leaves
   every child aligned on the same left edge. */
.ps-page .ps-hero,
.ps-page .ps-page-head,
.ps-page .ps-section,
.ps-page .ps-error,
.ps-page .ps-warning {
  padding-inline: max(var(--civ-space-4), calc((100% - 1240px) / 2));
}

.ps-page .ps-hero,
.ps-page .ps-page-head,
.ps-page .ps-section,
.ps-page .ps-error {
  padding-block: var(--civ-space-8);
}

.ps-page .ps-section--card {
  background-color: var(--civ-color-surface-card);
  border-top: 1px solid var(--civ-color-border-subtle);
  border-bottom: 1px solid var(--civ-color-border-subtle);
}

/* Ink surface: an editorial surface of the direction, not a dark theme. */
.ps-page .ps-section--ink {
  background-color: var(--civ-color-surface-invert);
  color: var(--civ-color-text-invert);
}

/* -------------------------------------------------------- typography ----- */

.ps-page .ps-h1,
.ps-page .ps-hero__title {
  font: var(--civ-weight-black) var(--civ-text-display) / var(--civ-leading-tight) var(--civ-font-display);
  letter-spacing: var(--civ-tracking-caps);
}

.ps-page .ps-hero__accent {
  color: var(--civ-color-text-link);
}

.ps-page .ps-h2 {
  font: var(--civ-weight-black) var(--civ-text-h1) / var(--civ-leading-snug) var(--civ-font-heading);
}

.ps-page .ps-h2--ink {
  color: var(--civ-color-text-invert);
}

.ps-page .ps-h3 {
  font: var(--civ-font-role-h3);
}

/* A sub-heading inside a section that already has its H2. */
.ps-page .ps-subhead {
  margin-top: var(--civ-space-10);
  padding-top: var(--civ-space-6);
  border-top: 1px solid var(--civ-color-border-default);
}

.ps-page .ps-kicker {
  font: var(--ps-font-caps);
  color: var(--civ-color-text-link);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-kicker);
}

.ps-page .ps-kicker--ink {
  color: var(--civ-color-state-activity-on-dark);
}

.ps-page .ps-lead {
  max-width: 66ch;
  margin-top: var(--civ-space-4);
  font: var(--civ-font-role-body-lg);
  color: var(--civ-color-text-secondary);
}

.ps-page .ps-lead--ink {
  color: var(--civ-color-text-on-dark);
}

.ps-page .ps-text {
  max-width: 70ch;
  margin-top: var(--civ-space-2);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
}

/* Metadata face. It stays at the body size on purpose: the accessibility
   checklist reserves the muted ink for metadata of 16px and above. */
.ps-page .ps-note {
  max-width: 70ch;
  margin-top: var(--civ-space-4);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-muted);
}

/* The editorial rule of the direction: a line, never a content carrier. */
.ps-page .ps-rule {
  width: var(--civ-space-16);
  height: 2px;
  margin-top: var(--civ-space-6);
  background-color: var(--civ-color-border-strong);
}

.ps-page .ps-prose > .ps-h3 {
  margin-top: var(--civ-space-6);
}

/* An inline textual link. Underlined by default — never colour alone. A card
   call to action is a control, so it carries the WCAG 2.2 target minimum
   rather than the height of its own line box. */
.ps-page .ps-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--civ-target-min);
  font: var(--ps-font-action);
  color: var(--civ-color-text-link);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: text-decoration-color var(--ps-fast) var(--civ-motion-ease), color var(--ps-fast) var(--civ-motion-ease);
}

.ps-page .ps-link:hover {
  color: var(--civ-color-action-primary-hover);
}

/* --------------------------------------------------------------- lists ---- */

/* The global list-style reset removes the markers, so an editorial list gets
   its own: a short rule, i.e. a SHAPE, which survives high-contrast modes and
   never depends on colour to be seen. */
.ps-page .ps-list {
  margin-top: var(--civ-space-4);
  max-width: 78ch;
}

.ps-page .ps-list > li {
  position: relative;
  padding-left: var(--civ-space-6);
  margin-top: var(--civ-space-3);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
}

.ps-page .ps-list > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: var(--civ-space-4);
  height: 2px;
  background-color: var(--civ-color-border-strong);
}

.ps-page .ps-section--ink .ps-list > li {
  color: var(--civ-color-text-on-dark);
}

.ps-page .ps-section--ink .ps-list > li::before {
  background-color: var(--civ-color-border-invert);
}

/* ------------------------------------------------------------- actions ---- */

.ps-page .ps-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--civ-space-3);
  margin-top: var(--civ-space-6);
}

.ps-page .ps-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--civ-target-comfort);
  padding: 0 var(--civ-space-6);
  border: 2px solid transparent;
  border-radius: var(--civ-radius-sm);
  font: var(--ps-font-action);
  text-align: center;
  text-decoration: none;
  transition: background-color var(--ps-fast) var(--civ-motion-ease), color var(--ps-fast) var(--civ-motion-ease), border-color var(--ps-fast) var(--civ-motion-ease);
}

.ps-page .ps-btn--primary {
  background-color: var(--civ-color-action-primary-bg);
  color: var(--civ-color-action-primary-text);
}

.ps-page .ps-btn--primary:hover {
  background-color: var(--civ-color-action-primary-hover);
}

.ps-page .ps-btn--secondary {
  background-color: var(--civ-color-action-secondary-bg);
  border-color: var(--civ-color-action-secondary-border);
  color: var(--civ-color-action-secondary-text);
}

.ps-page .ps-btn--secondary:hover {
  background-color: var(--civ-color-action-primary-bg);
  color: var(--civ-color-action-primary-text);
}

.ps-page .ps-btn--on-ink {
  background-color: var(--civ-color-action-on-invert-bg);
  color: var(--civ-color-action-on-invert-text);
}

/* Secondary action on the ink surface: the inverted ink carries the border, so
   the boundary of the control clears the 3:1 the checklist asks of a control
   edge — the 16%-opacity separator ink would not. */
.ps-page .ps-btn--on-ink-secondary {
  background-color: transparent;
  border-color: var(--civ-color-text-invert);
  color: var(--civ-color-text-invert);
}

.ps-page .ps-btn--on-ink-secondary:hover {
  background-color: var(--civ-color-action-on-invert-bg);
  border-color: var(--civ-color-action-on-invert-bg);
  color: var(--civ-color-action-on-invert-text);
}

/* --------------------------------------------------------------- cards ---- */

.ps-page .ps-card {
  margin-top: var(--civ-space-6);
  padding: var(--civ-space-6) var(--civ-space-4);
  background-color: var(--civ-color-surface-card);
  border: 1px solid var(--civ-color-border-default);
  border-radius: var(--civ-radius-lg);
  box-shadow: var(--civ-shadow-card);
  color: var(--civ-color-text-default);
}

.ps-page .ps-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--civ-space-2);
  margin-bottom: var(--civ-space-3);
}

.ps-page .ps-card__kicker {
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

/* Synthetic tag: the same marker tokens as the banner, doubled by its text.
   It is never the only place a figure is qualified. */
.ps-page .ps-tag {
  display: inline-block;
  padding: var(--civ-space-1) var(--civ-space-3);
  background-color: var(--civ-color-marker-synthetic-bg);
  border: 1px solid var(--civ-color-marker-synthetic-border);
  border-radius: var(--civ-radius-xs);
  font: var(--civ-font-role-body);
  color: var(--civ-color-marker-synthetic-text);
}

.ps-page .ps-tag--gated {
  background-color: var(--civ-color-state-warning-bg);
  border-color: var(--civ-color-state-warning-border);
  color: var(--civ-color-state-warning-text);
}

.ps-page .ps-question {
  max-width: 60ch;
  margin-top: var(--civ-space-3);
  font: var(--civ-weight-semibold) var(--civ-text-body-lg) / var(--civ-leading-heading) var(--civ-font-heading);
}

/* ------------------------------------------------------- study catalogue -- */

/* The card grid. `auto-fit` with a floor slightly under the 320px viewport
   keeps a single column at 320 without a media query, and the group is what
   the staggered entry animation applies to. */
.ps-page .ps-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--civ-space-4);
  margin-top: var(--civ-space-6);
}

.ps-page .ps-study {
  display: flex;
  flex-direction: column;
  gap: var(--civ-space-2);
  padding: var(--civ-space-5) var(--civ-space-4);
  background-color: var(--civ-color-surface-card);
  border: 1px solid var(--civ-color-border-default);
  border-left: 4px solid var(--civ-color-border-strong);
  border-radius: var(--civ-radius-md);
  box-shadow: var(--civ-shadow-card);
  transition: box-shadow var(--ps-base) var(--civ-motion-ease), border-left-color var(--ps-base) var(--civ-motion-ease);
}

.ps-page .ps-study:hover {
  box-shadow: var(--civ-shadow-raised);
  border-left-color: var(--civ-color-text-link);
}

.ps-page .ps-study__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--civ-space-2);
  justify-content: space-between;
}

.ps-page .ps-study__theme {
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

.ps-page .ps-study__meta {
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-muted);
}

.ps-page .ps-study__action {
  margin-top: auto;
  padding-top: var(--civ-space-2);
}

/* The status legend, including the one status this site never uses. */
.ps-page .ps-legend {
  margin-top: var(--civ-space-6);
}

.ps-page .ps-legend dt {
  margin-top: var(--civ-space-4);
}

.ps-page .ps-legend dd {
  margin-top: var(--civ-space-1);
  max-width: 78ch;
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
}

/* --------------------------------------------------- answer modes, columns - */

.ps-page .ps-modes,
.ps-page .ps-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--civ-space-4);
  margin-top: var(--civ-space-6);
}

/* The two answer modes are typographically IDENTICAL on purpose: the spoken
   answer is a way of answering, never the recommended one. */
.ps-page .ps-modes__item,
.ps-page .ps-columns__item {
  padding: var(--civ-space-5) var(--civ-space-4);
  background-color: var(--civ-color-surface-card);
  border: 1px solid var(--civ-color-border-default);
  border-top: 4px solid var(--civ-color-border-strong);
  border-radius: var(--civ-radius-md);
}

/* The "never used for" column: a distinct top edge AND its own title, never
   colour alone. */
.ps-page .ps-columns__item--refused {
  border-top-color: var(--civ-color-state-error-border);
}

.ps-page .ps-columns__item .ps-list {
  margin-top: var(--civ-space-2);
}

/* --------------------------------------------------------- professional --- */

.ps-page .ps-usecases {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--civ-space-3);
  margin-top: var(--civ-space-6);
}

.ps-page .ps-usecases__item {
  padding: var(--civ-space-4);
  background-color: var(--civ-color-surface-page);
  border: 1px solid var(--civ-color-border-default);
  border-radius: var(--civ-radius-md);
  font: var(--civ-font-role-body);
}

/* -------------------------------------------------------------- tables ---- */

/* Wide content scrolls inside its OWN container: the page body never scrolls
   horizontally, at 320px or at 200% zoom. */
.ps-page .ps-scroll {
  overflow-x: auto;
}

.ps-page .ps-sheet,
.ps-page .ps-table {
  width: 100%;
  margin-top: var(--civ-space-4);
  border-collapse: collapse;
  font: var(--civ-font-role-body);
}

.ps-page .ps-sheet th,
.ps-page .ps-sheet td,
.ps-page .ps-table th,
.ps-page .ps-table td {
  padding: var(--civ-space-3) 0;
  border-top: 1px solid var(--civ-color-border-subtle);
  text-align: left;
  vertical-align: top;
}

.ps-page .ps-sheet th {
  width: 40%;
  padding-right: var(--civ-space-4);
  color: var(--civ-color-text-secondary);
  font-weight: var(--civ-weight-semibold);
}

.ps-page .ps-sheet caption,
.ps-page .ps-table caption {
  padding-bottom: var(--civ-space-2);
  color: var(--civ-color-text-secondary);
  font: var(--civ-font-role-body);
  text-align: left;
}

.ps-page .ps-table__num {
  font-family: var(--civ-font-mono);
  font-variant-numeric: tabular-nums;
}

.ps-page .ps-facts {
  margin-top: var(--civ-space-6);
  padding-top: var(--civ-space-4);
  border-top: 1px solid var(--civ-color-border-subtle);
}

.ps-page .ps-facts dt {
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

.ps-page .ps-facts dd {
  margin-bottom: var(--civ-space-3);
  font: var(--civ-font-role-body);
}

/* ---------------------------------------------------------------- bars ---- */

/* Decoration only: the list is aria-hidden and every value is written as text
   beside its label, with the accessible table open right below it. Colour
   carries the rank (--r), the percentage carries the width (--w); the strict
   CSP forbids an inline style attribute, so a width can only exist as a class
   and PublicSiteStyleGuardTest asserts the width classes and the catalogue
   percentages are the SAME set. */
.ps-page .ps-bars {
  margin-top: var(--civ-space-2);
}

.ps-page .ps-bars__item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--civ-space-1) var(--civ-space-3);
  margin-top: var(--civ-space-4);
}

.ps-page .ps-bars__label {
  font: var(--civ-font-role-body);
}

.ps-page .ps-bars__value {
  font-family: var(--civ-font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: var(--civ-weight-semibold);
}

.ps-page .ps-bar {
  grid-column: 1 / -1;
  display: block;
  height: var(--civ-space-3);
  background-color: var(--civ-color-chart-track);
  border-radius: var(--civ-radius-xs);
  overflow: hidden;
}

/* The fill grows from its left edge. The WIDTH is never animated — only a
   transform is, so no layout is recalculated and nothing on the page moves. */
.ps-page .ps-bar__fill {
  display: block;
  height: 100%;
  background-color: var(--civ-color-chart-1);
  transform-origin: left center;
  /* LONGHANDS, never the `animation` shorthand: with `animation: none <dur>
     <easing> both` the parser re-reads `none` as the fill-mode and promotes
     `both` to the animation NAME, so switching the animation off by name would
     only work by accident (no @keyframes is called `both`). Observed in
     Chrome; the longhand form makes `animation-name: none` unambiguous. */
  animation-name: var(--ps-grow-name);
  animation-duration: var(--ps-enter);
  animation-timing-function: var(--civ-motion-ease-out);
  animation-fill-mode: both;
}

.ps-page .ps-bars__item:nth-child(2) .ps-bar__fill {
  animation-delay: var(--ps-stagger);
}

.ps-page .ps-bars__item:nth-child(3) .ps-bar__fill {
  animation-delay: calc(var(--ps-stagger) * 2);
}

.ps-page .ps-bars__item:nth-child(4) .ps-bar__fill {
  animation-delay: calc(var(--ps-stagger) * 3);
}

.ps-page .ps-bar__fill--r1 {
  background-color: var(--civ-color-chart-lead);
}

.ps-page .ps-bar__fill--r2 {
  background-color: var(--civ-color-chart-1);
}

.ps-page .ps-bar__fill--r3 {
  background-color: var(--civ-color-chart-2);
}

.ps-page .ps-bar__fill--r4 {
  background-color: var(--civ-color-chart-3);
}

/* Width utilities — exactly the percentages src/PublicSite/Demo renders. */
.ps-page .ps-bar__fill--w13 { width: 13%; }
.ps-page .ps-bar__fill--w16 { width: 16%; }
.ps-page .ps-bar__fill--w19 { width: 19%; }
.ps-page .ps-bar__fill--w22 { width: 22%; }
.ps-page .ps-bar__fill--w23 { width: 23%; }
.ps-page .ps-bar__fill--w24 { width: 24%; }
.ps-page .ps-bar__fill--w27 { width: 27%; }
.ps-page .ps-bar__fill--w31 { width: 31%; }
.ps-page .ps-bar__fill--w38 { width: 38%; }
.ps-page .ps-bar__fill--w41 { width: 41%; }
.ps-page .ps-bar__fill--w46 { width: 46%; }

/* --------------------------------------------------------- disclosures ---- */

.ps-page .ps-disclosure {
  margin-top: var(--civ-space-6);
  border-top: 1px solid var(--civ-color-border-default);
}

.ps-page .ps-disclosure__toggle {
  display: flex;
  align-items: center;
  gap: var(--civ-space-3);
  min-height: var(--civ-target-comfort);
  padding: var(--civ-space-3) 0;
  color: var(--civ-color-text-link);
  font: var(--ps-font-action);
  cursor: pointer;
  list-style: none;
  transition: color var(--ps-fast) var(--civ-motion-ease);
}

.ps-page .ps-disclosure__toggle::-webkit-details-marker {
  display: none;
}

.ps-page .ps-disclosure__toggle::marker {
  content: "";
}

.ps-page .ps-disclosure--faq .ps-disclosure__toggle {
  color: var(--civ-color-text-default);
}

.ps-page .ps-faq__question {
  font: var(--civ-font-role-h3);
}

.ps-page .ps-faq .ps-text {
  padding-bottom: var(--civ-space-4);
}

/* ------------------------------------------------------------ sequences --- */

.ps-page .ps-steps {
  margin-top: var(--civ-space-6);
}

.ps-page .ps-steps__item {
  padding: var(--civ-space-6) 0;
  border-top: 1px solid var(--civ-color-border-default);
}

.ps-page .ps-steps__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--civ-space-2);
  margin-bottom: var(--civ-space-2);
}

/* Grid child at md and above: min-width 0 keeps a long unbroken word from
   pushing the column — and therefore the band — wider than the viewport. */
.ps-page .ps-steps__body {
  min-width: 0;
}

.ps-page .ps-steps__number {
  display: block;
  font: var(--civ-weight-black) var(--civ-text-h1) / var(--civ-leading-tight) var(--civ-font-display);
  color: var(--civ-color-text-data);
}

.ps-page .ps-steps__proof {
  margin-top: var(--civ-space-4);
  padding: var(--civ-space-3) var(--civ-space-4);
  background-color: var(--civ-color-surface-page);
  border: 1px solid var(--civ-color-border-subtle);
  border-radius: var(--civ-radius-md);
  font: var(--civ-font-role-body);
}

.ps-page .ps-steps__proofkey {
  display: block;
  margin-bottom: var(--civ-space-1);
  color: var(--civ-color-text-secondary);
  font-weight: var(--civ-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

/* --------------------------------------------------- placeholder blocks --- */

/* The reserved institutional blocks. Dashed on purpose: the form itself says
   "nothing has been decided here", so no person or body is ever invented. */
.ps-page .ps-reserved {
  margin-top: var(--civ-space-6);
}

.ps-page .ps-reserved__item {
  margin-top: var(--civ-space-4);
  padding: var(--civ-space-4);
  background-color: var(--civ-color-surface-page);
  border: 2px dashed var(--civ-color-border-default);
  border-radius: var(--civ-radius-md);
}

.ps-page .ps-reserved__label {
  margin-top: var(--civ-space-1);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

.ps-page .ps-empty {
  margin-top: var(--civ-space-6);
  padding: var(--civ-space-8) var(--civ-space-4);
  border: 2px dashed var(--civ-color-border-default);
  border-radius: var(--civ-radius-md);
  text-align: center;
}

.ps-page .ps-empty__title {
  font: var(--civ-font-role-h3);
}

.ps-page .ps-empty__body {
  max-width: 60ch;
  margin: var(--civ-space-2) auto 0;
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-secondary);
}

/* A note that qualifies what surrounds it: colour PLUS a border PLUS its own
   title, never colour alone. */
.ps-page .ps-warning {
  padding-block: var(--civ-space-4);
  background-color: var(--civ-color-state-warning-bg);
  border-left: 4px solid var(--civ-color-state-warning-border);
  border-radius: var(--civ-radius-md);
  color: var(--civ-color-text-default);
}

.ps-page .ps-warning--info {
  background-color: var(--civ-color-state-activity-tint);
  border-left-color: var(--civ-color-state-activity-border);
}

.ps-page .ps-warning__title {
  font: var(--civ-font-role-h3);
  color: var(--civ-color-state-warning-text);
}

/* The info title takes the DEFAULT ink, not the activity ink: measured in the
   browser, the activity text on the activity tint composes to 3.18:1 at
   19px/600 — which is not large text, so it misses the 4.5:1 floor. The tone
   is carried by the tint and the left border; the colour of the title was
   never the thing that distinguished it. */
.ps-page .ps-warning--info .ps-warning__title {
  color: var(--civ-color-text-default);
}

.ps-page .ps-warning__body {
  max-width: 78ch;
  margin-top: var(--civ-space-2);
  font: var(--civ-font-role-body);
}

/* The status markers of a demonstration sheet, rendered under its H1. */
.ps-page .ps-page-head__markers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--civ-space-2);
  margin-top: var(--civ-space-4);
}

/* --------------------------------------------------------------- error ---- */

.ps-page .ps-error {
  background-color: var(--civ-color-surface-invert);
  color: var(--civ-color-text-invert);
}

.ps-page .ps-error__code {
  font: var(--civ-weight-black) var(--civ-text-hero) / var(--civ-leading-tight) var(--civ-font-display);
  color: var(--civ-color-state-activity);
}

.ps-page .ps-error .ps-h1,
.ps-page .ps-error .ps-lead {
  color: var(--civ-color-text-invert);
}

.ps-page .ps-error__exits {
  margin-top: var(--civ-space-6);
}

/* The exits are cards on the ink surface. Their border carries the boundary
   of a control, so it takes the 10:1 on-dark ink rather than the 16%-opacity
   rule used for decorative separators — at that opacity the four exits read
   as one undivided block. */
.ps-page .ps-error .ps-navlist__link {
  min-height: var(--civ-target-comfort);
  padding: var(--civ-space-3) var(--civ-space-4);
  border: 1px solid var(--civ-color-text-on-dark);
  border-radius: var(--civ-radius-sm);
  color: var(--civ-color-text-invert);
}

.ps-page .ps-error .ps-navlist__link:hover {
  border-color: var(--civ-color-text-invert);
}

/* -------------------------------------------------------------- footer ---- */

.ps-page .ps-footer {
  background-color: var(--civ-color-surface-invert);
  color: var(--civ-color-text-on-dark);
}

.ps-page .ps-footer__inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: var(--civ-space-10) var(--civ-space-4) var(--civ-space-6);
}

.ps-page .ps-footer__brand {
  font: var(--civ-weight-black) var(--civ-text-h3) / var(--civ-leading-tight) var(--civ-font-display);
  color: var(--civ-color-text-invert);
  text-transform: uppercase;
  letter-spacing: var(--civ-tracking-caps);
}

.ps-page .ps-footer__mission {
  max-width: 46ch;
  margin-top: var(--civ-space-3);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-on-dark);
}

.ps-page .ps-footer__nav {
  margin-top: var(--civ-space-6);
}

.ps-page .ps-footer .ps-navlist__link {
  color: var(--civ-color-text-invert);
}

.ps-page .ps-footer .ps-navlist__link:hover,
.ps-page .ps-footer .ps-navlist__link[aria-current="page"] {
  border-bottom-color: var(--civ-color-border-invert);
}

.ps-page .ps-footer__pending {
  max-width: 78ch;
  margin-top: var(--civ-space-6);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-on-dark);
}

.ps-page .ps-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--civ-space-2) var(--civ-space-6);
  margin-top: var(--civ-space-6);
  padding-top: var(--civ-space-4);
  border-top: 1px solid var(--civ-color-border-invert);
  font: var(--civ-font-role-body);
  color: var(--civ-color-text-on-dark);
}

/* ================================================== entry animations ===== */

/* Two keyframes, both ending on the element's OWN normal styles: with no
   animation at all (reduced motion, or a browser that never runs it) every
   element renders exactly as it does here. Nothing is hidden waiting for a
   trigger, and there is no scroll observer — the site loads no script. */

@keyframes ps-rise {
  from {
    opacity: 0;
    transform: translateY(var(--civ-space-2));
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes ps-grow {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

/* The hero enters as one editorial block, line after line. Longhands, for the
   reason documented on .ps-bar__fill. */
.ps-page .ps-hero > * {
  animation-name: var(--ps-enter-name);
  animation-duration: var(--ps-enter);
  animation-timing-function: var(--civ-motion-ease-out);
  animation-fill-mode: both;
}

.ps-page .ps-hero > *:nth-child(2) {
  animation-delay: var(--ps-stagger);
}

.ps-page .ps-hero > *:nth-child(3) {
  animation-delay: calc(var(--ps-stagger) * 1.5);
}

.ps-page .ps-hero > *:nth-child(4) {
  animation-delay: calc(var(--ps-stagger) * 2);
}

.ps-page .ps-hero > *:nth-child(5) {
  animation-delay: calc(var(--ps-stagger) * 2.5);
}

/* Card and column groups appear one after the other rather than as a block.
   The delay is bounded: the fourth item is the last to be staggered, so no
   element can wait more than three steps. */
.ps-page .ps-cards > *,
.ps-page .ps-modes > *,
.ps-page .ps-columns > *,
.ps-page .ps-usecases > *,
.ps-page .ps-reserved > * {
  animation-name: var(--ps-enter-name);
  animation-duration: var(--ps-enter);
  animation-timing-function: var(--civ-motion-ease-out);
  animation-fill-mode: both;
}

.ps-page .ps-cards > *:nth-child(2),
.ps-page .ps-modes > *:nth-child(2),
.ps-page .ps-columns > *:nth-child(2),
.ps-page .ps-usecases > *:nth-child(2),
.ps-page .ps-reserved > *:nth-child(2) {
  animation-delay: var(--ps-stagger);
}

.ps-page .ps-cards > *:nth-child(3),
.ps-page .ps-modes > *:nth-child(3),
.ps-page .ps-columns > *:nth-child(3),
.ps-page .ps-usecases > *:nth-child(3),
.ps-page .ps-reserved > *:nth-child(3) {
  animation-delay: calc(var(--ps-stagger) * 2);
}

.ps-page .ps-cards > *:nth-child(n + 4),
.ps-page .ps-modes > *:nth-child(n + 4),
.ps-page .ps-columns > *:nth-child(n + 4),
.ps-page .ps-usecases > *:nth-child(n + 4),
.ps-page .ps-reserved > *:nth-child(n + 4) {
  animation-delay: calc(var(--ps-stagger) * 3);
}

/* ================================================== md — 768px and up ==== */
/* --civ-bp-md; @media cannot read a custom property. */

@media (min-width: 768px) {
  .ps-page .ps-hero,
  .ps-page .ps-page-head,
  .ps-page .ps-section,
  .ps-page .ps-error {
    padding-block: var(--civ-space-12);
  }

  .ps-page .ps-header__bar {
    padding: var(--civ-space-4) var(--civ-space-8);
  }

  .ps-page .ps-card {
    padding: var(--civ-space-6);
  }

  .ps-page .ps-steps__item {
    display: grid;
    grid-template-columns: var(--civ-space-16) minmax(0, 1fr) minmax(0, 0.9fr);
    gap: var(--civ-space-6);
    align-items: start;
  }

  .ps-page .ps-steps__head {
    display: block;
    margin-bottom: 0;
  }

  .ps-page .ps-steps__proof {
    margin-top: 0;
  }

  .ps-page .ps-facts {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--civ-space-2) var(--civ-space-6);
  }

  .ps-page .ps-facts dd {
    margin-bottom: 0;
  }

  .ps-page .ps-legend {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--civ-space-3) var(--civ-space-6);
    align-items: baseline;
  }

  .ps-page .ps-legend dt,
  .ps-page .ps-legend dd {
    margin-top: 0;
  }

  .ps-page .ps-reserved {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--civ-space-4);
  }

  .ps-page .ps-reserved__item {
    margin-top: 0;
  }

  .ps-page .ps-footer__inner {
    padding: var(--civ-space-16) var(--civ-space-8) var(--civ-space-8);
  }

  .ps-page .ps-error__exits .ps-navlist {
    flex-direction: column;
  }
}

/* ================================================= lg — 1024px and up ==== */
/* --civ-bp-lg. */

@media (min-width: 1024px) {
  /* Five entries at the 16px floor need the lg width to sit beside the
     wordmark; below it the native disclosure is the navigation. */
  .ps-page .ps-nav {
    display: block;
  }

  .ps-page .ps-menu {
    display: none;
  }

  .ps-page .ps-navlist {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--civ-space-4);
  }

  .ps-page .ps-header__bar {
    flex-wrap: nowrap;
  }

  .ps-page .ps-reserved {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .ps-page .ps-card {
    max-width: 900px;
  }
}

/* ================================================== reduced motion ====== */

/* The ONE place motion is switched off, and it wins by construction: the five
   custom properties are re-pointed at .ps-page, the same selector that
   declared them, so no more specific rule can outrank the override — every
   animated rule reads the property rather than a literal. The animation NAMES
   become `none`, which means the keyframes never apply at all and no element
   can be left mid-transition. The wildcard block below is a second net for
   anything that would forget the contract. */
@media (prefers-reduced-motion: reduce) {
  .ps-page {
    --ps-enter-name: none;
    --ps-grow-name: none;
    --ps-enter: 0ms;
    --ps-stagger: 0ms;
    --ps-fast: 0ms;
    --ps-base: 0ms;
  }

  .ps-page * {
    animation-duration: 0ms;
    animation-delay: 0ms;
    animation-iteration-count: 1;
    transition-duration: 0ms;
    transition-delay: 0ms;
    scroll-behavior: auto;
  }
}
