/* National Board of Operations Professionals
   Marketing stylesheet.

   The palette is a MARKETING palette, not the book's. That distinction cost a
   round: the Volume I cover is warm cream and warm black because it is a
   printed literary object, and reading those values onto a site made it look
   antique rather than authoritative. The books keep their palette. The site
   runs deep blue, white, and one bright accent reserved for action. */

:root {
  --ink:        #101B2B;
  --ink-soft:   #3C4A5E;
  --ink-faint:  #5B6878;
  --rule:       #D7DEE7;
  --rule-soft:  #EAEEF4;
  --paper:      #FFFFFF;
  --paper-warm: #F4F7FA;
  --navy:       #12294A;
  --signal:     #E8571F;
  --measure:    38rem;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* ---------- layout ---------- */

.wrap { max-width: 62rem; margin: 0 auto; padding: 0 1.75rem; }
.measure { max-width: var(--measure); }

main { padding: 4.5rem 0 5rem; }

section + section { margin-top: 3.5rem; }

/* ---------- masthead ---------- */

.masthead {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
}

.masthead .wrap {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  flex-wrap: wrap;
}

.wordmark {
  text-decoration: none;
  color: var(--navy);
  display: block;
  line-height: 1.25;
}

.wordmark .initials {
  font-family: var(--ui);
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: 1.05rem;
}

.wordmark .full {
  display: block;
  font-family: var(--ui);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 500;
  margin-top: 0.2rem;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 1.75rem;
  flex-wrap: wrap;
}

nav a {
  font-family: var(--ui);
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-soft);
  font-weight: 500;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}

nav a:hover { color: var(--navy); border-bottom-color: var(--rule); }
nav a[aria-current="page"] { color: var(--navy); border-bottom-color: var(--navy); }

/* ---------- type ---------- */

h1 {
  font-size: clamp(1.9rem, 4.2vw, 2.7rem);
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.012em;
  margin: 0 0 1.5rem;
  color: var(--navy);
  max-width: 22ch;
}

h2 {
  font-family: var(--ui);
  font-size: 0.78rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
  margin: 0 0 1.1rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule);
}

h3 {
  font-size: 1.18rem;
  font-weight: 600;
  line-height: 1.35;
  margin: 2rem 0 0.55rem;
  color: var(--navy);
}

p { margin: 0 0 1.15rem; max-width: var(--measure); }

.lede { font-size: 1.15rem; line-height: 1.6; color: var(--ink-soft); }

a { color: var(--navy); text-underline-offset: 0.18em; }

strong { font-weight: 600; }

/* ---------- components ---------- */

.rule { border: 0; border-top: 1px solid var(--rule); margin: 3.25rem 0; }

.standfirst {
  border-left: 2px solid var(--navy);
  padding: 0.15rem 0 0.15rem 1.4rem;
  margin: 0 0 2.25rem;
}
.standfirst p { margin: 0; font-size: 1.12rem; color: var(--ink-soft); }

.comparison {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5rem 0 2rem;
  font-size: 0.95rem;
  max-width: var(--measure);
}
.comparison th, .comparison td {
  text-align: left;
  padding: 0.7rem 1rem 0.7rem 0;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
}
.comparison th {
  font-family: var(--ui);
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
}
.comparison td:first-child { font-weight: 600; white-space: nowrap; padding-right: 2rem; }

.note {
  background: var(--paper-warm);
  border: 1px solid var(--rule-soft);
  padding: 1.4rem 1.6rem;
  margin: 2rem 0;
  max-width: var(--measure);
}
.note p:last-child { margin-bottom: 0; }
.note p { font-size: 0.97rem; }

.action {
  display: inline-block;
  font-family: var(--ui);
  font-size: 0.82rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-weight: 600;
  text-decoration: none;
  color: var(--paper);
  background: var(--navy);
  padding: 0.95rem 1.9rem;
  border: 1px solid var(--navy);
}
.action:hover { background: var(--ink); border-color: var(--ink); }

.action-secondary {
  background: transparent;
  color: var(--navy);
}
.action-secondary:hover { background: var(--paper-warm); color: var(--navy); border-color: var(--navy); }

.actions { margin: 2rem 0 0.75rem; display: flex; gap: 0.9rem; flex-wrap: wrap; }

.disclosure {
  font-size: 0.86rem;
  color: var(--ink-faint);
  margin-top: 1.1rem;
}

.meta {
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.6rem;
}

ol.spec, ul.spec { max-width: var(--measure); padding-left: 1.2rem; margin: 0 0 1.4rem; }
ol.spec li, ul.spec li { margin-bottom: 0.6rem; }

.changelog { max-width: var(--measure); margin: 1.25rem 0 0; }
.changelog dt {
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
  margin-top: 1.1rem;
}
.changelog dd { margin: 0.3rem 0 0; }

/* ---------- form ---------- */

.field { margin-bottom: 1.75rem; max-width: var(--measure); }
.field > legend, .field > label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.7rem;
  font-size: 1rem;
}
fieldset.field { border: 0; padding: 0; margin-left: 0; margin-right: 0; }

.choice { display: block; margin-bottom: 0.45rem; font-size: 0.97rem; cursor: pointer; }
.choice input { margin-right: 0.6rem; }

input[type="email"] {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
  font-family: inherit;
  font-size: 1rem;
  background: var(--paper);
  color: var(--ink);
}
input[type="email"]:focus { outline: 2px solid var(--navy); outline-offset: -2px; }

button.action { border: 1px solid var(--navy); cursor: pointer; font-family: var(--ui); }

.result {
  border-top: 2px solid var(--navy);
  padding-top: 1.5rem;
  margin-top: 2.5rem;
}
.result[hidden] { display: none; }

/* ---------- footer ---------- */

footer {
  border-top: 1px solid var(--rule);
  margin-top: 5rem;
  padding: 2.5rem 0 3.5rem;
  background: var(--paper-warm);
}

footer .wrap { display: flex; justify-content: space-between; gap: 2.5rem; flex-wrap: wrap; }

footer p, footer li {
  font-family: var(--ui);
  font-size: 0.82rem;
  color: var(--ink-faint);
  line-height: 1.7;
  margin: 0;
}

footer ul { list-style: none; padding: 0; margin: 0; }
footer a { color: var(--ink-soft); text-decoration: none; }
footer a:hover { text-decoration: underline; }

.colophon { max-width: 30rem; }

@media (max-width: 40rem) {
  body { font-size: 17px; }
  main { padding: 3rem 0 3.5rem; }
  .masthead .wrap { flex-direction: column; gap: 1.1rem; }
  nav ul { gap: 1.2rem; }
}

/* honeypot: present for bots, invisible and unfocusable for people */
.hp { display: none; }

/* ---------- job task analysis ---------- */

.ratebar { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.rate {
  display: inline-flex; align-items: center; gap: 0.35rem;
  border: 1px solid var(--rule); padding: 0.4rem 0.75rem;
  font-size: 0.92rem; cursor: pointer; min-width: 3.1rem; justify-content: center;
}
.rate:hover { background: var(--paper-warm); }
.rate input { margin: 0; }
.rate:has(input:checked) { border-color: var(--navy); background: var(--paper-warm); font-weight: 600; }

.allocrow {
  display: grid; grid-template-columns: 1fr 5.5rem auto;
  gap: 0.8rem; align-items: center; max-width: var(--measure);
  padding: 0.45rem 0; border-bottom: 1px solid var(--rule-soft);
  font-size: 0.95rem;
}
.allocnum {
  padding: 0.45rem 0.6rem; border: 1px solid var(--rule);
  font-family: inherit; font-size: 0.95rem; width: 100%;
  text-align: right; background: var(--paper); color: var(--ink);
}

textarea {
  width: 100%; padding: 0.8rem 1rem; border: 1px solid var(--rule);
  font-family: inherit; font-size: 1rem; line-height: 1.5;
  background: var(--paper); color: var(--ink); resize: vertical;
}
textarea:focus, .allocnum:focus { outline: 2px solid var(--navy); outline-offset: -2px; }

.domain { border-top: 1px solid var(--rule); padding-top: 1.6rem; margin-top: 2.2rem; }
.domain h3 { margin-top: 0; }
.q { margin-bottom: 1.3rem; max-width: var(--measure); }
.q > p { font-weight: 600; margin-bottom: 0.5rem; font-size: 0.99rem; }

button.action:disabled { opacity: 0.55; cursor: default; }

/* ---------- two-scale rating rows ---------- */

.scales {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0.9rem 1.6rem; align-items: start;
}
.scalelabel {
  display: block; font-size: 0.74rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.4rem;
}
.ratebar.freq.auto { opacity: 0.45; }

#progress {
  position: sticky; top: 0; z-index: 5;
  background: var(--paper); border-bottom: 1px solid var(--rule);
  padding: 0.65rem 0 0.7rem; margin-bottom: 1.4rem;
  font-size: 0.86rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-faint);
}
#progress::after {
  content: ""; display: block; height: 2px; width: var(--pct, 0%);
  background: var(--navy); margin-top: 0.5rem; transition: width 0.2s;
}
#progress.done { color: var(--navy); }

.anchors { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem 1.6rem; }
.anchors ol { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.93rem; }
.anchors li { margin-bottom: 0.15rem; }
.anchors ol { list-style: none; padding-left: 0; counter-reset: a -1; }
.anchors ol li::before {
  content: counter(a) "  "; counter-increment: a;
  font-weight: 600; color: var(--navy);
}

@media (max-width: 46rem) {
  .scales, .anchors { grid-template-columns: 1fr; }
}
/* ---------- narrow phones ---------- */

/* Long unbreakable strings, principally the contact address and certificate
   numbers, are wider than a 320px viewport and were the last thing forcing a
   horizontal scroll. break-word only splits a word that cannot fit on its own,
   so ordinary prose is unaffected. */
body { overflow-wrap: break-word; }
/* ---------- sign in ---------- */

/* Sign in is the only nav item that leaves the public site, so it is set
   apart rather than sitting in the run of pages. Separated by a rule and
   pushed to the end, which is where every visitor has been trained to look
   for it. */
nav ul li.signin {
  border-left: 1px solid var(--rule);
  padding-left: 1.75rem;
}
nav ul li.signin a { color: var(--navy); font-weight: 600; }
nav ul li.signin a:hover { border-bottom-color: var(--navy); }

@media (max-width: 40rem) {
  /* The rule reads as a divider only when the item is on the same line as
     something else. Once the nav wraps it is just a stray mark. */
  nav ul li.signin { border-left: 0; padding-left: 0; }
}

/* ======================================================================
   COMMERCIAL COMPONENTS
   Added 15 August 2026, when the site stopped being a specification and
   started being an offer.

   The rule from the top of this file still holds: no gradients, no drop
   shadows, no animation, no accent colour. A certification body is believed
   because it looks like it has been there a while, and the visual grammar
   of "been there a while" is rules, space and restraint. Everything below
   gets its emphasis from weight, scale and a hairline, never from colour.
   ====================================================================== */

/* ---------- the mark ---------- */

/* An instrument dial rather than a logo: a baseline through a circle, with
   eight ticks for the eight domains. It is drawn in one colour with no
   fills so it survives being embossed on a certificate, faxed, printed in
   black and white, and rendered at 20px in a browser tab. */
.mark { display: block; height: 2.35rem; width: auto; color: var(--navy); flex: none; }
.mark-lg { height: 5.5rem; }
.wordmark-row { display: flex; align-items: center; gap: 0.9rem; text-decoration: none; }

/* ---------- hero ---------- */

.hero { padding-bottom: 0.5rem; }
.hero h1 { max-width: 20ch; }
.hero .lede { max-width: 34rem; }

.eyebrow {
  font-family: var(--ui);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
  margin: 0 0 1.1rem;
}

/* ---------- authority strip ---------- */

/* Four facts, each one checkable. Deliberately not a testimonial row: NBOP
   has no holders yet, and a body that invents social proof before it has
   any is the exact thing this whole site is arguing against. */
.facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  margin: 3rem 0;
}
.facts div { padding: 1.6rem 1.6rem 1.6rem 0; border-right: 1px solid var(--rule-soft); }
.facts div:last-child { border-right: 0; }
.facts dt, .facts .n {
  display: block;
  font-family: var(--ui);
  font-size: 1.7rem;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.1;
  margin-bottom: 0.5rem;
  letter-spacing: -0.01em;
}
.facts dd, .facts p { margin: 0; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5; max-width: none; }

/* ---------- cards ---------- */

.cards { display: grid; gap: 1.15rem; margin: 1.75rem 0 0; }
.cards-2 { grid-template-columns: repeat(2, 1fr); }
.cards-3 { grid-template-columns: repeat(3, 1fr); }

.card {
  border: 1px solid var(--rule);
  padding: 1.5rem 1.6rem 1.6rem;
  background: var(--paper);
  display: flex;
  flex-direction: column;
}
a.card { text-decoration: none; color: inherit; }
a.card:hover { border-color: var(--navy); background: var(--paper-warm); }
.card h3 { margin: 0 0 0.5rem; font-size: 1.06rem; }
.card p { font-size: 0.93rem; color: var(--ink-soft); margin-bottom: 0.9rem; max-width: none; }
.card p:last-child { margin-bottom: 0; }
.card .price {
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule-soft);
  font-family: var(--ui);
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
}
.card .price b { color: var(--navy); font-size: 0.95rem; letter-spacing: 0; }

/* ---------- the offer module ---------- */

/* The one heavy element on the site. It earns the weight because it is the
   only place a number is being asked for. */
.offer {
  border: 2px solid var(--navy);
  padding: 2rem 2.2rem 2.2rem;
  margin: 2.25rem 0;
  max-width: 34rem;
  background: var(--paper);
}
.offer .amount {
  font-family: var(--ui);
  font-size: 3rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--navy);
  line-height: 1;
  display: block;
}
.offer .terms {
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
  margin: 0.7rem 0 1.5rem;
}
.offer ul { list-style: none; padding: 0; margin: 0 0 1.6rem; }
.offer li {
  padding: 0.6rem 0 0.6rem 1.5rem;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 0.95rem;
  position: relative;
}
.offer li:last-child { border-bottom: 0; }
.offer li::before {
  content: "";
  position: absolute;
  left: 0; top: 1.15rem;
  width: 0.7rem; height: 1px;
  background: var(--navy);
}
.offer li.no { color: var(--ink-faint); }
.offer li.no::before { background: var(--rule); }
.offer .action { width: 100%; text-align: center; }

/* ---------- release banner ---------- */

/* The cadence is a product, so it gets a fixed place on the page rather
   than a sentence buried in a paragraph. */
.release {
  border-top: 2px solid var(--navy);
  border-bottom: 1px solid var(--rule);
  padding: 1.4rem 0 1.5rem;
  margin: 3rem 0;
  display: flex;
  gap: 2rem;
  align-items: baseline;
  flex-wrap: wrap;
}
.release .tag {
  font-family: var(--ui);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--navy);
  white-space: nowrap;
}
.release p { margin: 0; font-size: 0.95rem; color: var(--ink-soft); }

/* ---------- volumes ---------- */

/* Books are drawn as spines rather than as cover mockups, because there are
   no covers yet and a fake 3D book render is the single most common tell of
   a course being sold as an institution. */
.volumes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.15rem; margin-top: 1.75rem; }
.volume {
  border: 1px solid var(--rule);
  border-left: 4px solid var(--navy);
  padding: 1.25rem 1.4rem 1.35rem;
  background: var(--paper-warm);
}
.volume .vn {
  font-family: var(--ui);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
  display: block;
  margin-bottom: 0.5rem;
}
.volume h3 { margin: 0 0 0.4rem; font-size: 1rem; line-height: 1.3; }
.volume p { font-size: 0.88rem; color: var(--ink-soft); margin: 0; max-width: none; }
.volume .status {
  display: block;
  margin-top: 0.8rem;
  font-family: var(--ui);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ---------- faq ---------- */

.faq { max-width: var(--measure); margin-top: 1.5rem; border-top: 1px solid var(--rule); }
.faq details { border-bottom: 1px solid var(--rule-soft); }
.faq summary {
  cursor: pointer;
  padding: 1.05rem 2rem 1.05rem 0;
  font-weight: 600;
  font-size: 1rem;
  list-style: none;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 0.2rem; top: 0.95rem;
  font-weight: 400;
  font-size: 1.3rem;
  color: var(--ink-faint);
  line-height: 1;
}
.faq details[open] summary::after { content: "\2013"; }
.faq summary:hover { color: var(--navy); }
.faq details > p { font-size: 0.96rem; color: var(--ink-soft); margin: 0 0 1.15rem; }

/* ---------- closing band ---------- */

.closer {
  border-top: 1px solid var(--rule);
  margin-top: 4rem;
  padding-top: 2.75rem;
}
.closer h2 { border: 0; padding: 0; }

/* ---------- status line ---------- */

.status-line {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink-faint);
  padding: 1.1rem 1.4rem;
  margin: 2.5rem 0;
  max-width: var(--measure);
  background: var(--paper-warm);
}
.status-line p { margin: 0; font-size: 0.9rem; color: var(--ink-soft); }

/* ---------- responsive ---------- */

@media (max-width: 58rem) {
  .facts { grid-template-columns: repeat(2, 1fr); }
  .facts div:nth-child(2) { border-right: 0; }
  .facts div:nth-child(1), .facts div:nth-child(2) { border-bottom: 1px solid var(--rule-soft); }
  .cards-3, .volumes { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 40rem) {
  .facts { grid-template-columns: 1fr; }
  .facts div { border-right: 0; border-bottom: 1px solid var(--rule-soft); padding-right: 0; }
  .facts div:last-child { border-bottom: 0; }
  .cards-2, .cards-3, .volumes { grid-template-columns: 1fr; }
  .offer { padding: 1.5rem 1.4rem 1.6rem; }
  .offer .amount { font-size: 2.4rem; }
  .mark { height: 2rem; }
}

/* ---------- phone navigation ----------

   Seven nav items wrap to three lines on a 390px viewport, which put the
   masthead in front of a third of the first screen. This is the CSS only
   disclosure pattern: a hidden checkbox, a label styled as the control, and
   a sibling selector. No JavaScript, so it cannot fail to load, and it
   degrades to the plain wrapped list if the selector is unsupported. */

.navtoggle { position: absolute; opacity: 0; pointer-events: none; }
.navbtn { display: none; }

@media (max-width: 46rem) {
  .masthead .wrap {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding-top: 1.1rem;
    padding-bottom: 1.1rem;
    gap: 1rem;
  }
  .navbtn {
    display: inline-block;
    font-family: var(--ui);
    font-size: 0.72rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--navy);
    border: 1px solid var(--rule);
    padding: 0.55rem 0.9rem;
    cursor: pointer;
    white-space: nowrap;
    flex: none;
  }
  .navbtn:hover { border-color: var(--navy); }
  .masthead nav { display: none; width: 100%; order: 3; }
  .navtoggle:checked ~ nav { display: block; }
  .masthead nav ul {
    flex-direction: column;
    gap: 0;
    border-top: 1px solid var(--rule);
    margin-top: 0.4rem;
    padding-top: 0.3rem;
  }
  .masthead nav li { border-bottom: 1px solid var(--rule-soft); }
  .masthead nav li:last-child { border-bottom: 0; }
  .masthead nav a { display: block; padding: 0.85rem 0; border-bottom: 0; font-size: 0.8rem; }
  .masthead nav ul li.signin { border-left: 0; padding-left: 0; }
  .wordmark .full { font-size: 0.62rem; letter-spacing: 0.07em; }
}

