/*
 * Manifest development site.
 *
 * Built to the measured Gallagher visual language in docs/charter/gallagher-visual-language.md.
 * Every value here traces to a measurement in that document rather than to preference. The five
 * rules it names are load bearing and are not to be softened:
 *
 *   1. Zero radius, zero shadow, zero gutter.
 *   2. Navy is ink, not area. It fills type, buttons and tags, and nothing else.
 *   3. Two weights, 300 and 700, with nothing between them. Body copy is the light one.
 *   4. Backgrounds bleed to the viewport; text never touches the edge.
 *   5. Text is never placed over a photograph.
 *
 * Branding is Manifest, not Gallagher Specialty, by instruction of 18 August 2026. The palette
 * stays because it is the house palette; only the marks and the wordmark are ours.
 *
 * The display face on the source is News Gothic, which is licensed. Libre Franklin is its nearest
 * freely licensed relative and is self hosted, so no request leaves the page to a third party.
 */

@font-face {
  font-family: "Libre Franklin";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/libre-franklin-300.woff2") format("woff2");
}
@font-face {
  font-family: "Libre Franklin";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/libre-franklin-400.woff2") format("woff2");
}
@font-face {
  font-family: "Libre Franklin";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/libre-franklin-700.woff2") format("woff2");
}

:root {
  color-scheme: light;

  /* Measured from specialty.ajg.com. Ink, headings and interaction; the fills are set per block
     by the generator and do not appear here. */
  --ink: #00263e;
  --heading: #00325b;
  --interaction: #0075bc;
  --surface: #ffffff;
  --rule: #d8d9da;

  --sans: "Libre Franklin", "Segoe UI", system-ui, -apple-system, Helvetica, Arial, sans-serif;

  /* The measured type scale. Nothing on the page is smaller than 16px. */
  --size-body: 16px;
  --size-button: 18px;
  --size-compact: 20px;
  --size-tile: 28px;
  --size-section: 40px;
  --size-display: 60px;

  /* The measured spacing. 80px is the block module and 57px is the one horizontal constant. */
  --pad-block: 80px;
  --pad-left: 57px;
  --pad-right: 33px;

  --masthead-height: 72px;
}

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

/* The scrollbar is hidden, by instruction of 18 August 2026. The page still scrolls by wheel,
   touch, keyboard and the scrollbar's own keys; only the gutter is gone, which keeps the full
   bleed blocks running edge to edge with nothing cutting into them.

   Stated plainly because it is a real trade: a hidden scrollbar removes the one visual cue that
   tells a reader how much page is left and where in it they are. */
html {
  scrollbar-width: none;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar {
  display: none;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--size-body);
  font-weight: 300;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* A short page, such as the not found page, would otherwise leave its footer stranded halfway up
   the screen with white below it. The column pushes the colophon to the bottom without moving it
   on a page long enough to scroll. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1 0 auto;
}

h1,
h2,
h3 {
  margin: 0;
  color: var(--heading);
  font-weight: 700;
  letter-spacing: 0;
}

p {
  margin: 0;
}

a {
  color: var(--interaction);
}

img {
  max-width: 100%;
  height: auto;
}

/* ---------- masthead ---------- */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: var(--masthead-height);
  padding: 0 var(--pad-left) 0 var(--pad-left);
  border-bottom: 1px solid var(--rule);
}

.masthead__brand {
  display: flex;
  align-items: center;
  line-height: 0;
}

.masthead__brand img {
  height: 30px;
  width: auto;
}

/* The sections of the site, in the masthead on every page, which is where the source puts them
   and the reason the architecture is one click from anywhere. Set like the source's navigation:
   uppercase, letterspaced, no underline, and the page you are on carries the weight. */
.masthead__nav {
  display: flex;
  align-items: center;
  gap: 28px;
}

.masthead__nav a {
  color: var(--ink);
  font-size: var(--size-body);
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-decoration: none;
  white-space: nowrap;
}

.masthead__nav a:hover {
  color: var(--interaction);
}

.masthead__nav a[aria-current="page"] {
  font-weight: 700;
}

.masthead__nav a:focus-visible {
  outline: 2px solid var(--interaction);
  outline-offset: 4px;
}

/* ---------- the tag, after the source's dateline device ---------- */

/* An inline reversed box, not a block. It wraps into two stacked bars of unequal width rather
   than one box with a ragged edge, which is what box-decoration-break buys and is a signature of
   the source. A rounded pill is the wrong component. */
.tag {
  margin: 0 0 18px;
  line-height: 24px;
}

.tag span {
  background: var(--ink);
  color: var(--surface);
  font-size: var(--size-body);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.block--reversed .tag span {
  background: var(--surface);
  color: var(--ink);
}

/* ---------- button ---------- */

/* Square, solid, and it hugs its label. Never full width. */
.button {
  display: inline-block;
  background: var(--ink);
  color: var(--surface);
  font-size: var(--size-button);
  font-weight: 700;
  line-height: 1;
  padding: 12px 20px;
  text-decoration: none;
}

.button:hover {
  background: var(--heading);
}

.button:focus-visible {
  outline: 2px solid var(--interaction);
  outline-offset: 3px;
}

.block--reversed .button {
  background: var(--surface);
  color: var(--ink);
}

/* ---------- hero ---------- */

/* Text in the left half, the right half left white. The source does the same, and the empty half
   is the composition rather than an oversight. */
.hero {
  padding: var(--pad-block) var(--pad-right) var(--pad-block) var(--pad-left);
  max-width: 720px;
}

/* The eyebrow and the standfirst are both a step below the tile size, which is what makes the
   display heading dominate. Judged against the source by two scale-independent measures: the
   ratio of title cap height to body cap height, which is roughly 2.5 to 1 there, and the line
   length of the standfirst, which runs to about 55 characters there against 46 at the larger
   size. */
.hero__eyebrow {
  font-size: var(--size-compact);
  font-weight: 300;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 10px;
}

/* Capitals and bold, because this is a landing page and not an article. The source runs both:
   its section landing sets MARITIME & LOGISTICS in capitals at weight 700, while an article's
   sentence-case H1 is the light weight at the same size. Capitals go bold, sentence case goes
   light, and the article template below keeps the light setting. */
.hero__title {
  font-size: var(--size-display);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.05;
  margin-bottom: 24px;
  /* A single word set in capitals cannot wrap, so on a narrow screen it decides the page width
     and everything scrolls sideways. The size steps below handle the real cases; this is the
     backstop for a title nobody sized for, because a page that scrolls sideways is worse than a
     word broken across two lines. */
  overflow-wrap: break-word;
}

.hero__standfirst {
  font-size: var(--size-compact);
  font-weight: 300;
  line-height: 1.6;
  /* Wider than the title, not narrower. On the source the standfirst runs past the right edge of
     the display heading, which is what makes the heading read as a heading. */
  max-width: 52ch;
  margin-bottom: 32px;
}

/* Where a hero offers more than one way on, as the not found page does. The buttons keep their
   own size and sit on one line until they cannot. */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
}

/* ---------- the mosaic ---------- */

/* Four equal columns of 25vw, zero gutters, full bleed, no page margin. Blocks butt directly
   against each other; a gutter here collapses the publication into a card grid. */