@media (max-width: 46rem) {
  /* The wordmark is the only flexible item in the masthead row, so it has to
     be allowed to shrink or it pushes the menu control onto a second line. */
  .masthead .wordmark { flex: 1 1 auto; min-width: 0; }
}

@media (max-width: 34rem) {
  /* Below this the full name cannot sit on one line beside the menu control.
     It is in the footer of every page, so the mark and the initials carry it
     here, which is what a masthead does at small sizes anyway. */
  .wordmark .full { display: none; }
  .wordmark .initials { font-size: 1.15rem; }
}

/* ---------------------------------------------------------------------------
   WARMTH AND SCALE

   The first cut of this sheet said "restrained by design" and then restrained
   itself into a specification document. Restraint is not the absence of
   presence. What follows adds typographic scale, warmth and a single accent,
   and adds no gradients, no shadows and no animation, because those would be
   decoration rather than authority.
   --------------------------------------------------------------------------- */

body {
  background: var(--paper);
  color: var(--ink);
  font-size: 1.0625rem;
  line-height: 1.72;
  -webkit-font-smoothing: antialiased;
}

/* Display type. A standards body should read like a university press, which
   means the headline carries the weight and the body text stays quiet. */
h1 {
  font-size: clamp(2.5rem, 6vw, 4.25rem);
  line-height: 1.03;
  letter-spacing: -0.021em;
  margin-bottom: 1.1rem;
}
h2 {
  font-size: clamp(1.55rem, 2.7vw, 2.1rem);
  line-height: 1.18;
  letter-spacing: -0.012em;
}
h3 { letter-spacing: -0.006em; }

main p { max-width: var(--measure); }

/* The eyebrow is where the accent lives on most pages: one short red mark at
   the top of a section, then nothing else competing with it. */
.eyebrow,
main > .wrap > section > h2::before,
section > h2::before { }

.eyebrow {
  color: var(--signal);
  letter-spacing: .2em;
  font-weight: 600;
}

/* Section rules, warmed and given a signal tick at the left so the page has a
   rhythm you can scan rather than an undifferentiated column. */
section { border-top: 1px solid var(--rule); }
section > h2 {
  position: relative;
  padding-top: .2rem;
}
section > h2::before {
  content: "";
  position: absolute;
  top: -1.35rem;
  left: 0;
  width: 2.25rem;
  height: 2px;
  background: var(--signal);
}

/* Standfirst: the paragraph that has to make somebody keep reading. */
.standfirst {
  border-left: 3px solid var(--signal);
  padding-left: 1.6rem;
}
.standfirst p {
  font-size: clamp(1.2rem, 2vw, 1.45rem);
  line-height: 1.52;
  color: var(--ink-soft);
  letter-spacing: -0.008em;
}

.lede { font-size: 1.185rem; line-height: 1.6; color: var(--ink-soft); }

/* Dark bands. Warm black, taken off the cover field, not navy. Used to break
   the page into movements. */