.mosaic {
  display: grid;
  /* minmax(0, 1fr), not 1fr. A bare 1fr track will not shrink below its content's minimum width,
     so a long tag or an unbreakable word pushes the track wider than the viewport and the whole
     page scrolls sideways. Measured at 390px: tracks came out 433px wide inside a 390px page. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
}

/* The photograph sets the row height and the text block stretches to it, which is how the source
   behaves: text is pinned to the top and the slack falls out of the bottom. The ratios are the
   measured ones, 5:3 for the two column lead and portrait for a single column cell, whose rows
   run 435 to 609px against a 360px width on the source. A text block longer than its picture
   grows the row instead. */
.block {
  min-height: 0;
}

.block--lead {
  grid-column: span 2;
}

.block--cell {
  grid-column: span 1;
}

/* The image half of each pair. Text is never placed on it. */
.block--image {
  grid-column: span 2;
  aspect-ratio: 5 / 3;
  background-size: cover;
  background-position: 50% 50%;
}

.block--cell + .block--image {
  grid-column: span 1;
  aspect-ratio: 3 / 4;
}

/* A text block. 80px above and below, 57px in from the left, 33px on the right: the asymmetry is
   measured, not a rounding error. */
.block--lead,
.block--cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: var(--pad-block) var(--pad-right) var(--pad-block) var(--pad-left);
}

.block__title {
  font-size: var(--size-tile);
  line-height: 1.04;
  margin-bottom: 12px;
}

.block--lead .block__title {
  font-size: var(--size-section);
  line-height: 1.05;
}

.block__standfirst {
  font-weight: 300;
  line-height: 1.5;
  margin-bottom: 24px;
}

/* The button follows the copy; the slack falls out of the bottom of the block. The source pins
   text 80px from the top of its row and lets the excess height fall below, rather than spreading
   the contents to fill. */
.block__action {
  margin-top: 8px;
}

.block--reversed,
.block--reversed .block__title,
.block--reversed .block__standfirst {
  color: var(--surface);
}

/* ---------- an entry ---------- */

.article__image {
  height: 420px;
  background-size: cover;
  background-position: 50% 50%;
}

.article__head,
.article__body,
.article__back {
  max-width: 1024px;
  margin: 0 auto;
  padding: 0 24px;
}

.article__head {
  padding-top: var(--pad-block);
  padding-bottom: 24px;
}

.article__title {
  font-size: var(--size-display);
  font-weight: 300;
  line-height: 1.05;
  margin-bottom: 20px;
}

.article__standfirst {
  font-size: var(--size-tile);
  font-weight: 300;
  line-height: 1.6;
  max-width: 34ch;
}

.article__date {
  margin-top: 20px;
  font-size: var(--size-compact);
  font-weight: 300;
  color: var(--ink);
}

.article__body {
  padding-bottom: var(--pad-block);
  border-top: 1px solid var(--rule);
  padding-top: 40px;
}

.article__body h2 {
  font-size: var(--size-compact);
  margin: 40px 0 12px;
}

.article__body h2:first-child {
  margin-top: 0;
}

.article__body p {
  font-weight: 300;
  line-height: 1.5;
  max-width: 70ch;
  margin-bottom: 16px;
}

.article__back {
  padding-bottom: var(--pad-block);
}

/* ---------- figures ---------- */

/* A diagram here is the mosaic at reading size: flat cells of the house fills, butted against
   each other with no gutter, no radius and no shadow, and no arrows. A numbered sequence carries
   its order in the numbers, which are set in the same reversed box the datelines use, so nothing
   decorative had to be invented for it. */
.figure {
  margin: 32px 0 40px;
  max-width: 70ch;
}

.figure__caption {
  font-size: var(--size-body);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink);
  margin-bottom: 12px;
}

.figure__cells {
  display: grid;
  /* Equal columns that will shrink, for the same reason the mosaic uses minmax(0, 1fr): a bare
     1fr track refuses to go below its content and pushes the page sideways. */
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.figure__cell {
  padding: 24px;
  font-weight: 300;
  line-height: 1.5;
}

.figure__cell p {
  margin: 0;
  max-width: none;
}

.figure__cell .tag {
  margin-bottom: 10px;
}

/* The fills cycle so that neighbouring cells differ. As in the mosaic, the tint carries no
   meaning: it separates one cell from the next and nothing more. */
.figure__cell:nth-child(4n + 1) {
  background: #dbeaf7;
}
.figure__cell:nth-child(4n + 2) {
  background: #c5def2;
}
.figure__cell:nth-child(4n + 3) {
  background: #f1eadd;
}
.figure__cell:nth-child(4n + 4) {
  background: #dcdfbb;
}

/* The one conclusion a figure is allowed to draw, ruled off from the parts above it. */
.figure__result {
  border-top: 2px solid var(--ink);
  background: #c5def2;
  padding: 20px 24px;
  font-weight: 700;
}

.article__body .figure__result {
  margin-bottom: 0;
  max-width: none;
  /* Body copy is the light weight, and a paragraph inside the article body would inherit it. The
     result is the one line in a figure that is a conclusion, so it keeps the bold. */
  font-weight: 700;
}

/* ---------- colophon ---------- */

.colophon {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding: 24px var(--pad-left) 40px;
  border-top: 1px solid var(--rule);
}

.colophon__line,
.colophon__restricted {
  font-size: var(--size-body);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.colophon__line {
  color: var(--interaction);
}

.colophon__restricted {
  color: var(--ink);
  font-weight: 300;
  text-transform: none;
  letter-spacing: 0;
}

/* ---------- narrower screens ---------- */

/* The source collapses four columns straight to one at 999px, which leaves a tablet with a phone
   layout and enormous scroll. Section 10 of the visual language records that as a defect we do not
   copy, so there is a two column state here. */
@media (max-width: 1100px) {
  .mosaic {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .block--lead,
  .block--cell,
  .block--image,
  .block--cell + .block--image {
    grid-column: span 1;
  }
  :root {
    --size-display: 45px;
    --pad-block: 56px;
    --pad-left: 40px;
  }
}

@media (max-width: 700px) {
  .mosaic {
    grid-template-columns: minmax(0, 1fr);
  }
  /* The eyebrow scales with the heading. Holding it at full size while the display shrinks makes
     it the largest thing on a phone, which is the source's most visible responsive fault. */
  :root {
    --size-display: 38px;
    --size-tile: 22px;
    --pad-block: 40px;
    --pad-left: 24px;
    --pad-right: 24px;
    --masthead-height: 60px;
  }
  .block {
    min-height: 0;
  }
  /* A min-height against an aspect-ratio makes the box grow its WIDTH to satisfy the ratio, so
     at 390px the image cell came out 433px wide and the page scrolled sideways. On one column the
     ratio has nothing left to decide, so it is dropped and the height stated outright. */
  .block--image {
    aspect-ratio: auto;
    height: 260px;
  }
  /* The wordmark and two section links do not fit on one line on a phone, so the masthead is
     allowed to become two lines rather than shrinking type below the 16px floor. */
  .masthead {
    flex-wrap: wrap;
    height: auto;
    min-height: var(--masthead-height);
    padding-top: 12px;
    padding-bottom: 12px;
    gap: 8px 20px;
  }
  /* Three sections no longer fit on one line beside the wordmark, and a fourth is plausible. The
     nav wraps within itself rather than the type shrinking below the 16px floor, and the row gap
     is tighter than the column gap so a wrapped line reads as the same list rather than a second
     one. Before this the nav was 514px wide inside a 390px screen and every page on the site
     scrolled sideways by 149px. */
  .masthead__nav {
    flex-wrap: wrap;
    gap: 6px 20px;
  }
  .figure__cells {
    grid-template-columns: minmax(0, 1fr);
  }
  .hero__standfirst,
  .article__standfirst {
    max-width: none;
  }
  .colophon {
    padding-left: 24px;
    padding-right: 24px;
  }
}

/* One more step below 400px. "DEVELOPMENT" at 38px runs wider than a 320px screen allows once the
   24px gutters are taken off, and a capitalised word has no break opportunity in it.
   This block sits after the 700px block deliberately: both match on a phone, they have equal
   specificity, and the later one wins. It used to sit before it, so every rule in it was dead and
   the display size on a 390px screen was the 38px this block exists to reduce. */
@media (max-width: 400px) {
  :root {
    --size-display: 30px;
    --pad-left: 20px;
    --pad-right: 20px;
  }
  /* The gutters come off the nav too, so three sections have the best chance of two lines rather
     than three. */
  .masthead__nav {
    gap: 6px 16px;
  }
  .masthead__nav a {
    letter-spacing: 0.03em;
  }
  .colophon {
    padding-left: 20px;
    padding-right: 20px;
  }
}

/*
 * The published roadmap.
 *
 * Generated by ops/tools/dev-site/roadmap-figure.mjs from the plans ledger, so this stylesheet
 * decides how it looks and nothing here decides what it says.
 *
 * The five rules hold: zero radius, zero shadow, zero gutter; navy is ink and the state bars are
 * rules rather than areas; two weights only; the band backgrounds bleed to their own edges. The
 * chart's own type sits below the 16px floor, which is the one place on the site it does. A
 * diagram is read as a picture rather than as running copy, and the alternative is a chart too
 * wide for the page it sits on.
 */

.rm {
  display: flex;
  flex-direction: column;
  gap: 30px;
  max-width: none;
}

.rm-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--size-body);
  font-weight: 300;
}
.rm-legend li {
  display: flex;
  align-items: center;
  gap: 10px;
}
.rm-swatch {
  display: block;
  width: 30px;
  height: 15px;
  border: 1.4px solid var(--rule);
  background: var(--surface);
}
.rm-swatch.rm-done {
  background: #d9ecdd;
  border-color: #4e9a6b;
}
.rm-swatch.rm-progress {
  background: #fbeeca;
  border-color: #c8a127;
}
.rm-swatch.rm-waiting {
  background: #e6ddf4;
  border-color: #8a6cc0;
}
.rm-swatch.rm-open {
  background: #f9dedb;
  border-color: #c97d75;
}

.rm-flow {
  display: flex;
  flex-direction: column;
}
.rm-band {
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 26px 28px 32px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.rm-band-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 26px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 16px;
}
.rm-band-no {
  margin: 0;
  font-size: var(--size-body);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--interaction);
}
.rm-band-name {
  margin: 0;
  font-size: var(--size-tile);
  font-weight: 300;
  color: var(--heading);
  line-height: 1.15;
}
.rm-band-meta {
  text-align: right;
}
.rm-months {
  margin: 0;
  font-size: var(--size-compact);
  font-weight: 700;
  color: var(--ink);
}
.rm-count {
  margin: 0;
  font-size: var(--size-body);
  font-weight: 300;
  color: #5a6b78;
}