.hero, .closer, .offer, .release {
  background: var(--navy);
  color: var(--paper);
  border: 0;
}
.hero h1, .closer h2, .offer h2, .release h2 { color: var(--paper); }
.hero p, .closer p, .offer p, .release p { color: #D9D1C2; }
.hero .eyebrow, .closer .eyebrow, .offer .eyebrow, .release .eyebrow { color: #E08D80; }
.offer .price { color: var(--paper); }
.hero a, .closer a, .offer a, .release a { color: var(--paper); }

/* Panels and cards. A hairline of colour on the leading edge does more for
   perceived quality than a shadow ever will, and it survives print. */
.card, .volume, .note, .faq, .status-line {
  background: var(--paper-warm);
  border: 1px solid var(--rule-soft);
}
.card, .volume { border-left: 3px solid var(--rule); }
.note, .status-line { border-left: 3px solid var(--signal); }

.facts { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.facts .n {
  font-family: var(--display);
  font-size: clamp(2.4rem, 4.4vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
}

/* Links: an academic underline, set off the baseline so descenders survive. */
main a, footer a {
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: var(--rule);
}
main a:hover, footer a:hover {
  color: var(--signal);
  text-decoration-color: var(--signal);
}

/* Masthead and footer share the page ground so the site reads as one sheet. */
.masthead { background: var(--paper); border-bottom: 1px solid var(--rule); }
.masthead nav a { letter-spacing: .12em; }
.masthead nav a:hover { color: var(--signal); }
.masthead [aria-current="page"] { color: var(--signal); }
.masthead .mark { color: var(--ink); }

footer { background: var(--paper-warm); border-top: 1px solid var(--rule); color: var(--ink-soft); }

/* Tables read as reference material, which is what they are. */
table { border-color: var(--rule); }
thead th { border-bottom: 2px solid var(--ink); letter-spacing: .13em; }
tbody tr + tr { border-top: 1px solid var(--rule-soft); }

/* Buttons. Solid warm black by default; the red one is reserved for the single
   most important action on a page and is not used more than once. */
.action {
  background: var(--ink);
  color: var(--paper);
  border: 1px solid var(--ink);
  letter-spacing: .1em;
}
.action:hover { background: var(--signal); border-color: var(--signal); color: var(--paper); }
.action-secondary {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
}
.action-secondary:hover { background: var(--ink); color: var(--paper); }

.tag, .status, .vn { color: var(--ink-faint); letter-spacing: .16em; }
.meta { color: var(--ink-faint); }

::selection { background: var(--signal); color: var(--paper); }

/* --- corrections after looking at it on screen ---------------------------- */

/* A background needs padding or the type sits on the trim edge. */
.hero {
  padding: clamp(2.25rem, 4.5vw, 4rem) clamp(1.6rem, 3.5vw, 3.25rem) clamp(2rem, 4vw, 3.25rem);
  margin: 1.5rem 0 3rem;
}
.closer, .release {
  padding: clamp(2rem, 4vw, 3rem) clamp(1.6rem, 3.5vw, 3rem);
  margin: 3rem 0;
}
.hero h1 { max-width: 18ch; margin-top: .6rem; }
.hero .lede, .hero p { color: #DED6C6; }

/* The offer module goes back to light. Two dark blocks in one screen is a
   pattern, and the moment the accent repeats it stops being an accent. It also
   fixes a real defect: .offer .amount was set in the same warm black as the
   band, so the price was invisible against it. */
.offer {
  background: var(--paper-warm);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--signal);
}
.offer h2, .offer h3 { color: var(--ink); }
.offer p { color: var(--ink-soft); }
.offer .eyebrow { color: var(--signal); }
.offer .amount, .offer .price { color: var(--ink); }
.offer a { color: var(--ink); }
.offer .action { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.offer .action:hover { background: var(--signal); border-color: var(--signal); }

/* Dark bands should not also carry the section hairline and tick. */
.hero, .closer, .release { border-top: 0; }
.hero > h2::before, .closer > h2::before, .release > h2::before { background: var(--signal); }

/* --- section headings ----------------------------------------------------- */
/* The base sheet set h2 as a tiny uppercase sans label, which is a caption,
   not a heading. Enlarging it inherited the uppercase, the sans and the faint
   grey, so it read as a washed-out sign rather than a section title. A serif
   heading in full ink is what makes a page look like a press and not a form. */
h2 {
  font-family: var(--display);
  text-transform: none;
  letter-spacing: -0.014em;
  color: var(--ink);
  font-weight: 400;
  border-bottom: 0;
  padding-bottom: 0;
  margin: 0 0 1.15rem;
}
section { padding-top: 2.6rem; margin-top: 3rem; }
section > h2::before { top: -1.5rem; }

h3 { color: var(--ink); font-size: 1.22rem; }

/* The small uppercase label still has a job. It is just not the section title. */
.eyebrow { font-size: .72rem; }

/* The markup already carries an <hr class="rule"> between some sections, so the
   section border-top drew a second line right underneath it. One rule, not two. */
hr.rule + section { border-top: 0; padding-top: 1.4rem; margin-top: 1.6rem; }
hr.rule { border: 0; border-top: 1px solid var(--rule); margin: 3.25rem 0 0; }

/* .release .tag was set in --navy, and the release banner is now --navy, so the
   label rendered warm black on warm black at a contrast ratio of exactly 1.
   Caught by the contrast audit, not by looking at it. */
.release .tag { color: #E08D80; }

/* ===========================================================================
   IMAGE-LED COMPONENTS

   Adapted from how Les Mills and Course Careers actually build a page, which
   is not "a column of text with better colours". The moves worth stealing:
   a full bleed photographic hero with the headline sitting ON the image, a
   manifesto block set at display size with the accent picking out phrases,
   and cards that are photographs rather than boxes.

   What is deliberately NOT stolen: the energy. Les Mills sells exertion, so
   it shouts. NBOP sells a judgement about whether someone is competent, so
   it uses the same structure at a lower volume. Scale and photography, not
   glitz.
   =========================================================================== */

/* Break a child of .wrap out to the full viewport width. */
.bleed { width: 100vw; margin-left: calc(50% - 50vw); max-width: none; }

/* --- the photographic hero ------------------------------------------------ */
.shot {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: min(78vh, 700px);
  padding: 0;
  margin: 0 0 clamp(2.5rem, 5vw, 4.5rem);
  border: 0;
  overflow: hidden;
  background: var(--navy) 68% center / cover no-repeat;
}
.shot::after {
  content: "";
  position: absolute;
  inset: 0;
  /* A scrim, not decoration. Without it the headline is unreadable over the
     lit part of the frame, and legibility outranks the photograph. */
  background: linear-gradient(100deg,
    rgba(20,18,15,0.94) 0%,
    rgba(20,18,15,0.84) 30%,
    rgba(20,18,15,0.45) 60%,
    rgba(20,18,15,0.30) 100%);
}
.shot > .wrap { position: relative; z-index: 1; padding-top: clamp(4rem, 9vw, 7rem); padding-bottom: clamp(2.5rem, 5vw, 4rem); }
.shot h1 {
  color: var(--paper);
  max-width: 16ch;
  font-size: clamp(2.6rem, 6.2vw, 4.9rem);
  text-wrap: balance;
}
.shot p, .shot .lede { color: #E4DBCB; max-width: 40ch; }
.shot .eyebrow { color: #E79486; }
.shot .action { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.shot .action:hover { background: var(--signal); border-color: var(--signal); color: var(--paper); }
.shot .action-secondary { background: transparent; color: var(--paper); border-color: rgba(247,241,225,.55); }
.shot .action-secondary:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.shot .meta, .shot .note p { color: #BFB5A4; }

/* --- the manifesto -------------------------------------------------------- */
/* One idea, set large enough that it is the only thing on the screen. The red
   marks the clause the whole page turns on, and appears once. */
.manifesto { border: 0; padding: clamp(3.5rem, 8vw, 7rem) 0; margin: 0; }
.manifesto p {
  font-size: clamp(1.7rem, 3.5vw, 3rem);
  line-height: 1.22;
  letter-spacing: -0.022em;
  max-width: 30ch;
  color: var(--ink);
}
.manifesto em { font-style: normal; color: var(--signal); }
.manifesto .attrib {
  font-family: var(--ui);
  font-size: .78rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint); margin-top: 2.25rem; max-width: none;
}

/* --- a dark full width band ---------------------------------------------- */
.band { background: var(--navy); color: var(--paper); padding: clamp(3rem, 6vw, 5.5rem) 0; border: 0; margin: clamp(3rem,6vw,5rem) 0; }
.band h2, .band h3 { color: var(--paper); }
.band p { color: #D6CDBD; }
.band .eyebrow { color: #E79486; }
.band h2::before { background: var(--signal); }
.band .action { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.band .action:hover { background: var(--signal); border-color: var(--signal); color: var(--paper); }

/* --- showcase: an artifact beside the argument ---------------------------- */
.showcase { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(1.75rem, 4vw, 3.5rem); align-items: center; }
.showcase figure { margin: 0; }
.showcase img { width: 100%; height: auto; display: block; }
.showcase .frame img { border: 1px solid rgba(247,241,225,.14); }
.showcase figcaption {
  font-family: var(--ui);
  font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint); margin-top: .85rem;
}
.band .showcase figcaption { color: #9C9284; }
@media (max-width: 780px) { .showcase { grid-template-columns: 1fr; } }

/* --- photographic tiles --------------------------------------------------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.15rem; margin: 2.25rem 0 0; }
.tile {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 330px; padding: 1.75rem; overflow: hidden; text-decoration: none;
  background: var(--navy) center / cover no-repeat; color: var(--paper);
}
.tile::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(20,18,15,.25) 0%, rgba(20,18,15,.55) 45%, rgba(20,18,15,.93) 100%);
}
.tile > * { position: relative; z-index: 1; }
.tile .eyebrow { color: #E79486; margin-bottom: .5rem; }
.tile h3 { color: var(--paper); margin: 0 0 .5rem; font-size: 1.55rem; }
.tile p { color: #CFC6B6; margin: 0; font-size: .96rem; max-width: 34ch; }
.tile:hover::after { background: linear-gradient(180deg, rgba(20,18,15,.18) 0%, rgba(20,18,15,.5) 45%, rgba(20,18,15,.9) 100%); }
.tile:hover h3 { color: var(--paper); }

/* --- proof strip ---------------------------------------------------------- */
.proof { display: flex; flex-wrap: wrap; gap: 2.5rem 3.5rem; align-items: baseline; padding: 1.75rem 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.proof div { display: flex; align-items: baseline; gap: .7rem; }
.proof b {
  font-family: var(--display);
  font-size: 1.9rem; font-weight: 400; letter-spacing: -0.02em; color: var(--ink);
}
.proof span {
  font-family: var(--ui);
  font-size: .72rem; letter-spacing: .15em; text-transform: uppercase; color: var(--ink-faint);
}
/* The homepage hero photograph. */
.hero.shot { background-image: url("/assets/img/hero-2000.jpg"); }

/* The first cut of .bleed set width:100vw and only margin-left, so the block
   shifted right instead of centring, and 100vw counts the scrollbar, which
   added a horizontal scroll. Symmetric negative margins with width:auto fix
   the centring; overflow-x on the root absorbs the scrollbar width. */
html, body { overflow-x: hidden; }
.bleed { width: auto; margin-inline: calc(50% - 50vw); }
.shot > .wrap { width: 100%; }

/* A photographic hero should butt against the masthead, not float below it in
   a band of page colour. And the eyebrow was inheriting the body measure, so
   a six word label wrapped. */
main > .wrap { padding-top: 0; }
main > .wrap > *:first-child:not(.shot) { margin-top: 2.75rem; }
.shot { margin-top: 0; }
.shot .eyebrow, .band .eyebrow, .tile .eyebrow { max-width: none; }
.shot .eyebrow { margin-bottom: 1.1rem; }

/* Two corrections found by inspecting computed style rather than eyeballing.
   1. The gap above the hero is main's own 72px padding, not the wrap's.
   2. overflow-x:hidden on html made it a scroll container and broke wheel
      scrolling. overflow:clip clips without creating one. */
html, body { overflow-x: clip; }
main:has(> .wrap > .shot:first-child) { padding-top: 0; }

/* ===========================================================================
   COOL PALETTE OVERRIDE

   Everything below re-points the values that were hardcoded warm while the
   site was running the book palette. Kept as an explicit layer rather than
   edited in place so the warm version stays recoverable.
   =========================================================================== */

/* Accent used as TEXT on white needs a darker cut: #E8571F on white is 3.6:1,
   which fails AA. #C2410C is 5.2:1 and reads as the same colour family. */
:root { --signal-ink: #C2410C; }

body { background: var(--paper); color: var(--ink); }
.masthead { background: var(--paper); }
footer { background: var(--paper-warm); }

.eyebrow { color: var(--signal-ink); }
.standfirst { border-left-color: var(--signal); }
.note, .status-line { border-left-color: var(--signal); }
.offer { border-left-color: var(--signal); }
section > h2::before { background: var(--signal); }

/* Dark bands: deep blue, not warm black. */
.hero, .closer, .offer, .release, .band, .tile { }
.hero, .closer, .release, .band { background: var(--navy); }
.hero p, .hero .lede, .closer p, .release p, .band p { color: #C6D2E2; }
.hero .eyebrow, .closer .eyebrow, .release .eyebrow, .band .eyebrow, .tile .eyebrow { color: #FF8B57; }
.release .tag { color: #FF8B57; }
.band .showcase figcaption { color: #8C9BB0; }
.showcase .frame img { border-color: rgba(255,255,255,.16); }

/* The offer module stays light on the white ground. */
.offer { background: var(--paper-cream); color: var(--ink); border-color: var(--rule); border-left-color: var(--signal); }
.offer p { color: var(--ink-soft); }
.offer .eyebrow { color: var(--signal-ink); }
.offer .amount, .offer .price, .offer h2, .offer h3, .offer a { color: var(--ink); }

/* Buttons. Bright accent with near-black type is 4.7:1 and passes; the same
   orange with white type would be 3.6:1 and would not. */
.action { background: var(--signal); color: var(--ink); border-color: var(--signal); font-weight: 600; }
.action:hover { background: var(--navy); border-color: var(--navy); color: #FFFFFF; }
.action-secondary { background: transparent; color: var(--ink); border-color: var(--ink); }
.action-secondary:hover { background: var(--ink); color: #FFFFFF; }
.hero .action, .band .action, .closer .action, .release .action { background: var(--signal); color: var(--ink); border-color: var(--signal); }
.hero .action:hover, .band .action:hover, .closer .action:hover, .release .action:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }
.hero .action-secondary, .band .action-secondary { color: #FFFFFF; border-color: rgba(255,255,255,.5); background: transparent; }
.hero .action-secondary:hover, .band .action-secondary:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }

.masthead nav a:hover, .masthead [aria-current="page"] { color: var(--signal-ink); }
main a:hover, footer a:hover { color: var(--signal-ink); text-decoration-color: var(--signal-ink); }
.manifesto em { color: var(--signal-ink); }
::selection { background: var(--signal); color: var(--ink); }

.card, .volume, .note, .faq, .status-line { background: var(--paper-warm); border-color: var(--rule-soft); }
.card, .volume { border-left-color: var(--rule); }

/* ===========================================================================
   HERO WITHOUT PHOTOGRAPHY

   A moody photograph of one person in a dark room reads as a film still, not
   as a body that certifies operators. The headline carries it instead. The
   band, the bleed and the type scale are unchanged, so the hero still has
   presence; it just is not pretending to be a magazine cover.
   =========================================================================== */
.hero.shot { background-image: none; background-color: var(--navy); }
.hero.shot::after { display: none; }
.hero.shot { min-height: 0; }
.hero.shot > .wrap { padding-top: clamp(3.5rem, 7vw, 5.5rem); padding-bottom: clamp(3rem, 6vw, 4.75rem); }
.hero.shot h1 { max-width: 19ch; }
.hero.shot p, .hero.shot .lede { color: #C6D2E2; }
.hero.shot .eyebrow { color: #FF8B57; }

/* A book cover is portrait, so it needs a narrower column than the certificate
   showcase gives it, and a hard cap so it does not balloon on wide screens. */
.showcase.cover { grid-template-columns: minmax(200px, 290px) 1fr; align-items: start; gap: clamp(1.75rem, 4vw, 3.25rem); }
.showcase.cover img { border: 1px solid var(--rule); width: 100%; height: auto; }
.showcase.cover .standfirst { border-left: 3px solid var(--signal); padding-left: 1.6rem; margin: 0; }
@media (max-width: 700px) {
  .showcase.cover { grid-template-columns: 1fr; }
  .showcase.cover figure { max-width: 260px; }
}

/* ===========================================================================
   ACADEMIC LAYER

   Structure taken from the Kingster college template, which is the register
   JT wants: a banner masthead per page, breadcrumbs, uppercase section
   headings with a trailing rule, and a dark fact panel beside the body copy.

   One deliberate departure: Kingster runs a photograph behind every banner.
   NBOP runs solid navy. "Less imagery, more academic" was the brief, and a
   standards body has no campus to photograph.
   =========================================================================== */

/* --- page banner ---------------------------------------------------------- */
.pagehead {
  background: var(--navy);
  color: #FFFFFF;
  border: 0;
  margin: 0 0 0;
  padding: 0;
  display: flex;
  align-items: flex-end;
  min-height: clamp(230px, 34vw, 400px);
}
.pagehead > .wrap { width: 100%; padding-top: clamp(2.75rem, 6vw, 5rem); padding-bottom: clamp(1.75rem, 3.5vw, 2.75rem); }
.pagehead .eyebrow { color: #FF8B57; display: block; margin: 0 0 .85rem; max-width: none; }
.pagehead h1 {
  color: #FFFFFF;
  text-transform: uppercase;
  letter-spacing: .012em;
  font-size: clamp(1.85rem, 4vw, 3.4rem);
  line-height: 1.1;
  margin: 0;
  max-width: 24ch;
}
.pagehead p, .pagehead .lede { color: #C6D2E2; max-width: 46ch; margin-top: 1.1rem; }
.pagehead .actions { margin-top: 1.75rem; }

/* --- breadcrumbs ---------------------------------------------------------- */
.crumbs {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
  margin: 0 0 clamp(2rem, 4vw, 3.25rem);
}
.crumbs > .wrap { padding-top: 1.05rem; padding-bottom: 1.05rem; }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .55rem; align-items: center; font-size: .84rem; }
.crumbs li + li::before { content: "›"; color: var(--ink-faint); margin-right: .55rem; }
.crumbs a { color: var(--ink-faint); text-decoration: none; }
.crumbs a:hover { color: var(--signal-ink); }
.crumbs [aria-current] { color: var(--ink); }

/* --- section headings, ruled --------------------------------------------- */
/* The device that makes an academic page read as one: an uppercase label with
   a hairline running out to the margin. */
section > h2 {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  text-transform: uppercase;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  letter-spacing: .075em;
  color: var(--navy);
  line-height: 1.25;
}
section > h2::before { display: none; }
section > h2::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--rule);
  min-width: 2rem;
}
section { border-top: 0; padding-top: 0; margin-top: clamp(2.5rem, 5vw, 3.75rem); }
hr.rule + section { padding-top: 0; margin-top: clamp(2.5rem, 5vw, 3.75rem); }

h3 { text-transform: none; }

/* --- body and sidebar ----------------------------------------------------- */
.layout { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.layout > .body > section:first-child { margin-top: 0; }
.sidebar { background: var(--navy); color: #FFFFFF; padding: 1.9rem 1.75rem; position: sticky; top: 1.5rem; }
.sidebar h2 {
  text-transform: uppercase; letter-spacing: .075em; font-size: 1.02rem;
  color: #FFFFFF; margin: 0 0 1.15rem; padding-bottom: .85rem;
  border-bottom: 1px solid rgba(255,255,255,.22);
  font-family: var(--display);
}
.sidebar dl { margin: 0; }
.sidebar dt {
  font-family: var(--ui);
  font-size: .68rem; letter-spacing: .15em; text-transform: uppercase;
  color: #8FA2BC; margin-top: 1.15rem;
}
.sidebar dt:first-child { margin-top: 0; }
.sidebar dd { margin: .3rem 0 0; color: #FFFFFF; font-size: 1.02rem; line-height: 1.45; max-width: none; }
.sidebar dd small { display: block; color: #A9B8CC; font-size: .84rem; margin-top: .15rem; }
.sidebar .action { display: block; text-align: center; margin-top: 1.6rem; background: var(--signal); color: var(--ink); border-color: var(--signal); }
.sidebar .action:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }
.sidebar p { color: #C6D2E2; font-size: .9rem; }
@media (max-width: 900px) {
  .layout { grid-template-columns: 1fr; }
  .sidebar { position: static; }
}

/* The banner replaces the old photographic hero entirely. */
.hero.shot { background-image: none; }

/* The margin shorthand on .pagehead and .crumbs reset the inline margins that
   .bleed depends on, so both banners stayed trapped inside the text column.
   Use margin-block so the bleed survives. */
.pagehead { margin: 0; margin-block: 0; margin-inline: calc(50% - 50vw); }
.crumbs { margin: 0; margin-block: 0 clamp(2rem, 4vw, 3.25rem); margin-inline: calc(50% - 50vw); }
main:has(> .wrap > .pagehead:first-child) { padding-top: 0; }

/* The first-child top margin was written when the hero was the only banner.
   The page banner must sit flush under the masthead too. */
main > .wrap > *:first-child:not(.shot):not(.pagehead) { margin-top: 2.75rem; }
main > .wrap > .pagehead:first-child { margin-top: 0; }

/* The button rules were scoped to .hero and .band. Renaming the hero to
   .pagehead orphaned them, which left the secondary button dark-on-navy at a
   contrast ratio of 1.19: invisible. */
.pagehead .action { background: var(--signal); color: var(--ink); border-color: var(--signal); }
.pagehead .action:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }
.pagehead .action-secondary { background: transparent; color: #FFFFFF; border-color: rgba(255,255,255,.55); }
.pagehead .action-secondary:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }
.pagehead .disclosure, .pagehead .meta, .pagehead .note p { color: #B9C6D8; }

/* Do not depend on :first-child. Any page banner sits flush under the
   masthead, whatever precedes it in source order. */
main:has(.pagehead) { padding-top: 0; }
main > .wrap > .pagehead { margin-top: 0; order: -1; }
main > .wrap:has(> .pagehead) { display: flex; flex-direction: column; }
main > .wrap > .crumbs { order: -1; }

/* ===========================================================================
   INSTITUTIONAL CHROME

   The previous passes added Kingster's details onto a text-document skeleton.
   This changes the skeleton: a fixed masthead, a heavyweight dark footer with
   real columns, and a body column that expects a fact panel beside it. That
   is what makes a site read as an institution rather than a long page.
   =========================================================================== */

/* --- masthead: fixed, with a rule and a utility strip ---------------------- */
.masthead {
  position: sticky; top: 0; z-index: 60;
  background: rgba(255,255,255,.97);
  backdrop-filter: saturate(1.4) blur(6px);
  border-bottom: 1px solid var(--rule);
  box-shadow: 0 1px 0 rgba(16,27,43,.04);
}
.masthead > .wrap { padding-top: 1.05rem; padding-bottom: 0; }
.masthead nav { border-top: 1px solid var(--rule-soft); margin-top: .95rem; }
.masthead nav ul { padding: .1rem 0 .1rem; }
.masthead nav a {
  font-size: .78rem; letter-spacing: .11em; font-weight: 600;
  padding: .95rem 0; display: inline-block; border-bottom: 3px solid transparent;
}
.masthead nav a:hover { border-bottom-color: var(--signal); color: var(--ink); }
.masthead [aria-current="page"] { border-bottom-color: var(--signal); color: var(--ink); }
.masthead .signin a {
  background: var(--navy); color: #FFFFFF; padding: .62rem 1.15rem;
  border-bottom: 0; border-radius: 0;
}
.masthead .signin a:hover { background: var(--signal); color: var(--ink); border-bottom: 0; }
.masthead .initials { letter-spacing: .16em; }

/* --- footer: the institutional block -------------------------------------- */
footer {
  background: var(--navy);
  color: #C6D2E2;
  border-top: 6px solid var(--signal);
  margin-top: clamp(3.5rem, 7vw, 6rem);
  padding: clamp(3rem, 5.5vw, 4.5rem) 0 0;
}
footer > .wrap { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1.75rem, 4vw, 3.5rem); align-items: start; }
footer .colophon { grid-column: 1; }
footer .colophon p:first-child { color: #FFFFFF; font-size: 1.06rem; letter-spacing: .04em; text-transform: uppercase; margin-bottom: .9rem; font-family: var(--display); }
footer .colophon p { color: #A9B8CC; font-size: .9rem; line-height: 1.65; max-width: 42ch; }
footer ul { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 2rem; grid-column: 2 / span 2; }
footer li { break-inside: avoid; margin: 0 0 .68rem; }
footer a { color: #DCE4EF; text-decoration: none; font-size: .9rem; }
footer a:hover { color: #FFFFFF; text-decoration: underline; text-decoration-color: var(--signal); text-underline-offset: .22em; }
footer .colophon a { color: #DCE4EF; text-decoration: underline; text-decoration-color: rgba(255,255,255,.3); }
@media (max-width: 800px) {
  footer > .wrap { grid-template-columns: 1fr; }
  footer ul { grid-column: 1; columns: 2; }
}

/* --- body column expects a companion panel -------------------------------- */
.layout { margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.layout > .body > *:first-child { margin-top: 0; }
.sidebar .rule-top { border-top: 1px solid rgba(255,255,255,.2); margin-top: 1.4rem; padding-top: 1.2rem; }

/* Pull the whole page in a touch: Kingster runs a narrower measure than we did,
   which is a large part of why it reads as considered rather than sprawling. */
.wrap { max-width: 1120px; }

/* --- banner photography ---------------------------------------------------
   A boardroom for a board. Clean, bright, architectural, and it disappears
   under the navy scrim so the headline never fights it. The overlay is not
   decoration: without it the type is unreadable over the windows. */
.pagehead {
  background-image:
    linear-gradient(100deg, rgba(16,32,58,.95) 0%, rgba(16,32,58,.88) 32%, rgba(16,32,58,.62) 68%, rgba(16,32,58,.5) 100%),
    url("/assets/img/banner-board-2000.jpg");
  background-size: cover, cover;
  background-position: center, 62% center;
  background-repeat: no-repeat, no-repeat;
}
.pagehead.plain { background-image: none; }

/* The sticky masthead was overlapping the sticky sidebar heading. */
.sidebar { top: 9.75rem; }
@media (max-width: 900px) { .sidebar { top: auto; } }

/* And it was taller than it needed to be, eating the banner. */
.masthead > .wrap { padding-top: .85rem; }
.masthead nav { margin-top: .7rem; }
.masthead nav a { padding: .78rem 0; }
.masthead .full { font-size: .66rem; }

/* ===========================================================================
   CONTENT BLOCKS

   The reference page never runs more than about two paragraphs before it
   changes format: ruled title, then a grid of titled cards, then a panel.
   These are the equivalents. The point is not decoration, it is that a reader
   scanning the page can find the shape of the argument without reading it.
   =========================================================================== */

/* Bulleted specification lists become a bordered grid instead of a wall. */
ul.spec {
  list-style: none; margin: 1.5rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
ul.spec li {
  background: var(--paper); margin: 0; padding: 1.15rem 1.25rem;
  font-size: .96rem; line-height: 1.6; position: relative;
}
ul.spec li::before {
  content: ""; position: absolute; left: 0; top: 1.35rem;
  width: 3px; height: 1.05rem; background: var(--signal);
}
.sidebar ul.spec, .offer ul.spec { display: block; border: 0; background: none; }

/* Titled cards: the workhorse for breaking a list into a scannable grid. */
.features { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.15rem; margin: 1.75rem 0 0; }
.feature { background: var(--paper-warm); border: 1px solid var(--rule-soft); border-top: 3px solid var(--navy); padding: 1.5rem 1.35rem; }
.feature:first-child { border-top-color: var(--signal); }
.feature .n {
  display: block; font-family: var(--ui);
  font-size: .68rem; letter-spacing: .17em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: .55rem;
}
.feature h3 { margin: 0 0 .5rem; font-size: 1.08rem; }
.feature p { margin: 0; font-size: .94rem; line-height: 1.62; color: var(--ink-soft); max-width: none; }

/* Numbered process. */
.steps { list-style: none; counter-reset: s; margin: 1.75rem 0 0; padding: 0; }
.steps li { counter-increment: s; position: relative; padding: 0 0 1.35rem 3.4rem; margin: 0; border-left: 1px solid var(--rule); }
.steps li:last-child { border-left-color: transparent; padding-bottom: 0; }
.steps li::before {
  content: counter(s, decimal-leading-zero); position: absolute; left: -1.05rem; top: -.15rem;
  width: 2.1rem; height: 2.1rem; display: grid; place-items: center;
  background: var(--navy); color: #FFFFFF; font-family: var(--ui);
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
}
.steps h3 { margin: 0 0 .3rem; font-size: 1.05rem; }
.steps p { margin: 0; font-size: .95rem; color: var(--ink-soft); }

/* A navy call band between sections. */
.callout { background: var(--navy); color: #FFFFFF; padding: clamp(1.75rem, 3.5vw, 2.6rem); margin: clamp(2.25rem, 4vw, 3.25rem) 0 0; border-left: 4px solid var(--signal); }
.callout h2, .callout h3 { color: #FFFFFF; margin-top: 0; }
.callout h2::after { background: rgba(255,255,255,.28); }
.callout p { color: #C6D2E2; }
.callout .action { background: var(--signal); color: var(--ink); border-color: var(--signal); margin-top: .9rem; }
.callout .action:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }

/* Tables read as reference tables, not as text. */
main table { width: 100%; border-collapse: collapse; margin-top: 1.5rem; font-size: .95rem; }
main thead th { background: var(--navy); color: #FFFFFF; text-align: left; padding: .85rem 1rem; font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; border: 0; }
main tbody td { padding: .9rem 1rem; border-bottom: 1px solid var(--rule-soft); vertical-align: top; }
main tbody tr:nth-child(even) td { background: var(--paper-warm); }

/* Notes read as marginalia, which is what they are. */
.note { border-left: 3px solid var(--signal); background: var(--paper-warm); padding: 1.15rem 1.35rem; }
.note p { margin: 0; font-size: .95rem; }

.standfirst p { font-size: clamp(1.12rem, 1.6vw, 1.3rem); }

/* An older rule left the table header in the faint grey while the new header
   band is navy, which measured 2.56:1. Header cells are white on navy; row
   header cells stay in ink on the light row. */
main thead th, main thead th * { color: #FFFFFF; }
main tbody th { color: var(--ink); background: transparent; text-align: left; padding: .9rem 1rem; border-bottom: 1px solid var(--rule-soft); }

/* .comparison th carries a class and outranked "main thead th", so the header
   stayed in faint grey on the navy band at 2.56:1. Match the specificity. */
table.comparison thead th, table.comparison thead th * { color: #FFFFFF; }
table.comparison thead th { background: var(--navy); }

/* Feature cards used as an index need their links to read as links. */
.features .feature h3 a { color: var(--ink); text-decoration: none; }
.features .feature h3 a:hover { color: var(--signal-ink); text-decoration: underline; text-underline-offset: .18em; }
.features .feature { display: flex; flex-direction: column; }
.features .feature p:last-child { margin-top: auto; }

/* Steps inside a section should not inherit the section's top margin twice. */
.steps li > h3 { margin-top: 0; }
.steps li > ul.spec { margin-top: .9rem; }
.steps li > p + p { margin-top: .6rem; }

/* --- FAQ accordions -------------------------------------------------------
   Open by default. An answer engine reads the DOM either way, but a human
   scanning for one fact should not have to click fourteen times to find it,
   and a collapsed answer is a worse experience than a long page. */
details.q { border-bottom: 1px solid var(--rule); padding: 0; }
details.q:first-of-type { border-top: 1px solid var(--rule); }
details.q summary {
  list-style: none; cursor: pointer; padding: 1.15rem 2.5rem 1.15rem 0; position: relative;
  font-family: var(--display);
  font-size: 1.12rem; line-height: 1.4; color: var(--navy); font-weight: 400;
}
details.q summary::-webkit-details-marker { display: none; }
details.q summary::after {
  content: ""; position: absolute; right: .35rem; top: 1.55rem;
  width: .72rem; height: .72rem; border-right: 2px solid var(--signal); border-bottom: 2px solid var(--signal);
  transform: rotate(45deg); transition: transform .15s ease;
}
details.q[open] summary::after { transform: rotate(-135deg); top: 1.75rem; }
details.q summary:hover { color: var(--signal-ink); }
details.q > div { padding: 0 2.5rem 1.35rem 0; }
details.q p { margin: 0; color: var(--ink-soft); font-size: 1rem; line-height: 1.7; }

/* Two finished covers side by side on the homepage. */
.covers { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 240px)); gap: clamp(1.25rem, 3vw, 2.5rem); margin: 2rem 0 1.25rem; }
.covers figure { margin: 0; }
.covers img { width: 100%; height: auto; display: block; border: 1px solid var(--rule); }
.covers a { text-decoration: none; }
.covers figcaption { margin-top: .85rem; }
.covers figcaption .vn { display: block; font-family: var(--ui); font-size: .66rem; letter-spacing: .17em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: .3rem; }
.covers figcaption a { font-family: var(--display); font-size: 1.1rem; color: var(--ink); }
.covers figcaption a:hover { color: var(--signal-ink); text-decoration: underline; text-underline-offset: .18em; }
.covers figcaption small { display: block; color: var(--ink-faint); font-size: .84rem; margin-top: .25rem; line-height: 1.45; }

/* ===========================================================================
   REFERENCE LAYOUT, SECOND PASS

   Three things the reference does that we were not doing:
   1. The banner carries the title only. Any heavy opening copy sits in a
      centred intro block underneath it, never in the banner.
   2. Section grounds alternate white and a light tint, so bands of content
      read as separate movements without needing rules everywhere.
   3. The big statement bands are centred, while body content stays ranged
      left. Centring everything would be worse; centring only the statements
      is what gives the page its rhythm.
   =========================================================================== */

/* --- the centred intro block --------------------------------------------- */
.intro { background: var(--paper); border: 0; margin: 0; padding: clamp(3rem, 6vw, 5rem) 0 clamp(2.5rem, 5vw, 4rem); }
.intro > .wrap { text-align: center; }
.intro .eyebrow { color: var(--ink-faint); letter-spacing: .2em; margin-bottom: 1rem; max-width: none; }
.intro h2 {
  display: block; text-align: center; text-transform: uppercase;
  font-size: clamp(1.5rem, 3.2vw, 2.5rem); line-height: 1.22; letter-spacing: .02em;
  color: var(--navy); margin: 0 auto 1.5rem; max-width: 22ch;
}
.intro h2::after { display: none; }
.intro p { margin-left: auto; margin-right: auto; max-width: 62ch; text-align: center; }
.intro .lede { font-size: clamp(1.08rem, 1.5vw, 1.22rem); color: var(--ink-soft); }
.intro .actions { justify-content: center; margin-top: 1.9rem; }
.intro .disclosure { color: var(--ink-faint); font-size: .88rem; margin-top: 1.1rem; }

/* --- alternating grounds -------------------------------------------------- */
/* A tinted band behind a whole section, full width, so the page has movements. */
.tint { background: var(--paper-warm); border: 0; padding: clamp(2.75rem, 5vw, 4.25rem) 0; margin: clamp(2.5rem, 5vw, 4rem) 0; }
.tint > .wrap > *:first-child { margin-top: 0; }
.tint .card, .tint .volume, .tint .feature, .tint ul.spec li { background: var(--paper); }

/* --- centred statement bands --------------------------------------------- */
.band.centred > .wrap { text-align: center; }
.band.centred h2 {
  display: block; text-align: center; justify-content: center;
  text-transform: uppercase; letter-spacing: .02em;
  font-size: clamp(1.6rem, 3.4vw, 2.7rem); line-height: 1.2;
  margin: 0 auto 1.2rem; max-width: 20ch;
}
.band.centred h2::after { display: none; }
.band.centred p { margin-left: auto; margin-right: auto; max-width: 58ch; }
.band.centred .actions { justify-content: center; }
.band.centred .eyebrow { max-width: none; }

/* The closer is the page's last statement, so it gets the same treatment. */
.closer { background: var(--navy); color: #FFFFFF; text-align: center; padding: clamp(3rem, 6vw, 5rem) 0; }
.closer > * { margin-left: auto; margin-right: auto; }
.closer h2 { display: block; text-align: center; text-transform: uppercase; letter-spacing: .02em; color: #FFFFFF; font-size: clamp(1.5rem, 3.2vw, 2.4rem); max-width: 22ch; margin: 0 auto 1.1rem; }
.closer h2::after { display: none; }
.closer p { color: #C6D2E2; max-width: 56ch; }
.closer .actions { justify-content: center; }
.closer .action { background: var(--signal); color: var(--ink); border-color: var(--signal); }
.closer .action:hover { background: #FFFFFF; color: var(--navy); border-color: #FFFFFF; }

/* Actions were a plain block; make them a proper row that can be centred. */
.actions { display: flex; flex-wrap: wrap; gap: .85rem; }

/* A centred heading with a hard character cap orphans its last word. Balance
   the wrap and give it room. */
.intro h2, .band.centred h2, .closer h2 { max-width: 28ch; text-wrap: balance; }
.intro h2 { margin-bottom: 1.35rem; }
.intro .lede { max-width: 58ch; }

/* Wrapping a section's contents in .wrap broke two things at once, both of my
   own making:
   1. The ruled heading selector was "section > h2", and the heading is now a
      grandchild. Match both depths.
   2. .tint used the margin shorthand, which reset the inline margins .bleed
      depends on, so the tint stopped at the text column instead of the
      viewport edge. Exactly the trap .pagehead fell into earlier. */
section > h2, section > .wrap > h2 {
  display: flex; align-items: center; gap: 1.25rem;
  text-transform: uppercase; font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  letter-spacing: .075em; color: var(--navy); line-height: 1.25;
}
section > .wrap > h2::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--rule); min-width: 2rem;
}
.tint > .wrap > h2::after { background: var(--rule); }

.tint { margin: 0; margin-block: clamp(2.5rem, 5vw, 4rem); margin-inline: calc(50% - 50vw); }

/* The intro and the centred bands opt out of the ruled treatment entirely. */
.intro > .wrap > h2, .band.centred > .wrap > h2, .closer > .wrap > h2 { display: block; }
.intro > .wrap > h2::after, .band.centred > .wrap > h2::after, .closer > .wrap > h2::after { display: none; }
.closer > .wrap { text-align: center; }
.closer > .wrap > h2 { text-align: center; margin-left: auto; margin-right: auto; }
.closer > .wrap > p { margin-left: auto; margin-right: auto; }
.closer > .wrap > .actions { justify-content: center; }

/* The intro heading was rendering at the ruled-label size, 21.6px, because the
   ruled selector and the intro selector were fighting. Set the centred
   headings at a specificity nothing else in the sheet reaches, so this cannot
   drift again. */
.intro > .wrap > h2 {
  font-size: clamp(1.6rem, 3.4vw, 2.6rem);
  line-height: 1.18;
  max-width: 34ch;
  margin: 0 auto 1.4rem;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--navy);
}
.band.centred > .wrap > h2, .closer > .wrap > h2 {
  font-size: clamp(1.6rem, 3.4vw, 2.5rem);
  line-height: 1.2;
  max-width: 30ch;
  margin: 0 auto 1.15rem;
  text-transform: uppercase;
  letter-spacing: .02em;
}

/* ===========================================================================
   BACK TO THE INTERIOR PAGE MODEL

   The reference page JT is working from is the programme page, not their
   homepage. Its opening is ranged LEFT inside the body column with the fact
   panel beside it. Centring was borrowed from their homepage and is wrong
   here, so it comes back out.

   Also fixes a real defect: the ruled heading rule set color:var(--navy), and
   it was winning on the closer, which has a navy ground. Navy on navy is a
   contrast ratio of 1.00. The heading was invisible.
   =========================================================================== */

.intro { background: var(--paper); padding: clamp(2.25rem, 4vw, 3.25rem) 0 0; margin: 0; }
.intro > .wrap { text-align: left; }
.intro > .wrap > h2 {
  text-align: left; margin: 0 0 1.15rem; max-width: 26ch;
  font-size: clamp(1.35rem, 2.4vw, 1.95rem);
}
.intro .eyebrow { color: var(--signal-ink); letter-spacing: .17em; }
.intro p { margin-left: 0; margin-right: 0; text-align: left; max-width: var(--measure); }
.intro .actions { justify-content: flex-start; }

/* Any heading on a dark ground stays white, whatever else claims it. */
.closer h2, .closer > .wrap > h2,
.band h2, .band > .wrap > h2,
.pagehead h2, .sidebar h2, .callout h2 { color: #FFFFFF; }
.closer > .wrap > h2::after, .band > .wrap > h2::after { background: rgba(255,255,255,.3); }

/* The facts strip was built for full page width. Inside the body column four
   abreast is cramped, so let it wrap. */
.layout .facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0; }
.layout .facts > div { padding: 1.15rem 1.15rem 1.15rem 0; border-right: 1px solid var(--rule-soft); }
.layout .facts > div:last-child { border-right: 0; }
@media (max-width: 620px) { .layout .facts { grid-template-columns: 1fr 1fr; } }

/* Covers sit two abreast in the column too. */
.layout .covers { grid-template-columns: repeat(auto-fit, minmax(150px, 200px)); }

/* A grid item defaults to min-width:auto, so a wide child can push the panel
   past its column. On phones that made the fact panel overhang the page. */
.layout > .body, .layout > .sidebar { min-width: 0; }
.sidebar { box-sizing: border-box; max-width: 100%; }
.sidebar dd, .sidebar dt, .sidebar p { overflow-wrap: anywhere; }
@media (max-width: 900px) { .layout > .sidebar { width: 100%; } }

/* ============================================================
   LAYER 29 - Reference alignment: font, style, layout.

   Measured off the Kingster BSBA interior page at a 1287px
   viewport, because that is the page JT pointed at:

     display face   LeBeauneNew, a caps-only Trajan-style serif
     text face      Jost
     h1             48 / 57.6 / 700 / white
     eyebrow        21px, blue, sentence case, not tracked caps
     body           16 / 27.2 / #6B6B6B
     section title  27px / 600 / #161616, no underline rule
     hero banner    782px tall, photograph clearly readable
     grid           781 body + 20 gap + 411 sidebar = 1212
     gutter         40px in from the viewport edge
     bands          navy, footer darker than the bands
     section pad    90/60, 95/45, 65/60

   LeBeauneNew is licensed. Cinzel is the closest free equivalent:
   same Trajan lineage, same caps-only behaviour, on Google Fonts so
   it loads for every visitor. Jost is an exact match and also free.

   The accent moves from orange to the reference blue. Two bright
   accents fight each other; the brick red in the mark is a logo
   spot colour and is left alone. The blue is set at #0063C6 rather
   than the reference #0082FA because #0082FA carries white at only
   3.4:1 and we put white on it in buttons. #0063C6 reads as the
   same blue and holds white at 5.5:1.
   ============================================================ */

:root {
  --ui: "Jost", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --display: "Cinzel", "Iowan Old Style", Georgia, "Times New Roman", serif;

  --ink: #161616;
  --ink-soft: #6B6B6B;
  --ink-faint: #8A8A8A;
  --rule: #E4E7EC;
  --rule-soft: #F1F3F6;
  --paper: #FFFFFF;
  --paper-warm: #F4F4F4;
  --navy: #223D71;
  --navy-deep: #16233B;
  --signal: #0063C6;
  --signal-ink: #0063C6;
  --signal-lift: #7FC0FF;
  --gutter: 40px;
}

body {
  font-family: var(--ui);
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink-soft);
  -webkit-font-smoothing: antialiased;
}

/* Their container is the viewport less a 40px gutter, capped so the
   measure never runs away on a wide monitor. */
.wrap {
  max-width: calc(1212px + 2 * var(--gutter));
  padding-inline: var(--gutter);
}

/* ---- display face -------------------------------------------------- */
h1, h2, h3, h4, h5, h6, .wordmark .initials, .wordmark .full {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .045em;
  color: var(--ink);
  line-height: 1.22;
  font-style: normal;
}
h1 { font-size: clamp(1.85rem, 4vw, 3rem); line-height: 1.2; letter-spacing: .02em; }
h2 { font-size: clamp(1.35rem, 2.3vw, 1.7rem); }
h3 { font-size: 1.0625rem; font-weight: 600; letter-spacing: .075em; }
h4, h5, h6 { font-size: .9375rem; font-weight: 600; letter-spacing: .075em; }

p, li, dd, dt, td, th, figcaption, blockquote, label, input, button, select {
  font-family: var(--ui);
}
p, li, dd { font-size: 1rem; line-height: 1.7; color: var(--ink-soft); }
.lede { font-size: 1.25rem; line-height: 1.6; font-weight: 300; color: var(--ink); font-style: normal; }
strong, b { color: var(--ink); font-weight: 600; }

/* Their eyebrow is a plain blue sentence, not tracked-out caps. */
.eyebrow {
  font-family: var(--ui);
  font-size: 1.25rem;
  line-height: 1.45;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--signal-ink);
  margin-bottom: .55em;
}
.pagehead .eyebrow, .closer .eyebrow { color: var(--signal-lift); }

/* ---- hero ----------------------------------------------------------- */
.pagehead {
  min-height: clamp(320px, 46vw, 640px);
  background-image:
    linear-gradient(92deg, rgba(12,24,45,.88) 0%, rgba(12,24,45,.72) 40%, rgba(12,24,45,.42) 78%, rgba(12,24,45,.34) 100%),
    url("/assets/img/banner-board-2000.jpg");
  background-size: cover, cover;
  background-position: center, 62% center;
  background-repeat: no-repeat, no-repeat;
}
.pagehead > .wrap {
  padding-top: clamp(3.5rem, 8vw, 7rem);
  padding-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.pagehead h1 { color: #FFFFFF; max-width: 18em; }

/* ---- section rhythm -------------------------------------------------- */
.intro { padding-top: 90px; padding-bottom: 60px; }
.closer { padding-top: 95px; padding-bottom: 90px; }
.band { padding-top: 65px; padding-bottom: 60px; }

/* Their section titles carry no underline. The hr.rule between our
   sections already does that job, and doing both reads as clutter. */
.layout .body > section > h2,
.intro > h2,
section > .wrap > h2 {
  border-bottom: 0;
  padding-bottom: 0;
  margin-bottom: 1.5rem;
}

/* ---- body / sidebar grid -------------------------------------------- */
@media (min-width: 62rem) {
  .layout {
    grid-template-columns: minmax(0, 1fr) 400px;
    gap: 20px;
  }
}
.sidebar { background: var(--navy); }
.sidebar h2, .sidebar h3 { color: #FFFFFF; }

/* ---- buttons --------------------------------------------------------- */
.action {
  font-family: var(--ui);
  font-size: .9375rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: none;
  border-radius: 0;
  padding: 1.05rem 1.9rem;
}

/* ---- chrome ---------------------------------------------------------- */
.masthead nav a { font-family: var(--ui); letter-spacing: .04em; }
.wordmark .initials { letter-spacing: .08em; }
footer { background: var(--navy-deep); }

/* Anything sitting on a dark ground keeps a white heading. Learned the
   hard way when the ruled-heading rule pinned navy type onto navy. */
.pagehead h1, .pagehead h2, .pagehead h3,
.closer h1, .closer h2, .closer h3,
.sidebar h2, .sidebar h3,
footer h2, footer h3, footer h4 { color: #FFFFFF; }

/* --- layer 30: corrections found on screen -------------------------------
   1. The filled button inherited --ink for its label, which was tolerable
      when --ink was near-black on orange and is not on blue. White it.
   2. The intro now sits in the body column on the homepage, matching the
      reference, so it must not carry its own band padding or gutter.
   3. The headline was allowed 18em and ran into the bright window in the
      photograph. 15em keeps it over the dense side of the frame, and the
      right end of the scrim comes down so white type never sits on glass.
   ------------------------------------------------------------------------ */

.action:not(.action-secondary) { color: #FFFFFF; border-color: var(--signal); }
.action:not(.action-secondary):hover { background: #004E9E; border-color: #004E9E; color: #FFFFFF; }

.layout .body > .intro {
  padding: 0;
  margin: 0 0 2.75rem;
  background: transparent;
}
.layout .body > .intro > .eyebrow { margin-top: 0; }

.pagehead {
  background-image:
    linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%),
    url("/assets/img/banner-board-2000.jpg");
}
.pagehead h1 { max-width: 15em; }

/* --- layer 31: weight, buttons, bands ------------------------------------
   LeBeauneNew is a light-stroked Trajan face, so its 700 still reads as a
   normal-weight inscriptional cap. Cinzel 700 is genuinely heavy and came
   out looking like a headline in a tabloid. The display face drops to 400
   at large sizes and only firms up at label sizes where it has to.

   Buttons copy the reference exactly: Jost 15/25.5 at weight 700, white on
   blue, 16/27/18 padding, 2px radius. The blue is #0063C6 rather than their
   #0082FA only because white on #0082FA is 3.4:1 and ours carries labels.

   Their page alternates full-width bands: white, then light grey, then
   navy, each on the 90/60 rhythm. Ours ran white the whole way down, which
   is why it read as one long column of text.
   ------------------------------------------------------------------------ */

h1, h2 { font-weight: 400; }
h3 { font-weight: 600; }
.pagehead h1 { font-weight: 400; letter-spacing: .03em; }
.intro > h2, .layout .body > section > h2, section > .wrap > h2 { font-weight: 400; }

.action, .btn {
  font-family: var(--ui);
  font-size: 15px;
  line-height: 25.5px;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: none;
  padding: 16px 27px 18px;
  border-radius: 2px;
}
.action:not(.action-secondary), .btn:not(.ghost) {
  background: var(--signal);
  border-color: var(--signal);
  color: #FFFFFF;
}
.action:not(.action-secondary):hover, .btn:not(.ghost):hover {
  background: #004E9E; border-color: #004E9E; color: #FFFFFF;
}
.action-secondary { color: var(--ink); border-color: #C9CED6; background: transparent; }
.action-secondary:hover { border-color: var(--signal); color: var(--signal); background: transparent; }

/* Full-width alternating bands, on their rhythm. */
.tint, .band, .features, .steps, .covers, .showcase {
  padding-top: 90px;
  padding-bottom: 60px;
}
.tint { background: #EDEDED; }
.band { background: var(--navy); color: #FFFFFF; }
.band p, .band li, .band dd { color: #D6DEEB; }
.closer { background: var(--navy); color: #FFFFFF; }
.closer p, .closer .lede { color: #D6DEEB; }

/* --- layer 32: the intro reads as body copy now ---------------------------
   It used to be a centred full-width band, so it was styled as one. Now
   that it sits in the body column beside the sidebar, the centring and the
   tracked-out eyebrow are wrong: the reference page runs everything in that
   column hard left. The .layout .body prefix is there because plain
   .eyebrow lost to the column's own paragraph rules once it moved inside.
   ------------------------------------------------------------------------ */

.layout .body > .intro,
.layout .body > .intro > * {
  text-align: left;
  margin-inline: 0;
}
.layout .body > .intro > h2 { max-width: 20ch; }
.layout .body .eyebrow,
.layout .body > .intro > .eyebrow {
  font-family: var(--ui);
  font-size: 1.25rem;
  line-height: 1.45;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--signal-ink);
}
.layout .body > .intro > .actions { justify-content: flex-start; }

/* --- layer 33: section titles to the measured size ------------------------
   Ours were running at 40px against the reference's 27px, which is why our
   pages read as a stack of headlines rather than a document. 27/32.4 is
   taken straight off their section titles. The sidebar heading needed its
   own line because an earlier rule named .sidebar h2 directly and kept the
   old serif at 16px.
   ------------------------------------------------------------------------ */

.layout .body > section > h2,
.layout .body > .intro > h2,
section > .wrap > h2,
.closer > .wrap > h2,
.band > .wrap > h2 {
  font-family: var(--display);
  font-size: 27px;
  line-height: 32.4px;
  font-weight: 400;
  letter-spacing: .045em;
  max-width: 30ch;
}
.layout .body > .intro > h2 { max-width: 26ch; }

.sidebar h2, .sidebar > h2 {
  font-family: var(--display);
  font-size: 20px;
  line-height: 24px;
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #FFFFFF;
}

.lede { font-size: 20px; line-height: 32px; }

/* --- layer 34: --ink-faint had to give ------------------------------------
   #8A8A8A is what the reference uses for de-emphasised meta lines, but it
   only clears AA there because their meta sits at larger sizes. Ours runs
   at 13 to 14px in prices, volume numbers and disclosures, where #8A8A8A
   lands at 3.45:1 on white and 3.14:1 on the grey band. 33 elements failed.
   #616161 holds 6.0:1 on white and 5.2:1 on the band and still reads as a
   step down from the body grey.
   ------------------------------------------------------------------------ */

:root { --ink-faint: #616161; }

/* --- layer 35: measure ----------------------------------------------------
   38rem was set when the body column was the whole page and a long line
   would have been unreadable. The column is now 772px, the same as the
   reference's 781px, and their paragraphs run the full width of it at
   703 to 743px. Ours were stopping at 608px and leaving a ragged empty
   strip down the middle of the page.
   ------------------------------------------------------------------------ */

:root { --measure: 45rem; }

/* --- layer 36: dark grounds ----------------------------------------------
   Retokenising broke every element that had been given a light-ground
   colour by name. strong went to #161616 and landed on navy at 1.15:1,
   the eyebrow to #0063C6 at 1.82:1, the outline button to a near-black
   label at 3.10:1, and the sidebar term labels sat at 4.08:1. Everything
   sitting on a dark ground is pinned here in one place so the next token
   change cannot quietly do it again.
   ------------------------------------------------------------------------ */

.pagehead strong, .pagehead b, .closer b, .band b, .sidebar b, footer b,
.closer strong, .pagehead b, .closer b, .band b, .sidebar b, footer b,
.band strong, .pagehead b, .closer b, .band b, .sidebar b, footer b,
.sidebar strong, .pagehead b, .closer b, .band b, .sidebar b, footer b,
footer strong, .pagehead b, .closer b, .band b, .sidebar b, footer b {
  color: #FFFFFF;
}
.pagehead .eyebrow,
.closer .eyebrow,
.band .eyebrow,
.sidebar .eyebrow,
footer .eyebrow {
  color: var(--signal-lift);
}
.pagehead dt,
.closer dt,
.band dt,
.sidebar dt,
footer dt {
  color: #C6D3E6;
}
.pagehead dd,
.closer dd,
.band dd,
.sidebar dd,
footer dd {
  color: #E3EAF4;
}
.pagehead figcaption,
.closer figcaption,
.band figcaption,
.sidebar figcaption,
footer figcaption {
  color: #C6D3E6;
}
.pagehead .action-secondary,
.closer .action-secondary,
.band .action-secondary,
.sidebar .action-secondary,
footer .action-secondary {
  color: #FFFFFF;
  border-color: rgba(255,255,255,.55);
  background: transparent;
}
.pagehead .action-secondary:hover,
.closer .action-secondary:hover,
.band .action-secondary:hover,
.sidebar .action-secondary:hover,
footer .action-secondary:hover {
  color: #FFFFFF;
  border-color: #FFFFFF;
  background: rgba(255,255,255,.10);
}
figcaption { color: var(--ink-soft); }
.layout .body figcaption { color: var(--ink-soft); }

/* --- layer 37: the last four, and why they survived layer 36 --------------
   Layer 36 set .band .eyebrow and .band figcaption correctly and then two
   lines later reset figcaption globally, and layer 32 had already claimed
   .layout .body .eyebrow at a higher specificity. Both dark-ground rules
   lost on specificity, not on order. These carry the .layout .body prefix
   so they outrank the rules that were beating them. .release is a dark
   block too and was simply missing from the list.
   ------------------------------------------------------------------------ */

.layout .body .band .eyebrow,
.layout .body .closer .eyebrow,
.layout .body .release .eyebrow { color: var(--signal-lift); }

.layout .body .band figcaption,
.layout .body .closer figcaption,
.layout .body .release figcaption { color: #C6D3E6; }

.release strong, .release b { color: #FFFFFF; }
.release p, .release li { color: #D6DEEB; }
.release dt { color: #C6D3E6; }
.release dd { color: #E3EAF4; }
.release .action-secondary { color: #FFFFFF; border-color: rgba(255,255,255,.55); }

/* --- layer 38: one footer, everywhere -------------------------------------
   The public pages and the portal had two different footers, and neither
   carried the mark. This is the reference's footer grammar: a brand block
   with the mark and the full name, three link columns under caps display
   headings, and a rule with the legal line beneath. Every page now ships
   the same markup, so the only place it can drift is here.

   Ground is #16233B, a step darker than the navy bands, which is the same
   relationship the reference uses. Every colour on it was checked: the
   lightest link text sits at 9.9:1 and the faintest legal line at 5.8:1.
   ------------------------------------------------------------------------ */

footer {
  background: var(--navy-deep);
  color: #C9D3E2;
  padding-top: 75px;
  padding-bottom: 26px;
}
footer .wrap { max-width: calc(1212px + 2 * var(--gutter)); }

.foot-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) repeat(3, minmax(0, 1fr));
  gap: 40px;
  align-items: start;
}

.footmark {
  display: flex;
  align-items: center;
  gap: .75rem;
  color: #FFFFFF;
  text-decoration: none;
  margin: 0 0 1.5rem;
}
.footmark .mark { width: 44px; height: 44px; flex: none; color: #FFFFFF; }
.footmark .initials {
  display: block;
  font-family: var(--display);
  font-size: 19px;
  line-height: 1.1;
  letter-spacing: .12em;
  color: #FFFFFF;
}
.footmark .full {
  display: block;
  font-family: var(--display);
  font-size: 10px;
  line-height: 1.45;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #9FB0C8;
  margin-top: .3rem;
}
.footmark:hover .full { color: #C9D3E2; }

.foot-brand p {
  font-size: 15px;
  line-height: 1.65;
  color: #B9C6D8;
  max-width: 36ch;
  margin: 0 0 .75rem;
}

.foot-col h2 {
  font-family: var(--display);
  font-size: 17px;
  line-height: 20.4px;
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #FFFFFF;
  margin: 0 0 1.15rem;
  border: 0;
  padding: 0;
}
.foot-col ul { list-style: none; margin: 0; padding: 0; }
.foot-col li { margin: 0 0 .7rem; }
.foot-col a, .foot-brand a {
  color: #C9D3E2;
  font-size: 15px;
  line-height: 1.6;
  text-decoration: none;
  border: 0;
}
.foot-col a:hover, .foot-brand a:hover { color: #FFFFFF; text-decoration: underline; }

.foot-base {
  margin-top: 56px;
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, .14);
  display: flex;
  flex-wrap: wrap;
  gap: 14px 40px;
  justify-content: space-between;
  align-items: baseline;
}
.foot-base p { font-size: 13.5px; line-height: 1.65; color: #93A3B9; margin: 0; max-width: 78ch; }
.foot-legal { white-space: nowrap; }

@media (max-width: 62rem) {
  .foot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px; }
  .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 34rem) {
  .foot-grid { grid-template-columns: minmax(0, 1fr); }
  footer { padding-top: 56px; }
}

/* --- layer 39: the footer, stated once and decisively ---------------------
   Layer 38 was correct and still lost. footer .wrap had been display:flex
   since the first stylesheet, so the four column grid was being squeezed
   into one flex child while .foot-base sat beside it as the other, and an
   older navy-footer layer was still forcing links to tracked-out caps.

   Everything below carries a body prefix so it outranks every earlier
   footer rule in this file rather than tying with it, and every property
   those older rules set is restated here rather than left to chance. If
   the footer needs changing again, change it here and nowhere else.
   ------------------------------------------------------------------------ */

body footer {
  background: var(--navy-deep);
  color: #C9D3E2;
  border: 0;
  border-top: 0;
  margin-top: 0;
  padding: 75px 0 26px;
}
body footer .wrap {
  display: block;
  max-width: calc(1212px + 2 * var(--gutter));
  padding-inline: var(--gutter);
  gap: 0;
}

body footer .foot-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) repeat(3, minmax(0, 1fr));
  gap: 40px;
  align-items: start;
}

body footer .footmark {
  display: flex;
  align-items: center;
  gap: .75rem;
  color: #FFFFFF;
  text-decoration: none;
  margin: 0 0 1.5rem;
}
body footer .footmark .mark { width: 44px; height: 44px; flex: none; color: #FFFFFF; }
body footer .footmark .initials {
  display: block; font-family: var(--display); font-size: 19px; line-height: 1.1;
  letter-spacing: .12em; font-weight: 400; text-transform: uppercase; color: #FFFFFF;
}
body footer .footmark .full {
  display: block; font-family: var(--display); font-size: 10px; line-height: 1.45;
  letter-spacing: .09em; font-weight: 400; text-transform: uppercase; color: #9FB0C8; margin-top: .3rem;
}
body footer .footmark:hover .full { color: #C9D3E2; }

body footer .foot-brand p {
  font-family: var(--ui); font-size: 15px; line-height: 1.65; font-weight: 400;
  letter-spacing: normal; text-transform: none; color: #B9C6D8; max-width: 36ch; margin: 0 0 .75rem;
}

body footer .foot-col h2 {
  font-family: var(--display); font-size: 17px; line-height: 20.4px; font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: #FFFFFF;
  margin: 0 0 1.15rem; border: 0; padding: 0; max-width: none;
}
body footer .foot-col ul { list-style: none; margin: 0; padding: 0; display: block; columns: auto; }
body footer .foot-col li {
  margin: 0 0 .7rem; padding: 0; font-family: var(--ui); font-size: 15px;
  line-height: 1.6; font-weight: 400; letter-spacing: normal; text-transform: none; color: #C9D3E2;
}
body footer .foot-col li::before { content: none; }
body footer a {
  font-family: var(--ui); font-size: 15px; line-height: 1.6; font-weight: 400;
  letter-spacing: normal; text-transform: none; color: #C9D3E2;
  text-decoration: none; border: 0; background: none; padding: 0;
}
body footer a:hover { color: #FFFFFF; text-decoration: underline; text-decoration-color: currentColor; }
body footer .footmark, body footer .footmark:hover { text-decoration: none; }

body footer .foot-base {
  margin-top: 56px;
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, .14);
  display: flex;
  flex-wrap: wrap;
  gap: 14px 40px;
  justify-content: space-between;
  align-items: baseline;
}
body footer .foot-base p {
  font-family: var(--ui); font-size: 13.5px; line-height: 1.65; font-weight: 400;
  letter-spacing: normal; text-transform: none; color: #93A3B9; margin: 0; max-width: 78ch;
}
body footer .foot-legal { white-space: nowrap; }

@media (max-width: 62rem) {
  body footer .foot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px; }
  body footer .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 34rem) {
  body footer .foot-grid { grid-template-columns: minmax(0, 1fr); }
  body footer { padding-top: 56px; }
  body footer .foot-legal { white-space: normal; }
}

/* --- layer 40: tables -----------------------------------------------------
   Taken off the reference's admissions table: border-collapse separate with
   a hairline gap so white gridlines show between cells, a solid accent
   header row in white Jost, grey body cells, and real padding. Measured
   there as 13px on the header and 15px on the body cells, Jost 16/27.2.

   Two deliberate departures.

   Theirs centres every cell. Theirs holds dates. Ours holds sentences like
   'How work is designed, sequenced and changed', and centred sentences are
   hard to read, so ours align left. The chrome is theirs; the alignment
   follows the content.

   Their body text is #949494 on grey, which is 2.6:1. On our #F1F3F6 cells
   the body grey lands at 4.45:1, still short, so cell text is #5C5C5C at
   5.6:1. It reads as the same grey.

   Written against 'main table' rather than the two .comparison tables that
   exist today, so any table added later is styled without anyone
   remembering to come back here.
   ------------------------------------------------------------------------ */

.tablewrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 2rem 0 2.5rem;
}

body main table {
  width: 100%;
  margin: 0;
  border: 0;
  border-collapse: separate;
  border-spacing: 2px;
  background: #FFFFFF;
  font-family: var(--ui);
  font-size: 16px;
  line-height: 27.2px;
}

body main table th {
  background: var(--navy);
  color: #FFFFFF;
  font-family: var(--ui);
  font-size: 16px;
  line-height: 27.2px;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
  vertical-align: middle;
  padding: 13px 20px;
  border: 0;
}

body main table td {
  background: #F1F3F6;
  color: #5C5C5C;
  font-family: var(--ui);
  font-size: 16px;
  line-height: 27.2px;
  font-weight: 400;
  text-align: left;
  vertical-align: top;
  padding: 15px 20px;
  border: 0;
}
body main table td:first-child { color: var(--ink); font-weight: 500; }
body main table tbody tr:hover td { background: #E7EBF1; }
body main table tbody th[scope="row"] { background: #E3E8EF; color: var(--ink); font-weight: 600; }

body main table caption {
  caption-side: top;
  text-align: left;
  font-family: var(--ui);
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-faint);
  padding: 0 0 .85rem;
}

/* On a dark band the header row would vanish into it, so it lifts to white
   type on navy and the cells go a shade of the band rather than page grey. */
.band table th, .closer table th, .release table th { background: #0A4E9E; }
.band table td, .closer table td, .release table td { background: #1B3560; color: #DCE4F0; }
.band table td:first-child, .closer table td:first-child, .release table td:first-child { color: #FFFFFF; }
.band table, .closer table, .release table { background: var(--navy); }

@media (max-width: 40rem) {
  body main table th, body main table td { padding: 12px 14px; }
  body main table { font-size: 15px; line-height: 25px; }
}

/* --- layer 41: .comparison outranked the table rules ----------------------
   The header row came back navy and tracked-out caps because an older
   table.comparison thead th rule carries a class and beat body main table
   th on specificity. Same lesson as the footer: writing the rule later in
   the file does not help if the older one is more specific. These carry
   both the body main prefix and the class.

   Header goes to the accent blue rather than staying navy, because the
   accent header row is the thing that makes the reference's tables read as
   designed rather than defaulted, and white on #0063C6 is 5.5:1.
   ------------------------------------------------------------------------ */

body main table.comparison,
body main table.comparison thead,
body main table.comparison tbody { border: 0; }

body main table.comparison thead th,
body main table.comparison th {
  background: var(--signal);
  color: #FFFFFF;
  font-family: var(--ui);
  font-size: 16px;
  line-height: 27.2px;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
  vertical-align: middle;
  padding: 13px 20px;
  border: 0;
}

body main table.comparison td {
  background: #F1F3F6;
  color: #5C5C5C;
  font-family: var(--ui);
  font-size: 16px;
  line-height: 27.2px;
  font-weight: 400;
  text-align: left;
  vertical-align: top;
  padding: 15px 20px;
  border: 0;
}
body main table.comparison td:first-child { color: var(--ink); font-weight: 500; }
body main table.comparison tbody tr:hover td { background: #E7EBF1; }

/* --- layer 42: display weight, one step up --------------------------------
   700 was too heavy, 400 too quiet. 500 is the middle: the caps still read
   as inscriptional rather than as a headline, but they carry enough weight
   to separate from the body grey around them.
   ------------------------------------------------------------------------ */

h1, h2 { font-weight: 500; }
.pagehead h1 { font-weight: 500; }
.intro > h2,
.layout .body > section > h2,
.layout .body > .intro > h2,
section > .wrap > h2,
.closer > .wrap > h2,
.band > .wrap > h2 { font-weight: 500; }
.sidebar h2, .sidebar > h2 { font-weight: 500; }
body footer .foot-col h2 { font-weight: 500; }
body footer .footmark .initials { font-weight: 500; }

/* --- layer 43: image tiles ------------------------------------------------
   The reference's MAJORS strip: a photograph under a heavy flat blue, with
   a centred white caps label on top. It is what breaks their long pages
   into sections that can be scanned rather than read.

   Built with background-blend-mode: luminosity, so the photograph keeps its
   light and shade but takes the accent blue's hue. That is a true duotone
   rather than a photo with a blue sheet over it, and it means eight
   different photographs still read as one set.

   The scrim over the top is at .76. That number is not taste. Luminosity
   blending can push a bright region of a photograph to roughly 0.60
   relative luminance, where white type would sit at 3.45:1 and fail. At
   .76 the worst case lands near 4.8:1 and the photograph is still visible,
   which is exactly how much of it shows on the reference.

   Ours carry a line of description under the label where theirs carry only
   a label, because the eight domain definitions are the substance of that
   section and a tile strip that dropped them would be decoration.
   ------------------------------------------------------------------------ */

.cards.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  margin: 2rem 0 2.5rem;
}

body .cards.tiles > .card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 232px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 30px 26px;
  border: 0;
  border-radius: 2px;
  background-color: var(--signal);
  background-image: var(--shot, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-blend-mode: luminosity;
}
body .cards.tiles > .card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(4, 44, 92, .76);
  transition: background .25s ease;
}
body .cards.tiles > a.card:hover::before { background: rgba(4, 44, 92, .62); }

body .cards.tiles > .card h3 {
  font-family: var(--display);
  font-size: 19px;
  line-height: 1.25;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #FFFFFF;
  margin: 0;
  max-width: 15ch;
}
body .cards.tiles > .card p {
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1.6;
  font-weight: 400;
  color: #FFFFFF;
  margin: .85rem 0 0;
  max-width: 30ch;
}
body .cards.tiles > a.card { text-decoration: none; }

@media (max-width: 34rem) {
  .cards.tiles { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  body .cards.tiles > .card { min-height: 190px; }
}

/* --- layer 44: tile labels must not break mid-word -------------------------
   'ROLE DESIGN AND ACCOUNTABILI / TY'. An earlier global overflow-wrap rule
   was breaking inside words, which is invisible in body copy and glaring in
   a 19px tracked cap. Wrapping is reset to word boundaries and the label
   steps down a point so the longest domain names fit on their own lines.
   ------------------------------------------------------------------------ */

body .cards.tiles > .card h3 {
  overflow-wrap: normal;
  word-break: normal;
  word-wrap: normal;
  hyphens: none;
  font-size: 18px;
  letter-spacing: .05em;
  max-width: 100%;
}
body .cards.tiles > .card p { overflow-wrap: normal; word-break: normal; }
.cards.tiles { grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); }

/* --- layer 45: a banner per page ------------------------------------------
   Every page shared one boardroom photograph, which was the most obvious
   remaining tell that the site was one template repeated. Each section now
   has its own, matched in palette and treatment so they still read as one
   set: the scrim, the crop and the type are unchanged.

   Keyed off the body class rather than per-page inline styles, so the
   banner for a section lives in one place and a new page in that section
   inherits it.
   ------------------------------------------------------------------------ */

body[data-page="certification"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-certification-2000.jpg"); }
body[data-page="standard"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-standard-2000.jpg"); }
body[data-page="registry"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-registry-2000.jpg"); }
/* The directory sits beside the register in the same menu, so it must not wear
   the same picture. Filing cabinets are the right image for a record you look
   a number up in. An atrium is the right one for a list of people who chose to
   be found. */
body[data-page="directory"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-atrium-2000.jpg"); }
body[data-page="verify"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-verify-2000.jpg"); }
body[data-page="qualify"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-qualify-2000.jpg"); }
body[data-page="contribute"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-contribute-2000.jpg"); }
body[data-page="about"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-about-2000.jpg"); }
body[data-page="books"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-books-2000.jpg"); }
body[data-page="faq"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-faq-2000.jpg"); }
body[data-page="endorsements"] .pagehead { background-image: linear-gradient(92deg, rgba(12,24,45,.90) 0%, rgba(12,24,45,.78) 38%, rgba(12,24,45,.60) 72%, rgba(12,24,45,.52) 100%), url("/assets/img/banner-endorsements-2000.jpg"); }

/* --- layer 46: the tile treatment on .features and link cards --------------
   Same component, two more shapes. .features carries a designation label
   above the title and a linked title; a.card is a whole tile that links.
   Everything inside a tile goes white, including the link, because a blue
   link on a blue tile is invisible.
   ------------------------------------------------------------------------ */

.features.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
  gap: 20px;
  margin: 2rem 0 2.5rem;
  list-style: none;
  padding: 0;
}

body .features.tiles > .feature {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 262px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 30px 24px;
  border: 0;
  border-radius: 2px;
  background-color: var(--signal);
  background-image: var(--shot, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-blend-mode: luminosity;
}
body .features.tiles > .feature::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(4, 44, 92, .78);
  transition: background .25s ease;
}
body .features.tiles > .feature:hover::before { background: rgba(4, 44, 92, .66); }

body .features.tiles > .feature .n {
  display: block;
  font-family: var(--ui);
  font-size: 13px;
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #BFD9F7;
  margin: 0 0 .7rem;
  background: none;
  border: 0;
  padding: 0;
}
body .features.tiles > .feature h3 {
  font-family: var(--display);
  font-size: 18px;
  line-height: 1.25;
  font-weight: 500;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #FFFFFF;
  margin: 0;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}
body .features.tiles > .feature h3 a,
body .features.tiles > .feature a {
  color: #FFFFFF;
  text-decoration: none;
  border: 0;
}
body .features.tiles > .feature h3 a:hover { text-decoration: underline; text-decoration-color: currentColor; }
body .features.tiles > .feature p {
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1.6;
  color: #FFFFFF;
  margin: .85rem 0 0;
  max-width: 32ch;
  overflow-wrap: normal;
  word-break: normal;
}

@media (max-width: 34rem) {
  .features.tiles { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  body .features.tiles > .feature { min-height: 210px; }
}

/* --- layer 47: the certificate band is one block, not two columns ----------
   .showcase was a two column grid from when it sat across the full page.
   Inside a 772px body column it gave the specimen about 340px and the copy
   about 380px, and neither had room. It stacks now: the argument first at
   full width, then the specimen under it at full width, which is also the
   order somebody reads it in.
   ------------------------------------------------------------------------ */

.layout .body .showcase,
.band .showcase {
  display: flex;
  flex-direction: column;
  gap: 1.9rem;
  align-items: stretch;
}
.layout .body .showcase > div,
.band .showcase > div { order: 1; max-width: 62ch; }
.layout .body .showcase > .frame,
.band .showcase > .frame { order: 2; margin: 0; width: 100%; }
.layout .body .showcase > .frame img,
.band .showcase > .frame img { width: 100%; height: auto; display: block; }

/* --- layer 48: the price line inside a tile --------------------------------
   .price was styled for a white card and lands on the tile as faint grey on
   blue. Inside a tile it goes white, with the figure lifted.
   ------------------------------------------------------------------------ */

body .cards.tiles > .card .price { color: #DCE9F9; font-size: 14px; margin-top: .9rem; }
body .cards.tiles > .card .price b { color: #FFFFFF; font-weight: 600; }

/* --- layer 49: the band needs its own gutter -------------------------------
   .band bleeds past the body column, so without inline padding its content
   starts exactly on the band edge and the first letter of the heading gets
   clipped. It carries the page gutter now, like every other full width
   element.
   ------------------------------------------------------------------------ */

.layout .body > .band,
.layout .body .band { padding-inline: var(--gutter); }
@media (max-width: 40rem) {
  .layout .body > .band, .layout .body .band { padding-inline: 22px; }
}

/* --- layer 50: double padding in the certificate band ----------------------
   .showcase was given the 90/60 band rhythm back in layer 31, when it was
   its own full width section. It now sits inside .band, which already has
   90/60, so the two stacked and left 180px of empty navy above the
   eyebrow. That dead space, not the alignment, is what made the section
   look unresolved. The rhythm belongs to the band; the showcase is just
   its content.

   The designation label on the endorsement tiles was #BFD9F7, which is
   4.02:1 against the accent. #E3EFFC clears AA and still reads as a
   quieter step below the title.
   ------------------------------------------------------------------------ */

.band .showcase,
.layout .body .band .showcase { padding: 0; margin: 0; }
.layout .body .showcase > div, .band .showcase > div { max-width: 60ch; }

body .features.tiles > .feature .n { color: #E3EFFC; }

/* --- layer 53: section separation, done once in CSS ------------------------
   Some pages carried hand placed <hr class="rule"> between sections and
   some carried none: certification had seven, standard one, about none.
   That is why pages that were otherwise identical in structure read as
   different documents.

   The separator is a rule now, not markup. Every section in a body column
   that follows another gets the same hairline and the same space above it,
   so a page cannot drift by someone forgetting to type an hr. The existing
   hr.rule elements still work; the adjacent sibling selector skips a
   section that already has one before it, so nothing doubles up.
   ------------------------------------------------------------------------ */

.layout .body > section + section,
.layout .body > div + section,
.layout .body > section + div {
  border-top: 1px solid var(--rule);
  margin-top: 3.25rem;
  padding-top: 3.25rem;
}

/* A rule already sits there, so the section must not draw a second one. */
.layout .body > hr.rule + section,
.layout .body > hr.rule + div { border-top: 0; padding-top: 0; }

/* The closer is a full band; it brings its own edge. */
.layout .body > .closer,
.layout .body > section + .closer,
.layout .body > div + .closer {
  border-top: 0;
  padding-top: 95px;
  margin-top: 4rem;
}
.layout .body > .band { border-top: 0; }

/* --- layer 54: the closer, same on every page ------------------------------
   It was centred from when it was a standalone full width band on the home
   page. Now that every page ends with one, centred type inside a 772px
   column reads as a different component to the left aligned page above it,
   and the reference's own closing band is left aligned. All of them align
   left, carry the page gutter, and hold the same measure.
   ------------------------------------------------------------------------ */

.closer,
.layout .body > .closer {
  text-align: left;
  padding-inline: var(--gutter);
  padding-bottom: 90px;
}
.closer > *,
.layout .body > .closer > * { margin-inline: 0; text-align: left; }
.closer h2, .layout .body > .closer h2 { max-width: 22ch; }
.closer .lede, .closer p { max-width: 58ch; }
.closer .actions, .layout .body > .closer .actions { justify-content: flex-start; }

@media (max-width: 40rem) {
  .closer, .layout .body > .closer { padding-inline: 22px; padding-top: 64px; padding-bottom: 64px; }
}

/* --- layer 55: layer 47 was too broad, and it broke the book pages ---------
   Layer 47 stacked .showcase to fix the certificate band on the home page.
   It matched .showcase everywhere, including .showcase.cover on the three
   book pages, which is a different component: a book jacket in a narrow
   column beside its standfirst. Those pages went to a 792px cover stacked
   above the text. Caught on the Volume III page, but Volumes I and II had
   been wrong since layer 47 shipped.

   The stacking rule now names .band .showcase, which is the only place it
   was ever meant to apply, and .showcase.cover gets its two column grid
   stated back explicitly rather than relying on not being overridden.
   ------------------------------------------------------------------------ */

.layout .body .showcase.cover,
.showcase.cover {
  display: grid;
  grid-template-columns: minmax(200px, 290px) 1fr;
  gap: 2rem;
  align-items: start;
}
.showcase.cover > figure,
.layout .body .showcase.cover > figure {
  order: 0;
  width: auto;
  margin: 0;
}
.showcase.cover > .standfirst,
.layout .body .showcase.cover > .standfirst { order: 0; max-width: none; }
.showcase.cover > figure img { width: 100%; height: auto; display: block; }

@media (max-width: 40rem) {
  .showcase.cover, .layout .body .showcase.cover {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }
  .showcase.cover > figure { max-width: 260px; }
}

/* --- layer 56: the last two things still on the old serif -------------------
   The type rebuild moved the site to Jost and Cinzel, but two components were
   never converted because they name a literal font stack instead of using the
   tokens: the big figures in .facts, and the book titles in the cover
   captions. Both were computing to Iowan Old Style, which is only in the
   stack as a fallback for Cinzel. It showed up when the Volume III caption
   was compared against the other two.

   Both are display elements, so both take the display face.
   ------------------------------------------------------------------------ */

.facts .n,
body .facts .n {
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: .02em;
}

.covers figcaption a,
body .covers figcaption a {
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: .03em;
  text-transform: uppercase;
  font-size: 1rem;
  line-height: 1.35;
  color: var(--ink);
  text-decoration: none;
}
.covers figcaption a:hover { color: var(--signal); text-decoration: underline; }

/* --- layer 57: the FAQ questions were the last holdout ---------------------
   details.q summary names its own serif stack, so all fourteen questions on
   the FAQ were still rendering in the pre-rebuild face. The FAQ is the page
   built for answer engines, so it is the last page that should look like a
   different site. Questions take the display face, matching every other
   heading on the site.
   ------------------------------------------------------------------------ */

details.q > summary,
body details.q > summary {
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: .02em;
  color: var(--ink);
}

/* --- layer 58: the hairlines in the fact strip -----------------------------
   Each column carried border-right: 0.8px solid #F1F3F6. A sub pixel rule in
   a near white grey does not read as structure, it reads as a rendering
   artefact, and it rounds differently on every device. The columns are
   separated by space instead, which is what the reference site does.
   Same treatment for the criteria strip, which used the same device.
   ------------------------------------------------------------------------ */

.facts > *,
body .facts > *,
.criteria-strip > *,
body .criteria-strip > * {
  border-right: 0;
  border-left: 0;
  padding-right: 28px;
}
.facts, body .facts { gap: 8px 0; }
.criteria-strip, body .criteria-strip { gap: 8px 0; }
@media (max-width: 40rem) {
  .facts > *, body .facts > * { padding-right: 0; }
  .criteria-strip > *, body .criteria-strip > * { padding-right: 0; }
}

/* --- layer 59: the fact strip dividers, this time with enough specificity ---
   Layer 58 was right and lost. .layout .facts > div carries the border and is
   (0,2,1); my .facts > * was (0,1,0) and body .facts > * only (0,1,1), so the
   hairlines stayed. Same specificity trap as the footer and the tables.

   Every internal divider goes, vertical and horizontal. The rule above and
   below the strip stays, because that frames the block and is a full 1px in
   --rule rather than a sub pixel ghost.
   ------------------------------------------------------------------------ */

body .layout .facts > div,
body .layout .facts > div:last-child,
body .layout .facts > div:nth-child(1),
body .layout .facts > div:nth-child(2),
body .facts > div,
body .facts div,
body .criteria-strip > div,
body .criteria-strip div {
  border-right: 0;
  border-left: 0;
  border-bottom: 0;
  border-top: 0;
}
body .layout .facts > div { padding: 1.15rem 1.75rem 1.15rem 0; }
@media (max-width: 40rem) {
  body .layout .facts > div { padding-right: 0; }
}

/* --- layer 60: .wide narrows three pages, which is backwards ---------------
   interactive.css carries `.wide { max-width: 62rem }` from when .wrap was
   also 62rem. .wrap is now calc(1212px + 2 * gutter), so on qualify, registry
   and verify the container is capped at 992px and the body column lands at
   492px beside a 400px sidebar. Every other page runs 792px, and the home page
   is the standard. interactive.css loads after nbop.css, so equal specificity
   loses; this has to outrank a bare single class.

   Second half: .comparison td:first-child is nowrap on purpose, so the label
   column reads as one line the way the reference does. Inside the 792px body
   column a long label pushes the whole table past the column and .tablewrap
   scrolls sideways, which reads as broken rather than as a scroller. Labels
   wrap at the column edge instead. Short labels still sit on one line, because
   auto table layout only breaks them when it has to.
   ------------------------------------------------------------------------ */

body .wrap.wide,
body main > .wrap.wide {
  max-width: calc(1212px + 2 * var(--gutter));
  padding-inline: var(--gutter);
}

body .layout .body table.comparison { width: 100%; }
body .layout .body .comparison td:first-child { white-space: normal; }

/* --- layer 61: fact labels must not break mid word ------------------------
   overflow-wrap: break-word is inherited into .facts .n, and at 54px Cinzel a
   seven letter label does not fit the 198px column, so "Private" rendered as
   "Priva / te". Words now break at spaces and at existing hyphens only, which
   is the rule for every other display face on the site. Labels are authored
   short enough to fit; this is the guard that stops a long one being mangled.
   ------------------------------------------------------------------------ */

body .facts .n,
body .facts span.n,
body .criteria-strip .n,
body .volumes .vn,
body .features .n {
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

/* --- layer 62: the registered address -------------------------------------
   <address> is italic in every UA stylesheet, and the footer and body faces on
   this site are not. Both blocks reset it and then match the type around them:
   the footer copy exactly, and the about page address as a body-face block with
   a left rule, the way the standfirst is set.
   ------------------------------------------------------------------------ */

body footer .foot-address {
  font-family: var(--ui);
  font-style: normal;
  font-size: 15px;
  line-height: 1.65;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: #B9C6D8;
  max-width: 36ch;
  margin: 0 0 .75rem;
}

body .postal,
body address.postal {
  font-family: var(--ui);
  font-style: normal;
  font-size: 1rem;
  line-height: 1.7;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  margin: 0 0 1.25rem;
  padding-left: 1.1rem;
  border-left: 2px solid var(--rule);
}

/* --- layer 63: tables stack into cards on a phone -------------------------
   Every td on this site already carries data-label. Somebody intended the
   responsive treatment and the CSS was never written, so the attributes sat
   there doing nothing and .tablewrap just scrolled sideways instead. Two
   columns fit a 295px container, which is why this never showed up. The four
   column release table on the changelog page needs 436px and does not.

   Below 40rem each row becomes a card and each cell is labelled from its own
   data-label, so the header row is no longer load bearing and is hidden from
   sight while staying in the accessibility tree.
   ------------------------------------------------------------------------ */

@media (max-width: 40rem) {
  body main table.comparison,
  body main table.comparison tbody,
  body main table.comparison tr,
  body main table.comparison td { display: block; width: 100%; }

  body main table.comparison thead {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }

  body main table.comparison tr {
    border-bottom: 1px solid var(--rule);
    padding: .9rem 0;
  }
  body main table.comparison tr:last-child { border-bottom: 0; }

  body main table.comparison td,
  body main table.comparison td:first-child {
    padding: .55rem 0 0;
    border: 0;
    white-space: normal;
  }
  body main table.comparison tr td:first-child { padding-top: 0; }

  body main table.comparison td::before {
    content: attr(data-label);
    display: block;
    font-family: var(--ui);
    font-size: .68rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--ink-faint);
    margin-bottom: .15rem;
  }
  body main table.comparison td:not([data-label])::before { content: none; }

  body .layout .body .tablewrap,
  body .tablewrap { overflow-x: visible; }
}

/* --- layer 64: the job task analysis, made findable ----------------------
   The analysis gates the blueprint, the item bank, the cut score and version
   1.0 of the standard, and it was reachable only from body copy and the
   footer. The strip puts it under the masthead on every public page except
   the one it points at. The counter is the fuller treatment on contribute.

   Both carry the live number from the API. Both are hidden until it arrives.
   ------------------------------------------------------------------------ */

body .jta-strip {
  background: var(--navy-deep);
  border-bottom: 3px solid var(--signal);
}
body .jta-strip > .wrap {
  display: flex;
  align-items: baseline;
  gap: .5rem 1.15rem;
  flex-wrap: wrap;
  padding-top: .85rem;
  padding-bottom: .85rem;
}
body .jta-strip p {
  font-family: var(--ui);
  font-size: .95rem;
  line-height: 1.5;
  color: #E4EAF3;
  margin: 0;
  max-width: none;
}
body .jta-strip .jta-strip-n {
  font-family: var(--ui);
  font-weight: 600;
  color: #FFFFFF;
  white-space: nowrap;
}
body .jta-strip a {
  font-family: var(--ui);
  font-size: .95rem;
  font-weight: 600;
  color: #FFFFFF;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
body .jta-strip a:hover { color: var(--signal-lift); }

@media (max-width: 40rem) {
  body .jta-strip > .wrap { display: block; }
  body .jta-strip a { display: inline-block; margin-top: .4rem; }
}

/* the fuller counter, on contribute.html */
body .jta-count {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--signal);
  padding: 1.5rem 1.7rem;
  margin: 2rem 0 2.4rem;
}
body .jta-count .jta-figure {
  font-family: var(--display);
  font-size: clamp(2.4rem, 6vw, 3.4rem);
  line-height: 1;
  letter-spacing: .02em;
  color: var(--ink);
  margin: .3rem 0 .35rem;
}
body .jta-count .jta-label {
  font-family: var(--ui);
  font-size: .95rem;
  color: var(--ink-soft);
  margin: 0 0 1.1rem;
}
body .jta-meter { height: 6px; background: var(--rule-soft); overflow: hidden; }
body .jta-meter > span {
  display: block; height: 100%; width: 0;
  background: var(--signal);
  transition: width .6s ease;
}
body .jta-count .note { margin-top: 1.1rem; margin-bottom: 0; }

/* --- layer 65: .visually-hidden belongs in the stylesheet every page loads
   It was only ever defined in interactive.css, which four pages load. Any
   page using the class without that file rendered its screen reader text as
   ordinary visible copy, which is what happened to the counter on contribute.
   ------------------------------------------------------------------------ */

body .visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* --- layer 66: the social profiles in the footer ---------------------------
   Set as bordered chips rather than a run of links with separators, so the
   row reads as a set of destinations and needs no punctuation glyph between
   them. Border is #5A6E8C, which clears 3:1 against the footer ground for
   1.4.11; the label colour clears 10:1 for 1.4.3.
   ------------------------------------------------------------------------ */

body footer .foot-social {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: .95rem 0 0;
  padding: 0;
  max-width: 36ch;
}

body footer .foot-social a {
  font-family: var(--ui);
  font-size: 13px;
  line-height: 1;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: none;
  color: #C9D3E2;
  border: 1px solid #5A6E8C;
  border-radius: 999px;
  padding: .55rem .9rem;
  text-decoration: none;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}

body footer .foot-social a:hover,
body footer .foot-social a:focus-visible {
  color: #FFFFFF;
  border-color: #FFFFFF;
  background: rgba(255, 255, 255, .06);
  text-decoration: none;
}

/* --- layer 67: the job task analysis form, after a submission was lost -----
   The collection rules treat the two rating scales as linked at their floor:
   a task that is not part of a role is never performed, and the reverse. The
   form did not say so and did not enforce it, so a respondent could spend
   twenty minutes building a submission the API would refuse as malformed,
   and the page reported only that it did not save. The controls now make the
   contradiction unreachable, and these rules give the disabled option and
   the failure message the weight they need.
   ------------------------------------------------------------------------ */

body .pairnote {
  font-size: .88rem;
  line-height: 1.6;
  color: var(--ink-soft);
  border-left: 3px solid var(--rule);
  padding: .1rem 0 .1rem 1rem;
  margin: 0 0 1.8rem;
  max-width: var(--measure);
}

body .rate:has(input:disabled) {
  opacity: .4;
  cursor: not-allowed;
  background: var(--rule-soft);
}

body .rate input:disabled { cursor: not-allowed; }
body .rate:has(input:disabled):hover { background: var(--rule-soft); }

body p.disclosure.is-error {
  color: #8C2F24;
  border-left: 3px solid #8C2F24;
  padding: .35rem 0 .35rem 1rem;
  font-size: .95rem;
  line-height: 1.6;
  font-weight: 500;
  max-width: var(--measure);
}

body p.disclosure.is-note {
  color: var(--ink);
  border-left: 3px solid var(--signal);
  padding: .35rem 0 .35rem 1rem;
  font-size: .95rem;
  line-height: 1.6;
  max-width: var(--measure);
}

/* --- layer 68: the footer profiles as brand marks -------------------------
   Six profiles is too many to set as worded chips: the row stopped reading as
   a set of destinations and started reading as a sentence. The marks are the
   real ones, served from this domain rather than a third party, and painted
   through a mask so they take the footer ink colour instead of arriving as a
   row of competing brand colours over the navy.

   The mask is the whole mechanism, so everything that depends on it sits
   inside the @supports block. A browser without mask support keeps the
   worded chips from layer 66 exactly as they were, which is a working footer
   rather than six blank squares. The label is never removed from the markup,
   only hidden, so the accessible name stays "Instagram" and not "link".
   ------------------------------------------------------------------------ */

body footer .si-instagram { --si: url("/assets/icons/instagram.svg"); }
body footer .si-threads { --si: url("/assets/icons/threads.svg"); }
body footer .si-tiktok { --si: url("/assets/icons/tiktok.svg"); }
body footer .si-facebook { --si: url("/assets/icons/facebook.svg"); }
body footer .si-linkedin { --si: url("/assets/icons/linkedin.svg"); }
body footer .si-youtube { --si: url("/assets/icons/youtube.svg"); }

@supports (mask-image: none) or (-webkit-mask-image: none) {

  body footer .foot-social { gap: .25rem; margin: .85rem 0 0; margin-left: -9px; }

  body footer .foot-social a.si {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: #C9D3E2;
    transition: color .15s ease, background-color .15s ease;
  }

  body footer .foot-social a.si:hover,
  body footer .foot-social a.si:focus-visible {
    color: #FFFFFF;
    background: rgba(255, 255, 255, .10);
    border: 0;
    text-decoration: none;
  }

  body footer .foot-social a.si > span {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  body footer .foot-social a.si::before {
    content: "";
    display: block;
    width: 21px;
    height: 21px;
    background-color: currentColor;
    -webkit-mask: var(--si) center / contain no-repeat;
    mask: var(--si) center / contain no-repeat;
  }

}

/* --- layer 69: long words in section headings on narrow screens -----------
   A section heading holding one long unbreakable word overflowed its column
   below about 400px. "Accommodations" needed 327px in a 310px measure. The
   fix is not to let the word break, because a heading cut mid-word is worse
   than the overflow, and not to rename sections around a layout defect. It
   is to give the display face slightly less room to ask for at the narrowest
   widths. Verified clean at 390, 360 and 320px.
   ------------------------------------------------------------------------ */

@media (max-width: 26rem) {

  body .layout .body > section > h2,
  body .layout .body > .intro > h2,
  body section > .wrap > h2,
  body .closer > .wrap > h2,
  body .band > .wrap > h2,
  body section > h2 {
    font-size: .95rem;
    letter-spacing: .045em;
  }

}
/* ---------- small text, measured in the hand ----------
 *
 * These are the editorial micro labels. At a desk they read as fine detail; on
 * a 360px phone the sidebar terms measured 10.88px and the footer wordmark
 * 10px, which is under any sensible floor for text somebody is expected to
 * actually read. Raised only at phone widths, so the desktop typography that
 * the site was designed around is untouched.
 */
@media (max-width: 48rem) {
  .sidebar dt,
  footer dt { font-size: 0.75rem; letter-spacing: 0.11em; }
  /* Matched at the same weight as the rule it is correcting. The obvious
   * .footmark-text .full lost to body footer .footmark .full on specificity
   * and changed nothing at all, which is the sort of fix that looks applied
   * and is not. */
  body footer .footmark .full { font-size: 0.72rem; letter-spacing: 0.06em; }

  /* Real controls with a 27px row to hit. The radio itself is 13px; the label
   * is what a thumb actually lands on, so that is what gets the size. */
  .choice { min-height: 2.5rem; display: flex; align-items: center; gap: 0.5rem; }
  .rate { min-height: 2.75rem; }
}

/* ---------- footer links you are meant to tap ----------
 *
 * The footer columns are navigation, not prose: stacked links a thumb is
 * expected to hit. They measured 17px tall with almost no gap between them,
 * which on a phone is a coin toss between Endorsements and Candidate handbook.
 * Padding rather than font size, so the footer looks the same and the target
 * grows to about 40px.
 *
 * Scoped to a link that is the whole of its list item, which is what a nav
 * link is. The social row is a <p> of icon links already sized 40px, and is
 * deliberately not touched.
 */
@media (max-width: 48rem) {
  footer li > a:only-child {
    display: block;
    padding: 0.62rem 0;
  }
  footer li { margin: 0; }
}

/* Breadcrumb links are navigation too, and were 18px tall. Inline-block so the
 * row stays a row; the padding is what the thumb gets. */
@media (max-width: 48rem) {
  .crumbs li > a { display: inline-block; padding: 0.5rem 0; }
}

/* Links that are the whole of their line rather than a word inside a sentence
 * are things somebody taps: a book title, an address, a lone call to action.
 * They were the height of their own type, 17 to 20px. Padding takes them past
 * 32px without touching the type or the layout around them. A link genuinely
 * inside a sentence is left alone, because a 32px word in a paragraph would
 * wreck the line rhythm for no gain.
 */
@media (max-width: 48rem) {
  main p > a:only-child,
  main h3 > a:only-child,
  main h4 > a:only-child,
  main li > a:only-child,
  .volume h3 > a { display: inline-block; padding: 0.5rem 0; }
}

/* The cover captions on the homepage, last of the micro type at 10.6px. */
@media (max-width: 48rem) {
  .covers figcaption .vn { font-size: 0.72rem; }
}



/* ---------- two formats, two links ----------
 *
 * The card used to carry one price and one link because there was one thing to
 * buy. Now there are two, and neither is the default: a row rather than a
 * primary with an afterthought beside it. On a phone each one is 44px tall,
 * which the generic rule above does not reach because these are not the only
 * child of anything.
 */
/* The price line breaks between the two formats, never inside one of them.
 * "KINDLE" on one line and "$9.99" on the next is a price nobody reads as a
 * price. Same reason the ISBN below does not split: it is an identifier
 * somebody may want to copy. */
.volume .status > span { white-space: nowrap; }
.status-line .isbn { white-space: nowrap; }
.volume .buys { display: flex; flex-wrap: wrap; gap: 0.1rem 1.15rem; margin-top: 0.45rem; }
.volume .buys a { font-size: 0.86rem; }
@media (max-width: 48rem) {
  .volume .buys a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* ---------- buy it in either format ----------
 *
 * The pills in each volume's sidebar. The secondary one restates its colours
 * rather than inheriting .action-secondary, which is written for a light band
 * and sets near black text on a border of the same near black. The sidebar is
 * navy. That rule reaching a dark panel is how this stylesheet has produced
 * unreadable text more than once, and the fix each time was to say the colour
 * on the state a global rule also targets.
 */
/* A grid rather than a flex row, because two pills of different word lengths in
 * a flex row come out different widths, and a wider one reads as the preferred
 * one. auto-fit drops them to one per row when the column would be too narrow
 * for the price to stay on its line. */
.sidebar .buypills {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.5rem;
  margin-top: 1.5rem;
}
.sidebar .buypills .action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin-top: 0;
  padding: 0.6rem 0.7rem;
  border-radius: 999px;
  text-align: center;
  font-size: 0.76rem;
  letter-spacing: 0.05em;
  /* One pill wrapping to two lines while the other does not made them look
   * like a primary and an afterthought, which is the exact thing they are not.
   * They break to two rows together or not at all. */
  white-space: nowrap;
}
.sidebar .buypills .action-secondary {
  background: transparent;
  color: #FFFFFF;
  border-color: rgba(255,255,255,0.55);
}
.sidebar .buypills .action-secondary:hover,
.sidebar .buypills .action-secondary:focus-visible {
  background: #FFFFFF;
  color: var(--navy);
  border-color: #FFFFFF;
}


/* --- layer 72: footer policy links ---------------------------------------
   A third flex child inside .foot-base, sitting between the governing board
   statement and the copyright. Inherits the muted footer grey rather than
   the brighter link colour, because these are furniture, not destinations
   we are pushing people towards. Wraps to its own line under 34rem. */
body footer .foot-policies {
  display: flex; flex-wrap: wrap; gap: .3rem 1.35rem;
  margin: 0; padding: 0; list-style: none;
}
body footer .foot-policies li {
  margin: 0; padding: 0;
  font-family: var(--ui); font-size: 13.5px; line-height: 1.65;
  letter-spacing: normal; text-transform: none;
}
body footer .foot-policies li::before { content: none; }
body footer .foot-policies a { font-size: 13.5px; line-height: 1.65; color: #93A3B9; }
body footer .foot-policies a:hover { color: #FFFFFF; text-decoration: underline; }
@media (max-width: 48rem) { body footer .foot-policies { width: 100%; } }


/* --- layer 73: skip to content -------------------------------------------
   First focusable element on the page. Hidden the same way .visually-hidden
   hides things, until it takes focus, when it un-clips and pins to the top
   left. Signal ground with white text clears 4.5:1. Honours reduced motion
   by having no transition to honour. */
body .skiplink {
  position: absolute;
  left: 0; top: 0;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  z-index: 1000;
}
body .skiplink:focus,
body .skiplink:focus-visible {
  width: auto; height: auto;
  margin: 0;
  padding: .85rem 1.25rem;
  clip: auto;
  clip-path: none;
  background: var(--signal);
  color: #FFFFFF;
  font-family: var(--ui);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .02em;
  text-decoration: none;
  border-radius: 0 0 3px 0;
  outline: 2px solid #FFFFFF;
  outline-offset: -5px;
}
body main:focus { outline: none; }

/* --- layer 74: the menu collapses when it stops fitting, not at a phone width -
   Measured rather than guessed. The primary nav's natural width is 1013px, and
   the masthead wrap carries 40px of padding a side, so the row needs about
   1200px of viewport to sit on one line. The drawer, though, only appeared at
   46rem (736px).

   Between those two numbers, which is most laptops and every tablet in
   landscape, the ten items wrapped onto a second ragged line under the
   wordmark. Nothing was broken and it read as broken, which for a standards
   body is the same problem.

   So the same drawer now applies up to 75rem. Below 46rem the original block
   still applies and says the same things; this one is a superset and they
   agree. The wordmark shrink stays at 46rem, because a tablet has room for the
   full organisation name and a phone does not.
   ------------------------------------------------------------------------ */
@media (max-width: 75rem) {
  .masthead .wrap {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding-top: 1.1rem;
    padding-bottom: 1.1rem;
    gap: 1rem;
  }
  .masthead .wordmark { flex: 1 1 auto; min-width: 0; }
  .navbtn {
    display: inline-block;
    font-family: var(--ui);
    font-size: 0.72rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--navy);
    border: 1px solid var(--rule);
    padding: 0.55rem 0.9rem;
    cursor: pointer;
    white-space: nowrap;
    flex: none;
  }
  .navbtn:hover { border-color: var(--navy); }
  .masthead nav { display: none; width: 100%; order: 3; }
  .navtoggle:checked ~ nav { display: block; }
  .masthead nav ul {
    flex-direction: column;
    gap: 0;
    border-top: 1px solid var(--rule);
    margin-top: 0.4rem;
    padding-top: 0.3rem;
  }
  .masthead nav li { border-bottom: 1px solid var(--rule-soft); }
  .masthead nav li:last-child { border-bottom: 0; }
  .masthead nav a { display: block; padding: 0.85rem 0; border-bottom: 0; font-size: 0.8rem; }
  .masthead nav ul li.signin { border-left: 0; padding-left: 0; }
}

/* --- layer 75: the primary nav, grouped -----------------------------------
   Ten flat links became six groups. The rules below are last in the file on
   purpose: earlier layers style .masthead nav a, and a grouped nav needs to
   win over them rather than fight for specificity.

   The submenu opens on hover and on focus-within, so it works with no
   JavaScript at all. nav.js adds click for touch and manages aria-expanded;
   if it never loads, keyboard users still reach every item by tabbing, because
   focus-within opens the panel the moment a child is focused.
--------------------------------------------------------------------------- */

.masthead nav ul { position: relative; }
.masthead nav li.has-sub { position: relative; }

/* The toggle is a desktop affordance only: a small caret after the label.
   It is a real button so that a keyboard and a screen reader both get told
   there is something here that opens. */
.masthead .subtoggle {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 0 .1rem 0 .34rem; margin: 0; line-height: 1;
  color: inherit; font: inherit;
}
.masthead .subtoggle::after {
  content: ""; display: inline-block; width: .38rem; height: .38rem;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  opacity: .55; transition: opacity .12s ease, transform .12s ease;
}
.masthead li.has-sub:hover .subtoggle::after,
.masthead li.has-sub:focus-within .subtoggle::after { opacity: 1; }
.masthead .subtoggle:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.masthead .subnav {
  position: absolute; top: 100%; left: 0; z-index: 60;
  min-width: 15rem; margin: 0; padding: .4rem 0;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--signal);
  box-shadow: 0 12px 28px rgba(13, 30, 59, .13);
  flex-direction: column; gap: 0;
  opacity: 0; visibility: hidden; transform: translateY(-3px);
  transition: opacity .13s ease, transform .13s ease, visibility .13s;
}
.masthead li.has-sub:hover > .subnav,
.masthead li.has-sub:focus-within > .subnav,
.masthead li.has-sub.open > .subnav {
  opacity: 1; visibility: visible; transform: translateY(0);
}
.masthead .subnav li { border: 0; }
.masthead .subnav a {
  display: block; padding: .5rem 1rem; border-bottom: 0;
  font-size: .74rem; letter-spacing: .06em; white-space: nowrap;
}
.masthead .subnav a:hover { background: var(--paper-warm); color: var(--signal); }

/* Under the breakpoint the masthead nav is already a stacked drawer, so the
   submenu is shown inline and indented rather than as a floating panel. A
   panel that hovers has nothing to hover on a touch screen, and hiding these
   behind a second tap would bury the pages this restructure exists to surface. */
@media (max-width: 75rem) {
  .masthead .subtoggle { display: none; }
  .masthead .subnav {
    position: static; opacity: 1; visibility: visible; transform: none;
    border: 0; box-shadow: none; background: none;
    min-width: 0; padding: 0 0 .35rem .9rem;
  }
  .masthead .subnav a {
    padding: .5rem 0; font-size: .72rem; white-space: normal;
    color: var(--ink-soft);
  }
  .masthead .subnav a:hover { background: none; }
  .masthead nav li.has-sub { border-bottom: 1px solid var(--rule-soft); }
}

/* --- layer 76: the masthead holds one line ---------------------------------
   The masthead is a wrapping flex row, and the grouped nav's carets nudged
   its natural width past common laptop viewports, so between about 1200 and
   1500 pixels the nav dropped to a second row with a rule above it. That
   two row state was never designed, it was overflow, and it read as a
   different site depending on your window width.

   Above the drawer breakpoint the row now refuses to wrap. What gives way
   instead, in order: the nav gap tightens, and below 88rem the long form of
   the wordmark yields to the initials, which is exactly what initials are
   for. The two row treatment (nav border-top, no bottom padding) belongs to
   the drawer regime only, so it is unset here.
--------------------------------------------------------------------------- */

@media (min-width: 75rem) {
  .masthead > .wrap {
    flex-wrap: nowrap;
    align-items: center;
    padding-bottom: 1.05rem;
  }
  .masthead nav { border-top: 0; margin-top: 0; }
  .masthead nav > ul { flex-wrap: nowrap; gap: 1.35rem; }
  .masthead nav a { white-space: nowrap; }
}

@media (min-width: 75rem) and (max-width: 88rem) {
  .wordmark .full { display: none; }
  .masthead nav > ul { gap: 1.1rem; }
}

/* === layer 77: warmth ======================================================
   The site read as sterile, and the palette was the reason rather than the
   layout. Pure white ground, ink at #161616 which is effectively black, a
   secondary ground of #F4F4F4 which is neutral grey and therefore reads as
   unstyled, and every grey in the file was hueless. Nothing was warm because
   nothing had any warmth in it to begin with.

   The reference is mrjttaylor.com, which solves this with a cream ground, a
   warm blue-grey for body copy, and geometry that is softened rather than
   square. Its palette is lifted here where it applies.

   WHAT IS DELIBERATELY NOT COPIED

   The display face. That site is Oswald, condensed and shouting, which is
   right for one person's name and wrong for a standards body: NBOP's Cinzel
   is most of what makes a page look like a published document rather than a
   pitch. Warmth is a palette and geometry problem, not a reason to give up
   the institutional voice.

   White also survives, for content that behaves like a document. Tables and
   panels stay white on the cream ground, which is what gives them the sense
   of being sheets laid on a desk, and keeps long reading crisp.
--------------------------------------------------------------------------- */

:root {
  /* grounds */
  --paper:       #FFFFFF;   /* documents, tables, panels: still white */
  --paper-warm:  #FAF6EF;   /* the page itself, from mrjttaylor.com */
  --paper-cream: #F4EEE2;   /* a warmer tier for pulled-aside blocks */

  /* ink. #161616 was near black and hard on a cream ground. */
  --ink:        #22303C;
  --ink-soft:   #54606A;
  --ink-faint:  #82796C;    /* warm taupe, so muted text is muted and not cold */

  /* rules, warmed to sit on cream rather than cut across it */
  --rule:       #E4DBCB;
  --rule-soft:  #F0E9DD;

  /* geometry */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 999px;
}

/* The page ground. Everything that was implicitly white now sits on cream,
   which is the single change that does most of the work. */
body { background: var(--paper-warm); }
.masthead { background: var(--paper-warm); border-bottom-color: var(--rule); }
footer { background: var(--paper-cream); }

/* Content that behaves like a document keeps a white sheet under it, so the
   contrast between page and document is what creates depth. */
main > .wrap > section > table,
.comparison, .admin-table, table { background: var(--paper); }

/* Type. A touch more line height and a warmer body colour: the same words
   read as less clipped without any of them changing. */
body { line-height: 1.75; color: var(--ink-soft); }
main p { color: var(--ink-soft); }
h1, h2, h3, h4 { color: var(--ink); }

/* Buttons become pills. This is the most recognisable thing the personal site
   does and it is the cheapest warmth on the page: a rounded action reads as an
   invitation, a square one as a form control. */
.action, .btn, button.btn, a.btn, .navbtn {
  border-radius: var(--r-pill);
}
.action { padding-inline: 1.5rem; }

/* Panels, tables and images stop being hard rectangles. Small radii only:
   a standards body should look considered rather than playful. */
.comparison, .admin-table, table,
.offer, .note, .status-line, .standfirst,
.tile, .card, .glance, figure, .frame img, .showcase img {
  border-radius: var(--r-md);
  overflow: hidden;
}
.hero img, .band img { border-radius: var(--r-lg); }

/* Full bleed dark bands stay square. A rounded corner on a band that runs to
   the edge of the window reads as a mistake rather than a decision. */
.hero, .closer, .band, .release { border-radius: 0; }

/* The navy sidebar panel and the dark bands get a warm edge rather than a
   hard one, so they sit on the cream instead of being punched through it. */
.glance, aside.glance, .side-panel { border-radius: var(--r-md); }

/* Table headers were full strength #0063C6 across the width, which is the
   loudest object on any page it appears on. Keeping the colour and dropping
   the weight leaves it legible and stops it shouting. */
table thead th, .comparison thead th { background: var(--navy); }

/* Rules inside tables warm up with everything else. */
table td, table th { border-color: var(--rule-soft); }

/* Focus rings pick up the accent rather than the browser default. */
a:focus-visible, button:focus-visible, .action:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--signal); outline-offset: 2px; border-radius: var(--r-sm);
}

/* Form controls, which were the squarest thing on the site. */
input[type="text"], input[type="email"], input[type="search"],
input[type="number"], select, textarea {
  border-radius: var(--r-sm); background: var(--paper); border-color: var(--rule);
}

/* A little lift under anything that is meant to read as a card. Shadows are
   kept nearly invisible: warmth here comes from colour and radius, and a heavy
   shadow would make an institutional page look like an app. */
.offer, .glance, .tile, .card { box-shadow: 0 1px 2px rgba(34, 48, 60, .04); }

/* === layer 78: warmth, second pass ========================================
   The palette moved but the page still had cold, heavy objects on it. The
   navy was the main one: #223D71 is a saturated blue-violet, and it is the
   fill behind every dark band, every side panel, every table header and the
   primary button, so it set the temperature of the whole site regardless of
   what the ground did. mrjttaylor.com uses #1E3A56, which is the same idea
   desaturated and turned toward slate. Changing one token cools nothing and
   warms everything at once.

   The rest of this layer is about severity rather than colour. A standards
   body should look considered, not clenched, and most of what read as rigid
   was hard 2px rules, very wide letterspacing, and flat fills with no depth.
--------------------------------------------------------------------------- */

:root {
  --navy:      #1E3A56;   /* was #223D71, saturated blue-violet */
  --navy-deep: #172E44;   /* for gradient ends and hovers */
  --navy-soft: #24425F;
}

/* Dark bands get a shallow vertical gradient. Flat navy across a full bleed
   band reads as a printed block; a few percent of movement reads as a
   surface. Kept subtle enough that it is felt rather than noticed. */
.hero, .closer, .band, .release {
  background: linear-gradient(178deg, var(--navy-soft) 0%, var(--navy) 55%, var(--navy-deep) 100%);
}

/* Side panels lose the slab quality: a warm hairline at the top edge gives
   them a lid instead of a cut, and a soft shadow lifts them off the cream. */
.glance, aside.glance, .side-panel {
  background: linear-gradient(180deg, var(--navy-soft) 0%, var(--navy) 100%);
  border-top: 3px solid var(--signal);
  box-shadow: 0 2px 10px rgba(30, 58, 86, .10);
}

/* The marker above a section heading was a hard 2px bar. Widened, thinned,
   and faded at its tail, so it points rather than stops. */
section > h2::before,
main > .wrap > section > h2::before {
  height: 3px;
  width: 3rem;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--signal) 0%, rgba(0, 99, 198, 0) 100%);
}

/* Eyebrows were set at .2em, which is wide enough to read as engraving. A
   little tighter, and warmed off pure accent blue so they sit on cream. */
.eyebrow {
  letter-spacing: .13em;
  font-size: .73rem;
}

/* The standfirst rule softens for the same reason as the heading marker. */
.standfirst { border-left-width: 3px; border-radius: 2px; }
.note, .status-line, .offer { border-left-width: 3px; }

/* Sections breathe. Most of the rigidity left after the palette moved was
   simply that blocks sat too close to each other to feel unhurried. */
main > .wrap > section { margin-top: 3.4rem; }
main > .wrap > section > h2 { margin-bottom: 1rem; }
main p + p { margin-top: 1.05rem; }

/* Links: the underline arrives on hover rather than sitting there, and the
   colour warms slightly instead of jumping. */
main a:not(.action):not(.btn) {
  text-underline-offset: .18em;
  text-decoration-thickness: 1px;
  transition: color .14s ease;
}

/* Buttons gain a little lift and a hover that moves rather than flashes. */
.action, .btn {
  transition: transform .14s ease, box-shadow .14s ease, background-color .14s ease;
  box-shadow: 0 1px 2px rgba(30, 58, 86, .10);
}
.action:hover, .btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(30, 58, 86, .16); }
.action:active, .btn:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(30, 58, 86, .12); }

/* Anyone who has asked for less motion gets none of the above. */
@media (prefers-reduced-motion: reduce) {
  .action, .btn, main a { transition: none; }
  .action:hover, .btn:hover { transform: none; }
}

/* Table headers stop being a solid bar of accent across the page width. */
table thead th, .comparison thead th {
  background: var(--navy);
  border-bottom: 2px solid var(--navy-deep);
}
table tbody tr:nth-child(even) { background: rgba(244, 238, 226, .45); }

/* Images sit on the cream rather than being cut into it. */
main img, figure img { border-radius: var(--r-md); }

/* The footer is the warmest thing on the page, which is the right place to
   end: a page should relax at the bottom rather than stop. */
footer { background: var(--paper-cream); border-top: 1px solid var(--rule); }

/* Accessibility correction to layer 77.
   --ink-faint was warmed to #82796C, which looked right and measured 3.98:1
   on the cream and 3.71:1 on the warm tier. That token carries eyebrows,
   captions and table meta, all of which are normal-size text and therefore
   need 4.5:1. Warmth is not worth failing contrast for, so the same hue is
   taken down until it passes on the harder of the two grounds. */
:root { --ink-faint: #706757; }   /* 5.18:1 on cream, 4.83:1 on the warm tier */

/* === layer 79: the rest of the corners ====================================
   Layers 77 and 78 rounded the components I could name from looking at a few
   pages. A static pass over every stylesheet then found 221 selectors that
   paint a background or a border and never round anything, which is why the
   site still had square panels on pages I had not opened.

   So this block is generated from that audit rather than written by hand,
   which is the only way to be sure it covers what is actually there instead
   of what I remembered seeing. Three radii by role: controls take the small
   one, anything that reads as an action takes the pill, and every other
   painted container takes the panel radius.

   Deliberately left square: table cells, whose corners belong to the table
   around them; full bleed bands, where a rounded corner against the window
   edge reads as a mistake; breadcrumbs and progress bars, which are text and
   rules rather than panels.
--------------------------------------------------------------------------- */

/* form controls */
.admin-field input,
.admin-field textarea,
.board input[type="number"],
.board input[type="text"],
.board select,
.capturerow input[type="email"],
.exam-q textarea,
.field input[type="number"],
.field input[type="text"],
.field textarea,
.pf input[type="email"],
.pf input[type="password"],
.pf input[type="text"],
.q input[type="text"],
.q textarea,
.q-int input,
.searchbar input,
.searchbar select,
input[type=range] {
  border-radius: var(--r-sm);
}

/* anything that reads as an action */
.action-secondary,
.btn.danger,
.btn.ghost,
.callout .action,
.cases-list .pill,
.cases-list .pill.good,
.cases-list .pill.stop,
.cases-list .pill.warn,
.offer .action,
.pagehead .action,
.pagehead .action-secondary,
.pill,
.pill.go,
.pill.good,
.pill.stop,
.pill.warn,
.shot .action,
.shot .action-secondary,
.sidebar .action,
.sidebar .action-secondary,
.sidebar .buypills .action-secondary,
button.action {
  border-radius: var(--r-pill);
}

/* painted containers */
.admin-audit li,
.admin-dl,
.admin-dl > div,
.admin-ends li,
.admin-form,
.admin-gaps,
.admin-search,
.admin-stats,
.admin-stats > div,
.admin-tabs,
.admin-tabs a,
.allocnum,
.allocrow,
.bookblock,
.bookblock .cover img,
.callout,
.capture,
.card .price,
.cases-list li,
.courses .live,
.courses .soon,
.courses li,
.cov,
.cov.held,
.coverage,
.covers img,
.credcard,
.credcard .rows,
.criteria-strip,
.criterion,
.criterion.met .mark,
.domain,
.domain .box,
.domains,
.door,
.endorsement,
.endorsement.held,
.err,
.exam-bar,
.exam-q,
.facts,
.facts div,
.facts div:nth-child(1),
.facts div:nth-child(2),
.faq,
.faq details,
.feature,
.finding,
.finding.closing,
.finding.sev-primary,
.firewall,
.foot-base,
.intro,
.layout .body > .intro,
.layout .body > div + section,
.layout .body > section + div,
.layout .body > section + section,
.layout .facts > div,
.lessonlist a,
.lessonvideo .transcript,
.msg,
.msg.err,
.msg.ok,
.nextsteps .step,
.nextsteps .step.primary,
.offer li,
.offer ul.spec,
.pagehead,
.portal-bar,
.portal-bar .who button,
.portal-bar nav a,
.portal-rail,
.portal-rail .rail-flyout,
.proof,
.q,
.q-choice,
.qblock,
.radio,
.rail,
.rail .railtop,
.rail-brand,
.rail-burger,
.rail-drawer,
.rail-drawer .drawer-account,
.rail-drawer .drawer-close,
.rail-drawer .drawer-group + .drawer-group,
.rail-drawer .drawer-head,
.rail-flyout,
.rail-scrim,
.rail-top,
.rate,
.result,
.rule,
.segmented label,
.segmented label.on,
.shot,
.showcase .frame img,
.showcase.cover .standfirst,
.showcase.cover img,
.sidebar,
.sidebar .rule-top,
.sidebar h2,
.sidebar ul.spec,
.stage,
.status,
.steps li,
.steps li.now,
.submitrow,
.tint,
.tint .card,
.tint .feature,
.tint .volume,
.tint ul.spec li,
.toggle,
.verdict,
.volume,
.yousaid,
body .features.tiles > .feature .n,
body .jta-count,
body .jta-meter,
body .jta-meter > span,
body .jta-strip,
body .pairnote,
body .postal,
body address.postal,
body footer,
body footer .foot-base,
body footer a,
body main table,
body p.disclosure.is-error,
body p.disclosure.is-note,
details.q,
details.q:first-of-type,
h2,
hr.rule,
main > .wrap > section > table,
nav a,
nav ul li.signin,
section,
ul.spec,
ul.spec li {
  border-radius: var(--r-md);
}

/* The two the generated pass could not reach.

   .subnav is the nav dropdown from layer 75, written before the radius tokens
   existed, so it declared its own border and never came back for a corner.
   The panel it drops is the first thing a visitor sees open, so it is the
   worst one to have left square.

   And an anchor that carries its own border is behaving as a button whatever
   it is called, so it takes the action radius. */
.masthead .subnav { border-radius: 0 0 var(--r-md) var(--r-md); }
main a[class]:not(.action):not(.btn) { border-radius: var(--r-sm); }

/* === layer 80: what the cream revealed ====================================
   Moving the ground to cream exposed a class of element that had been
   invisible: sections painted white on a white page. They read as nothing
   before and read as cards now, which is a layout they were never designed
   for. .intro is the clearest case, an intro band declared
   `background: var(--paper); border: 0` with 90px of top padding and two
   paragraphs in it. As a band that is fine. As a card it looks like a
   mistake, because it is one.

   The rule is simple and worth stating: white is for things that behave like
   a document, which means tables, panels, notes and callouts. A full width
   section that merely wanted to not be grey is a band, and a band takes the
   page ground.
--------------------------------------------------------------------------- */

.intro {
  background: transparent;
  border-radius: 0;
}

/* Same reasoning: a section that runs the full content width and carries no
   border is a band rather than a panel, so it does not take a card corner. */
main > .wrap > section:not([class]) { background: transparent; border-radius: 0; }

/* === layer 81: the panel family, and one number per row ====================
   THE PANELS WENT INVISIBLE

   .card, .volume, .note, .faq and .status-line were all declared
   `background: var(--paper-warm)`, which was #F4F4F4 and read as a quiet
   panel on a white page. The warmth pass turned that token into the cream
   the whole page now sits on, so every one of them became cream on cream and
   stopped being a panel at all. The Common questions block was the visible
   symptom: correctly styled, and invisible.

   This is the same failure as .intro in layer 80 and the exact inverse of it.
   That one was white on white and became a card it was never meant to be;
   these were grey on white and became nothing. Both were caused by a token
   changing meaning underneath a rule that named it.

   The lesson is worth keeping: --paper-warm used to mean "slightly not the
   page" and now means "the page". Anything that wanted the first meaning has
   to say white.
--------------------------------------------------------------------------- */

.card, .volume, .note, .faq, .status-line {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
}
.card, .volume { border-left: 3px solid var(--signal); }

/* The FAQ needs padding now that it is a card rather than a rule with items
   hanging off it. */
.faq {
  padding: 1.35rem 1.5rem;
  max-width: 46rem;
  border-top: 1px solid var(--rule);
}
.faq > h2 { margin-top: 0; }
.faq > h2::before { content: none; }
.faq details:last-of-type { border-bottom: 0; }
.faq details:last-of-type > p { margin-bottom: 0; }

/* === layer 82: the ghost that was never a ghost ===========================
   303 buttons across 105 pages carry class="action ghost", and no stylesheet
   in this project ever defined .action.ghost. The modifier is only honoured on
   .btn, via .btn:not(.ghost), so on .action it did nothing at all and every
   intended secondary rendered as a filled primary.

   The markup asks for two tiers and the page showed one. That is why paired
   calls read as two equally weighted demands: "Paperback, $19.99" beside
   "Kindle, $9.99", "See the 15 lessons" beside "Run The Automation Reading",
   "Start with the Reading" beside "Or read from the beginning". In each pair
   the second is the quieter option and none of them looked it.

   Two grounds, because the same button appears on both. On the page the ghost
   is ink on nothing with a hairline. In a hero it has to take the light half
   of the palette or it is dark ink on navy.
--------------------------------------------------------------------------- */

.action.ghost {
  background: transparent;
  color: var(--ink);
  border-color: #C9CED6;
}
.action.ghost:hover,
.action.ghost:focus-visible {
  background: transparent;
  border-color: var(--signal);
  color: var(--signal-ink);
}

.pagehead .action.ghost,
.hero .action.ghost,
.band .action.ghost,
.closer .action.ghost {
  background: transparent;
  color: #FFFFFF;
  border-color: rgba(255, 255, 255, .5);
}
.pagehead .action.ghost:hover,
.pagehead .action.ghost:focus-visible,
.hero .action.ghost:hover,
.hero .action.ghost:focus-visible,
.band .action.ghost:hover,
.band .action.ghost:focus-visible,
.closer .action.ghost:hover,
.closer .action.ghost:focus-visible {
  background: rgba(255, 255, 255, .1);
  border-color: #FFFFFF;
  color: #FFFFFF;
}

/* === layer 83: three rules the blue migration left behind ==================
   The accent used to be the orange #E8571F, and the comment still standing at
   line 1167 records the arithmetic that justified pairing it with near black
   type: "Bright accent with near-black type is 4.7:1 and passes; the same
   orange with white type would be 3.6:1 and would not."

   That was true of the orange. The later palette repointed --signal to
   #0063C6 and the arithmetic inverted: white on the blue is 5.83:1 and passes,
   near black on it is 2.31:1 and fails. Most consumers were migrated. Three
   were not, and they are listed here rather than edited in place so the
   reason survives next to the fix.

   1 and 2 are AA failures reachable today on every page.
   3 is not a contrast failure. It is four rules that were written and then
   silently defeated by a later rule of equal specificity.
--------------------------------------------------------------------------- */

/* 1. Selected text, anywhere on the site. --ink on the accent fill is 2.31:1.
      The earlier ::selection at line 906 had this right with white; the rule
      at 1181 overrode it while the accent was still orange. Hardcoded rather
      than pointed at --paper, because a token that means "panel" should not
      be what decides legibility on top of a fill. */
::selection { background: var(--signal); color: #FFFFFF; }

/* 2. The Sign in button in the masthead, on 162 pages, for signed out
      visitors only. It rests navy with white type and flipped to the accent
      fill with --ink type on hover, which is the same 2.31:1. White also
      matches the resting label, so the button no longer changes text colour
      when the pointer arrives. */
.masthead .signin a:hover { background: var(--signal); color: #FFFFFF; border-bottom: 0; }

/* 3. Buttons on the dark grounds. Four rules say a button on a hero, band,
      closer, release, sidebar or pagehead should inverse to a white fill with
      navy type on hover, and all four are dead: .action:not(.action-secondary):hover
      carries the same specificity, sits later in the file, and wins with a
      darker blue instead. The label stays legible either way, but against the
      closer's navy the fill goes from 1.78:1 to 1.28:1, so the button gets
      harder to see at the moment it is being pointed at. The intended white is
      10.4:1. Restated here at a specificity the later rule cannot take back. */
.hero .action:not(.action-secondary):hover,
.band .action:not(.action-secondary):hover,
.closer .action:not(.action-secondary):hover,
.release .action:not(.action-secondary):hover,
.sidebar .action:not(.action-secondary):hover,
.pagehead .action:not(.action-secondary):hover {
  background: #FFFFFF;
  border-color: #FFFFFF;
  color: var(--navy);
}

/* The ghost variant on those grounds keeps its own treatment from layer 82,
   which is a light outline, so it must not be caught by the rule above. */
.hero .action.ghost:not(.action-secondary):hover,
.band .action.ghost:not(.action-secondary):hover,
.closer .action.ghost:not(.action-secondary):hover,
.release .action.ghost:not(.action-secondary):hover,
.sidebar .action.ghost:not(.action-secondary):hover,
.pagehead .action.ghost:not(.action-secondary):hover {
  background: rgba(255, 255, 255, .1);
  border-color: #FFFFFF;
  color: #FFFFFF;
}

/* === layer 84: the published weighting =====================================
   Written by standard-weights.js when a job task analysis finding exists. The
   table carries either what the analysis found or, once a committee has adopted
   it, the weighting of the standard. The page says which, so this only has to
   make eight numbers readable. */

.weights-block { margin: 1.75rem 0 0; }
.weights-table {
  width: 100%; max-width: 34rem; border-collapse: collapse;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: var(--r-md);
  overflow: hidden;
}
.weights-table th, .weights-table td {
  text-align: left; padding: .55rem .85rem; font-size: .95rem;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.weights-table thead th {
  font-family: var(--display); font-size: .7rem; letter-spacing: .14em;
  text-transform: uppercase; color: #C6D2E2; font-weight: 500;
}
.weights-table tbody tr:last-child td { border-bottom: 0; }
.weights-table td.num {
  text-align: right; font-variant-numeric: tabular-nums;
  font-family: ui-monospace, Menlo, Consolas, monospace; color: #FFFFFF;
}
.weights-excl {
  margin: .9rem 0 0; max-width: 40rem; font-size: .88rem; color: #C6D2E2; line-height: 1.6;
}

/* The same table on a light ground, if it is ever placed outside a closer. */
:not(.closer):not(.band) > .weights-block .weights-table {
  background: var(--paper); border-color: var(--rule);
}
:not(.closer):not(.band) > .weights-block .weights-table thead th { color: var(--ink-faint); }
:not(.closer):not(.band) > .weights-block .weights-table td.num { color: var(--ink); }
:not(.closer):not(.band) > .weights-block .weights-excl { color: var(--ink-soft); }
.weights-excl-list {
  margin: .5rem 0 0; padding-left: 1.15rem; max-width: 40rem;
  font-size: .88rem; color: #C6D2E2; line-height: 1.65;
}
.weights-excl-list li { margin: 0 0 .25rem; }
:not(.closer):not(.band) > .weights-block .weights-excl-list { color: var(--ink-soft); }

/* Two site wide table rules reach into this one and break it on a dark ground.
   main tbody tr:nth-child(even) td (nbop.css:1495) and
   table tbody tr:nth-child(even) (nbop.css:3954) paint alternate rows a light
   cream, which on the navy closer produces a row of pale text on pale ground
   that cannot be read at all. The header rule at :3950 fills thead with the
   accent, which is loud for eight numbers whose whole point is to be read
   calmly. Both are answered here rather than weakened where they live, because
   they are right for tables on the page ground. */
.closer .weights-table tbody tr:nth-child(even),
.closer .weights-table tbody tr:nth-child(even) td,
.band .weights-table tbody tr:nth-child(even),
.band .weights-table tbody tr:nth-child(even) td {
  background: rgba(255, 255, 255, .05);
}
.closer .weights-table tbody tr:nth-child(even) td,
.band .weights-table tbody tr:nth-child(even) td { color: #FFFFFF; }
.closer .weights-table thead th,
.band .weights-table thead th {
  background: rgba(255, 255, 255, .10);
  color: #C6D2E2;
}
.closer .weights-table td, .closer .weights-table th,
.band .weights-table td, .band .weights-table th {
  border-color: rgba(255, 255, 255, .14);
}
.closer .weights-table td:first-child,
.band .weights-table td:first-child { color: #FFFFFF; }