.rm-graph {
  display: block;
  width: 100%;
  height: auto;
  font-family: var(--sans);
}
.rm-node rect {
  fill: #f9dedb;
  stroke: #c97d75;
  stroke-width: 1.4;
}
.rm-node.rm-done rect {
  fill: #d9ecdd;
  stroke: #4e9a6b;
}
.rm-node.rm-progress rect {
  fill: #fbeeca;
  stroke: #c8a127;
}
.rm-node.rm-waiting rect {
  fill: #e6ddf4;
  stroke: #8a6cc0;
}

/* Each state carries its own ink, taken from the same family as its fill, so the type sits on its
   own ground rather than borrowing the page's. */
.rm-node text {
  fill: #732e28;
}
.rm-node.rm-done text {
  fill: #1a5236;
}
.rm-node.rm-progress text {
  fill: #6a5008;
}
.rm-node.rm-waiting text {
  fill: #412c6b;
}
.rm-title {
  font-size: 12.5px;
  font-weight: 300;
}
.rm-weeks {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.rm-edge {
  fill: none;
  stroke: #a7b8c4;
  stroke-width: 1.4;
}
.rm-head {
  fill: #a7b8c4;
}

.rm-joint {
  display: flex;
  justify-content: center;
  height: 32px;
}
.rm-joint span {
  display: block;
  width: 1px;
  height: 100%;
  background: var(--rule);
}

@media (max-width: 700px) {
  .rm-band {
    padding: 18px 14px 22px;
  }
  .rm-band-meta {
    text-align: left;
  }
}
