/* DP-10 — the launch page.
 *
 * ONE STYLESHEET, ONE REQUEST, NO FRAMEWORK (PERFORMANCE-BUDGET §5). The reset
 * below is nine lines because that is all a reset needs to be; a reset package
 * would be a dependency in the critical path of the one page every visitor
 * sees.
 *
 * NO LITERAL HEX ANYWHERE BELOW THE @font-face BLOCK. Every colour is a token
 * from ddm-web-tokens.css, which is generated from design/tokens.py, whose
 * ratios contrast.py measures on every test run (IMPLEMENTATION-SPEC §2).
 *
 * NO RADIUS, NO SHADOW, NO FLOATING CARD anywhere on this page (§1). Sections
 * are divided by hairlines and background changes. */

/* --- Faces. `ddm-fonts.css`, linked ahead of this file, declares them. -----
 * They moved there so the Wagtail marketing site could stop fetching the same
 * three families from fonts.googleapis.com while these files sat committed;
 * see that file's header. */

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, p, ul, ol, li, figure, fieldset, legend { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img { max-width: 100%; display: block; }
fieldset { border: 0; min-width: 0; }
button, input, select { font: inherit; color: inherit; }

/* --- Page ----------------------------------------------------------------- */
.ddm-launch {
  background: var(--ddm-white);
  color: var(--ddm-text);
  font-family: var(--ddm-font-ui);
  font-size: 16px;
  line-height: 1.6;
  /* 400% zoom and 320px reflow both depend on nothing here being wider than
   * the viewport. IMPLEMENTATION-SPEC §6 asks for both to be verified; this is
   * the property that makes them pass. */
  overflow-x: hidden;
}

.ddm-sr, .ddm-hp {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* THE SKIP LINK IS NEVER display:none (ACCESSIBILITY-CONTRACT §3) -- it is the
 * first focusable element and it must be reachable, so it is moved off-screen
 * and brought back on focus. */
.ddm-skip {
  position: absolute; left: 0; top: -100%; z-index: 20;
  background: var(--ddm-navy); color: var(--ddm-white);
  padding: 14px 20px; text-decoration: none;
}
.ddm-skip:focus { top: 0; }

/* --- Focus, everywhere, and never replaced by a colour change ------------- */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, .ddm-role input:focus-visible + span,
.ddm-source input:focus-visible + span, [tabindex]:focus-visible {
  outline: var(--ddm-focus-width) solid var(--ddm-focus);
  outline-offset: var(--ddm-focus-offset);
}

/* --- Type ----------------------------------------------------------------- */
.ddm-h1 {
  font-family: var(--ddm-font-display), "Instrument Fallback", Georgia, serif;
  font-weight: 400; font-size: 74px; line-height: 1.0; letter-spacing: -.022em;
}
/* The two H1 accents. ITALIC AS WELL AS COLOUR (ACCESSIBILITY-CONTRACT §2):
 * "the sentence reads identically without either". The teal is legal here and
 * only here -- 3.03:1 clears the large-text threshold at 74px/38px and fails
 * everywhere smaller. */
.ddm-h1__blue { font-style: italic; color: var(--ddm-blue); }
.ddm-h1__teal { font-style: italic; color: #1FA694; }

.ddm-h2 {
  font-family: var(--ddm-font-display), "Instrument Fallback", Georgia, serif;
  font-weight: 400; font-size: 66px; line-height: 1.02; letter-spacing: -.02em;
}
/* THE TWO ACTS WHOSE HEADING THE BOARD SETS SMALLER. 10-A draws the H2 at 66px
 * in four acts, at 62px in "Build interactive WordPress maps..." (62/1.03) and
 * "What you can build with it." (62/1.04), and at 74 in the closing act. The
 * two 62s are one class here; a 0.01 difference in leading is 0.6px a line and
 * naming it would be precision the drawing does not have.
 *
 * The two measures are the board's as well, and they are what keeps those
 * headings off the column beside them. */
.ddm-h2--sm { font-size: 62px; line-height: 1.03; }
.ddm-act__head--cases .ddm-h2 { max-width: 700px; }
.ddm-act__head--roster .ddm-h2 { max-width: 640px; }
.ddm-lede { font-size: 19px; line-height: 1.62; color: var(--ddm-text-muted); }
/* 15.5px IS THE BODY SIZE INSIDE EVERY GRID CELL on 10-A; the paragraph that
 * sits BESIDE an H2 in an act head is 17.5/1.64 and is set below. The page
 * used to run one 16.5px size for both, which made every cell taller than the
 * board and every head paragraph shorter -- the reason six of the eight acts
 * measured a different height from their artboard. */
.ddm-body { font-size: 15.5px; line-height: 1.6; color: var(--ddm-text-muted); }
.ddm-eyebrow, .ddm-label, .ddm-num {
  font-family: var(--ddm-font-mono); font-weight: 500; font-size: 10.5px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--ddm-text-label);
}
/* The smaller mono label: 10px/.16em, used where the board sets it that way --
 * the licensing class labels, the roster column headings and the use-case
 * numerals. */
.ddm-label--sm { font-size: 10px; letter-spacing: .16em; }
/* SUB-HEADS ARE NOT BODY COPY AND DO NOT TAKE THE BODY'S LEADING. The page sets
 * 1.6 on `.ddm-launch` and every H3 inherited it, so a 19-21px heading occupied
 * 30-34px of vertical space against the board's ~23-25. Four acts are built out
 * of cells with an H3 at the top of each, so the error compounded down the page
 * -- and it is also just loose: a one-line heading with 1.6 leading reads as a
 * paragraph that happens to be bold. */
.ddm-panel__title, .ddm-step__title, .ddm-case__title, .ddm-model__title {
  line-height: 1.25;
}
/* BOTH PULL QUOTES SIT UNDER A HAIRLINE on 10-A, and neither runs the width
 * of the act. Without the rule and the measure the line reads as a stray
 * sentence at the end of a section rather than the close of an argument. */
.ddm-pull {
  font-family: var(--ddm-font-display), "Instrument Fallback", Georgia, serif;
  font-size: 38px; line-height: 1.18; letter-spacing: -.014em;
  color: var(--ddm-text); max-width: 720px;
  margin-top: 72px; padding-top: 40px; border-top: 1px solid var(--ddm-rule-alt);
}
.ddm-pull--navy {
  color: var(--ddm-white); max-width: 780px; font-size: 34px; line-height: 1.2;
  margin-top: 52px; padding-top: 36px; border-top-color: var(--ddm-web-navy-rule);
}

/* --- Acts ----------------------------------------------------------------- */
.ddm-act {
  padding: 100px 56px 96px;
  border-top: 1px solid var(--ddm-rule);
}
.ddm-act--tint { background: var(--ddm-tint); }
.ddm-act--navy { background: var(--ddm-navy); color: var(--ddm-on-navy); }
.ddm-act--navy .ddm-h2 { color: var(--ddm-white); }
.ddm-act--navy .ddm-body { color: var(--ddm-on-navy); }
.ddm-act--navy .ddm-eyebrow, .ddm-act--navy .ddm-label { color: var(--ddm-on-navy-muted); }
/* TWO CHILDREN, ALWAYS. An act with an eyebrow has three -- eyebrow, heading,
 * paragraph -- and a two-column grid then puts the heading in the RIGHT column
 * and the paragraph under the eyebrow on the left, which is what the first
 * render of this page actually did on three of the nine acts. The eyebrow and
 * its heading are one title block; the paragraph is the other column, and where
 * that column holds two things (act 6's paragraph and its note) they are wrapped
 * in `.ddm-act__aside` for the same reason.
 *
 * THE GAP BELOW A HEAD IS PART OF THE HEAD, not a margin on whatever follows.
 * 10-A gives each act its own measure and its own gap and they are not the same
 * act to act; carrying them as modifiers keeps the numbers next to the board
 * they came from instead of scattered across six content blocks. */
.ddm-act__head {
  display: grid; grid-template-columns: 1fr 500px; gap: 80px;
  align-items: end; margin-bottom: 60px;
}
.ddm-act__head--wide { grid-template-columns: 1fr 460px; margin-bottom: 76px; }
.ddm-act__head--practice { margin-bottom: 64px; }
.ddm-act__head--roster { grid-template-columns: 1fr 520px; align-items: start; }
.ddm-act__head--cases {
  display: flex; align-items: end; justify-content: space-between;
  margin-bottom: 56px;
}
.ddm-act__head--cases .ddm-body { font-size: 16.5px; max-width: 420px; }
.ddm-act__title > .ddm-eyebrow { margin-bottom: 26px; }
/* The paragraph beside an H2 is the one place body copy is 17.5px. */
.ddm-act__head .ddm-body { font-size: 17.5px; line-height: 1.64; }
.ddm-act__head .ddm-lede { max-width: 560px; }

/* The four-hue rule. SPECTRUM ORDER IS THE MEANING and it always ascends. */
.ddm-rule4 { display: flex; height: 3px; margin: 0; }
.ddm-rule4 span { flex: 1; }

/* --- In-page movement ------------------------------------------------------
   EVERY DESTINATION ON THIS PAGE IS AN ANCHOR. The header's three nav items,
   both hero CTAs, the sticky bar and the sheet all point at `#section`, so the
   whole navigation of the page was a hard jump: the viewport replaced itself
   and gave the reader no sense of having travelled. Smooth scrolling is the
   default here for that reason, not for decoration.

   TURNED OFF UNDER `prefers-reduced-motion`, below, because scroll animation is
   exactly the vestibular trigger that media query exists for -- and the jump is
   the correct behaviour for somebody who asked for no motion, not a degraded
   one. */
html { scroll-behavior: smooth; }

/* --- Header --------------------------------------------------------------- */
.ddm-lheader { border-bottom: 1px solid var(--ddm-rule); }
.ddm-lheader__rule { display: flex; height: 3px; width: 396px; max-width: 100%; }
.ddm-lheader__rule span { flex: 1; }
/* THE CTA RUNS TO THE RIGHT EDGE. 10-A pads the bar on the left only and lets
 * the button fill the bar's full height against the viewport edge, which is
 * what makes the header read as a band rather than as a row of objects. */
.ddm-lheader__bar {
  display: flex; align-items: stretch; justify-content: space-between;
  height: 74px; padding: 0 0 0 56px;
}
.ddm-lheader__left { display: flex; align-items: center; gap: 36px; }
/* The 1px divider between the mark and the nav -- the one piece of DP-9's
 * header chrome 10-A keeps. */
.ddm-lheader__div { width: 1px; height: 26px; background: var(--ddm-rule); flex: none; }
/* The approved horizontal logo at the board's own measurements: 10-A draws it
   206x44 at 1440, 10-C 161x34 at 390. `height:auto` is deliberate -- the SVG
   carries its own ratio and a fixed pair here would distort it if the artwork
   is ever re-cut. */
/* THE MARK IS DRAWN THROUGH A WINDOW, which is how both artboards place it:
 * the SVG carries its own margin, and 10-A sets a 194x33 window over a 206x43.5
 * image offset -6/-6.2 so the wordmark's own edges -- not the file's padding --
 * sit on the header's baseline grid. Rendering the file at its nominal size
 * instead leaves the mark floating a few pixels high and small. */
.ddm-lheader__mark {
  display: block; position: relative; flex: none;
  width: 194px; height: 33px; overflow: hidden;
}
.ddm-lheader__mark img {
  position: absolute; top: -6.2px; left: -6px;
  width: 206px; height: 43.5px; max-width: none;
}
.ddm-lheader__nav ul { display: flex; align-items: center; gap: 28px; }
/* NO STANDING UNDERLINE. These are section anchors inside the page's own
 * chrome, not links into prose: 10-A draws them as plain 14.5/500 navy with a
 * 1.5px rule that appears on hover, and a permanent blue rule under all three
 * made the header look like a list of footnotes. */
.ddm-lheader__nav a {
  font-size: 14.5px; font-weight: 500; color: var(--ddm-text);
  text-decoration: none; padding: 4px 0;
  border-bottom: 1.5px solid transparent;
}
.ddm-lheader__nav a:hover { border-bottom-color: var(--ddm-text); }
.ddm-lheader__cta { margin-left: auto; }
.ddm-lheader__menu { display: none; background: none; border: 0; margin-left: auto;
  width: 44px; height: 44px; font-size: 22px; cursor: pointer; }
.ddm-sheet { border-top: 1px solid var(--ddm-rule); padding: 8px 20px 20px; }
.ddm-sheet ul a, .ddm-sheet ul .ddm-unavailable {
  display: block; min-height: 56px; line-height: 56px;
  color: var(--ddm-text); text-decoration: none;
  border-bottom: 1px solid var(--ddm-rule); }
.ddm-sheet ul li:first-child a { font-size: 18px; font-weight: 500; }
.ddm-sheet__cta { display: flex; width: 100%; margin-top: 18px; }

/* --- Buttons. Rectangles, nowrap, flex:none (VISUAL-SYSTEM §3). ----------- */
.ddm-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  height: 56px; padding: 0 32px; background: var(--ddm-navy);
  color: var(--ddm-white); text-decoration: none; border: 0;
  font-size: 16px; font-weight: 600; cursor: pointer;
  white-space: nowrap; flex: none;
  transition: background-color 120ms;
}
.ddm-btn:hover { background: var(--ddm-blue); }
/* The arrow rides the label; it is drawn in `currentColor` so the hover fill
 * carries it, and it is aria-hidden because it says nothing the label does not. */
.ddm-btn svg, .ddm-hero__link svg { flex: none; }
.ddm-lheader__cta { height: 74px; font-size: 14.5px; padding: 0 34px; gap: 11px; }
/* THE SECOND HERO ACTION IS A LINK, NOT A SECOND BUTTON. 10-A draws it as
 * underlined blue text with a down-arrow -- the arrow is the point, because the
 * destination is further down this same page. Two buttons side by side make two
 * equal offers, and only one of them is the thing this page is asking for. */
.ddm-hero__link {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 16px; font-weight: 500; color: var(--ddm-blue-700);
  text-decoration: none; padding-bottom: 3px;
  border-bottom: 1.5px solid var(--ddm-web-link-rule);
  transition: border-color 120ms;
}
.ddm-hero__link:hover { border-bottom-color: var(--ddm-blue-700); }
.ddm-btn[aria-disabled="true"] { background: var(--ddm-text-muted); cursor: progress; }

/* --- Hero ----------------------------------------------------------------- */
/* NO GUTTER BETWEEN THE COLUMNS. 10-A butts the image column against the copy
 * column at exactly 700px and separates them with a hairline; the padding lives
 * on the copy, not on the section. The page carried a 56px grid gap as well,
 * which pushed the image to 812 and left a band of white doing nothing. */
.ddm-hero { padding: 0; border-top: 0; }
.ddm-hero__inner { display: grid; grid-template-columns: 700px 1fr; gap: 0; align-items: start; }
.ddm-hero__copy { padding: 96px 64px 88px 56px; }
.ddm-hero__copy .ddm-h1 { margin-bottom: 32px; }
.ddm-hero__copy .ddm-lede { margin-bottom: 20px; }
.ddm-hero__support { font-size: 19px; line-height: 1.62; margin-bottom: 38px; }
.ddm-hero__copy .ddm-lede, .ddm-hero__support { max-width: 560px; }
/* The availability statement: 16.5px/500 behind a 3px Electric Blue left rule,
 * between the description and the CTA row. Stated once, nowhere else. */
.ddm-availability {
  font-size: 16.5px; line-height: 1.55; font-weight: 500; color: var(--ddm-text);
  border-left: 3px solid var(--ddm-blue); padding: 16px 0 16px 20px;
  max-width: 560px; margin-bottom: 34px;
}
.ddm-hero__cta { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }
.ddm-hero__figure {
  position: relative; align-self: stretch; min-height: 660px;
  background: var(--ddm-tint); border-left: 1px solid var(--ddm-rule);
}
.ddm-hero__figure picture, .ddm-hero__figure img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: left top;
}
/* The caption band sits BELOW the border, not over the image (§5). */
.ddm-hero__figure figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: rgba(20, 33, 54, .92); color: var(--ddm-on-navy);
  font-family: var(--ddm-font-mono); font-size: 11px; padding: 16px 24px;
}

/* --- Steps ---------------------------------------------------------------- */
.ddm-steps { display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 0; }
.ddm-step { padding: 30px 34px 0 0; border-right: 1px solid var(--ddm-rule-alt); }
.ddm-step:last-child { border-right: 0; padding-right: 0; }
.ddm-step + .ddm-step { padding-left: 34px; }
/* THE HUE SWATCH, which the page did not draw at all. 10-A opens every step
 * with an 11px square in that step's colour, above the numeral; the shared
 * spectrum rule across the top of the grid is what the four squares line up
 * with. Decorative, so it is a pseudo-element and never reaches the
 * accessibility tree -- the numeral and the heading carry the sequence. */
.ddm-step::before {
  content: ""; display: block; width: 11px; height: 11px;
  background: var(--ddm-blue); margin-bottom: 24px;
}
.ddm-step--sky::before { background: var(--ddm-sky); }
.ddm-step--teal::before { background: var(--ddm-teal); }
.ddm-step--green::before { background: var(--ddm-green); }
/* The numeral takes the step's own hue, at its text-legible weight. */
.ddm-step .ddm-num { display: block; color: var(--ddm-blue-700); margin-bottom: 12px; }
.ddm-step--sky .ddm-num { color: var(--ddm-sky-text); }
.ddm-step--teal .ddm-num { color: var(--ddm-teal-text); }
.ddm-step--green .ddm-num { color: var(--ddm-green-text); }
.ddm-step__title { font-size: 21px; font-weight: 600; letter-spacing: -.01em; margin: 0 0 12px; }

/* --- Search intent --------------------------------------------------------
 * THE RULE IS UNDER THE LABEL, NOT OVER IT. 10-A hangs the 2px hue rule off
 * the bottom of the mono label so the label names the column and the rule
 * opens the list; the page had the rule above, which reads as a divider
 * belonging to the act rather than a heading belonging to the column. */
.ddm-intent { display: grid; grid-template-columns: 1fr 1fr; gap: 0 80px; margin-top: 0; }
.ddm-intent .ddm-label {
  display: block; padding-bottom: 14px; margin-bottom: 4px;
  border-bottom: 2px solid var(--ddm-blue); color: var(--ddm-blue-700);
}
.ddm-intent__col--to .ddm-label { border-bottom-color: var(--ddm-green); color: var(--ddm-green-text); }
/* 1.35, NOT THE PAGE'S 1.6. Each of these is one line and the board sets no
 * leading on them at all, so they take the face's `normal` -- about 1.35 for
 * IBM Plex Sans. Written explicitly rather than as `normal` so a fallback face
 * cannot change the row height, which is the whole geometry of this act. */
.ddm-intent li {
  font-size: 16.5px; line-height: 1.35; padding: 15px 0; color: var(--ddm-text);
  border-bottom: 1px solid var(--ddm-rule-alt);
}
.ddm-intent__closing {
  margin-top: 44px; max-width: 780px; line-height: 1.62; color: var(--ddm-text-soft);
}

/* --- Proof panels ----------------------------------------------------------
 * FOUR CARDS IN A 2x2, EACH WITH ITS CAPTION UNDER ITS OWN IMAGE. 10-A draws
 * two rows of two bordered cards; the ratio alternates BETWEEN THE ROWS
 * (1.55:1, then 1:1.55) so the eye crosses the act rather than running down
 * one edge.
 *
 * The page had read that alternation as a rule about each panel and built four
 * full-width image-beside-text bands instead. Same numbers, different object:
 * the act ran 2041px against the board's 1401 -- 46% taller, and the single
 * largest visual divergence on the page. A caption belongs to the picture
 * above it, which is also why the card carries the border and the figure no
 * longer does. */
.ddm-panels { display: grid; gap: 40px; margin-top: 0; }
.ddm-panels__row { display: grid; gap: 40px; }
.ddm-panels__row--wide { grid-template-columns: 1.55fr 1fr; }
.ddm-panels__row--narrow { grid-template-columns: 1fr 1.55fr; }
.ddm-panel { border: 1px solid var(--ddm-rule); background: var(--ddm-white); }
.ddm-panel__figure { background: var(--ddm-tint); height: 384px; overflow: hidden; }
.ddm-panel__figure img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }
.ddm-panel__copy { padding: 22px 26px 26px; border-top: 1px solid var(--ddm-rule); }
.ddm-panel__title { font-size: 19px; font-weight: 600; margin-bottom: 8px; }

/* --- Use cases -------------------------------------------------------------
 * NO OUTER BOX. 10-A rules the top of the grid and between its columns and
 * under each row, and stops there -- the first cell's copy starts on the act's
 * own left margin. The page had a left border as well, which boxed the grid in
 * and stole 34px of measure from the first column, wrapping its two lines
 * onto three. */
.ddm-cases {
  display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 0;
  border-top: 1px solid var(--ddm-rule-alt);
}
.ddm-case {
  padding: 34px 40px; border-left: 1px solid var(--ddm-rule-alt);
  border-bottom: 1px solid var(--ddm-rule-alt);
}
.ddm-case:nth-child(3n+1) { padding-left: 0; border-left: 0; }
.ddm-case:nth-child(3n) { padding-right: 0; }
.ddm-cases .ddm-num { display: block; margin-bottom: 14px; }
.ddm-case__title { font-size: 20px; font-weight: 600; margin: 0 0 10px; }

/* --- Roster ----------------------------------------------------------------
 * THE NOTE IS THE SECOND HALF OF THE RIGHT-HAND COLUMN, not a band under the
 * head. 10-A stacks it beneath the act's supporting paragraph inside the same
 * 520px column, 22px below it; the page floated it across 900px of the act,
 * where it read as an announcement rather than as the small print belonging to
 * the paragraph above it. */
/* The paragraph and the note are ONE column with 22px between them (10-A). */
.ddm-act__aside { display: flex; flex-direction: column; gap: 22px; }
.ddm-note { padding: 20px 22px; border: 1px solid var(--ddm-web-navy-rule); }
.ddm-note p { color: var(--ddm-on-navy-soft); font-size: 14.5px; line-height: 1.62; }
.ddm-note .ddm-label { color: var(--ddm-blue-300); margin-bottom: 10px; }
.ddm-note strong { font-weight: 600; color: var(--ddm-white); }
.ddm-roster {
  display: grid; grid-template-columns: repeat(6, 1fr);
  margin-top: 0; border-top: 1px solid var(--ddm-web-navy-rule);
}
.ddm-roster__col { padding: 28px 24px 30px 0; border-right: 1px solid var(--ddm-web-navy-rule); }
.ddm-roster__col:last-child { border-right: 0; padding-right: 0; }
/* A GAPPED GRID, not padded rows: 10-A stacks the names with an 11px gap, so
 * the space is BETWEEN them and not also above the first and below the last. */
.ddm-roster ul { display: grid; gap: 11px; }
.ddm-roster li { color: var(--ddm-white); font-size: 15px; line-height: 1.35; padding: 0; }
.ddm-roster h3 { margin-bottom: 18px; }

/* --- Licensing -------------------------------------------------------------
 * RULED, NOT GAPPED. 10-A divides the four classes with hairlines the way
 * every other grid on the page is divided; the page separated them with 40px
 * of air and no rules at all, which is the one act where the reader has to
 * compare cells against each other. */
.ddm-model {
  display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 0;
  margin-bottom: 56px; border-top: 1px solid var(--ddm-rule-alt);
}
.ddm-model__part { padding: 30px 32px 32px; border-left: 1px solid var(--ddm-rule-alt); }
.ddm-model__part:first-child { padding-left: 0; border-left: 0; }
.ddm-model__part:last-child { padding-right: 0; }
.ddm-model .ddm-label { display: block; margin-bottom: 16px; }
.ddm-model__title { font-size: 21px; font-weight: 600; margin: 0 0 10px; }
.ddm-commit {
  display: grid; grid-template-columns: 300px 1fr; gap: 64px;
  margin-top: 0; padding-top: 44px; border-top: 1px solid var(--ddm-rule-alt);
}
.ddm-commit__head {
  font-family: var(--ddm-font-display), "Instrument Fallback", Georgia, serif;
  font-weight: 400; font-size: 34px; line-height: 1.1; letter-spacing: -.014em;
}
.ddm-commit ul { display: grid; grid-template-columns: 1fr 1fr; gap: 0 56px; }
/* Each commitment is a ruled row led by a 7px square in its own hue -- the
 * same four-colour sequence the page opens with, closing it. The square is
 * decorative: it repeats nothing, and the sentence beside it is the whole
 * commitment. */
.ddm-commit li {
  display: flex; gap: 14px; padding: 16px 0;
  border-bottom: 1px solid var(--ddm-rule-alt);
}
.ddm-commit li::before {
  content: ""; width: 7px; height: 7px; margin-top: 8px; flex: none;
  background: var(--ddm-blue);
}
.ddm-commit li:nth-child(2)::before { background: var(--ddm-sky); }
.ddm-commit li:nth-child(3)::before { background: var(--ddm-teal); }
.ddm-commit li:nth-child(4)::before { background: var(--ddm-green); }
.ddm-commit li strong { font-weight: 600; color: var(--ddm-text); }

/* --- Intake --------------------------------------------------------------- */
.ddm-intake { display: grid; grid-template-columns: 1fr 620px; gap: 80px; align-items: start; }
/* THE CLOSING HEADING IS H1-SIZED. 10-A sets it at 74/1.0 -- the only H2 on the
 * page that matches the hero -- because the act is the page's one ask. */
.ddm-intake__copy .ddm-h2 { font-size: 74px; line-height: 1; letter-spacing: -.022em; margin-bottom: 30px; }
.ddm-intake__lede {
  font-size: 18px; line-height: 1.62; color: var(--ddm-on-navy);
  max-width: 480px; margin-bottom: 38px;
}
/* The two promises are RULED ROWS with the spectrum's first two hues, not two
 * loose paragraphs: they are what the visitor is being asked to trust, and the
 * left column has to hold its own beside a 620px form panel. */
.ddm-intake__promises { max-width: 500px; }
.ddm-intake__promises li {
  display: flex; gap: 14px; padding: 18px 0;
  border-top: 1px solid var(--ddm-web-navy-rule);
  font-size: 15.5px; line-height: 1.6; color: var(--ddm-on-navy);
}
.ddm-intake__promises li:last-child { border-bottom: 1px solid var(--ddm-web-navy-rule); }
.ddm-intake__promises li::before {
  content: ""; width: 7px; height: 7px; margin-top: 8px; flex: none;
  background: var(--ddm-blue);
}
.ddm-intake__promises li:nth-child(2)::before { background: var(--ddm-sky); }
.ddm-intake__copy strong { font-weight: 600; color: var(--ddm-white); }
.ddm-intake__panel { background: var(--ddm-white); color: var(--ddm-text); padding: 40px 44px 44px; }

.ddm-field + .ddm-field, .ddm-field + .ddm-fieldset,
.ddm-fieldset + .ddm-field, .ddm-fieldset + .ddm-fieldset { margin-top: 26px; }
/* 1.3, not the page's 1.6: a field label is one line and the board leaves its
 * leading at `normal`. At 1.6 each of the five labels stood 4px taller than
 * the board draws it, which is 20px of drift down a single form panel. */
.ddm-field label, .ddm-fieldset legend {
  display: block; font-size: 14px; line-height: 1.3; font-weight: 600;
  margin-bottom: 9px;
}
.ddm-fieldset--sources legend { margin-bottom: 4px; }
/* REQUIRED AND OPTIONAL ARE WRITTEN IN WORDS as well as being programmatic.
 * No asterisk convention, "which needs a key nobody reads". */
.ddm-tag {
  font-family: var(--ddm-font-mono); font-weight: 500; font-size: 9px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ddm-text-label);
  margin-left: 8px;
}
.ddm-help { font-size: 13px; line-height: 1.5; color: var(--ddm-text-soft); margin-bottom: 13px; }

.ddm-field input[type="text"], .ddm-field input[type="email"], .ddm-field select {
  width: 100%; height: 50px; padding: 0 14px;
  border: 1.5px solid var(--ddm-web-control-border); background: var(--ddm-white);
  font-size: 15.5px;
}
.ddm-field input:hover, .ddm-field select:hover { border-color: var(--ddm-navy); }
.ddm-field--invalid input, .ddm-field--invalid select { border-color: var(--ddm-web-error-strong); }
.ddm-field__error { color: var(--ddm-web-error-text); font-size: 14px; margin-top: 8px; }

.ddm-roles { display: flex; flex-wrap: wrap; gap: 10px; }
.ddm-role { display: inline-flex; align-items: center; }
.ddm-role input, .ddm-source input {
  position: absolute; opacity: 0; width: 1px; height: 1px;
}
.ddm-role span {
  display: inline-flex; align-items: center; height: 44px; padding: 0 18px;
  border: 1.5px solid var(--ddm-web-control-border); font-size: 15px;
}
/* SELECTION IS NOT CARRIED BY COLOUR ALONE: the fill AND font-weight 500 AND
 * the checked radio underneath (ACCESSIBILITY-CONTRACT §2). */
.ddm-role input:checked + span {
  background: var(--ddm-navy); border-color: var(--ddm-navy);
  color: var(--ddm-white); font-weight: 500;
}

.ddm-sources { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 20px; }
/* "Something else" AND ITS FREE-TEXT BOX SHARE A ROW. 10-A puts the box beside
 * the tick rather than under a second label of its own; the page spent a whole
 * labelled field on it, which is the single largest reason the form panel ran
 * 300px past the copy column beside it. */
.ddm-sources__other {
  display: grid; grid-template-columns: auto 1fr; align-items: center;
  gap: 11px; margin-top: 13px;
}
.ddm-sources__other .ddm-source { margin: 0; }
.ddm-sources__other input[type="text"] {
  width: 100%; height: 44px; padding: 0 13px; font-size: 14.5px;
  border: 1.5px solid var(--ddm-rule); background: var(--ddm-tint);
}
.ddm-sources__other input[type="text"]:hover { border-color: var(--ddm-navy); }
.ddm-sources__other .ddm-sr-label { position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ddm-source { display: flex; align-items: center; gap: 12px; min-height: 44px; font-size: 15px; }
.ddm-source span { position: relative; padding-left: 30px; }
.ddm-source span::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; border: 1.5px solid var(--ddm-web-control-border);
  background: var(--ddm-white);
}
.ddm-source input:checked + span::before {
  background: var(--ddm-navy); border-color: var(--ddm-navy);
}
/* The tick: 11x8, white, 1.8px, round caps. A GLYPH as well as a fill. */
.ddm-source input:checked + span::after {
  content: ""; position: absolute; left: 4px; top: 50%; width: 11px; height: 8px;
  transform: translateY(-60%) rotate(-45deg);
  border-left: 1.8px solid var(--ddm-white); border-bottom: 1.8px solid var(--ddm-white);
  border-radius: 1px;
}
/* THE BUTTON COMES FIRST AND THE NOTICE EXPLAINS IT. 10-A puts the submit
 * above the privacy sentence, 16px apart, with 6px of air above the pair; the
 * page had the sentence first, so the last thing before the action was a
 * paragraph about data retention. The button is sized to its label, not to the
 * panel -- a 532px-wide button is not a button, it is a bar. */
.ddm-submit { display: flex; flex-direction: column; gap: 16px; padding-top: 6px; margin-top: 26px; }
.ddm-submit .ddm-btn { align-self: start; padding: 0 34px; }
.ddm-privacy { font-size: 13px; line-height: 1.55; color: var(--ddm-text-soft); margin: 0; }
.ddm-privacy a { color: var(--ddm-blue-700); border-bottom: 1px solid var(--ddm-web-link-rule); text-decoration: none; }

/* --- States --------------------------------------------------------------- */
.ddm-summary, .ddm-panel-error {
  background: var(--ddm-web-error-tint); border: 1px solid var(--ddm-web-error-border);
  border-left: 4px solid var(--ddm-web-error-strong); padding: 20px 24px; margin-bottom: 28px;
  color: var(--ddm-web-error-body); font-size: 14.5px;
}
.ddm-summary__head, .ddm-panel-error__head {
  color: var(--ddm-web-error-text); font-size: 16px; font-weight: 600; margin-bottom: 10px;
}
.ddm-summary li { margin-top: 6px; }
.ddm-summary a {
  color: var(--ddm-web-error-text);
  border-bottom: 1px solid var(--ddm-web-error-rule);
}
.ddm-panel-error p + p { margin-top: 8px; }

/* --- The recorded panel (B4 / B5) ------------------------------------------
 * ONE SURFACE CHANGE, ONE COLOUR RESET. `.ddm-intake__panel` is a WHITE island
 * inside `.ddm-act--navy`, and the act's descendant rules do not know that:
 * `.ddm-act--navy .ddm-body` painted ON_NAVY onto the panel's WHITE. Measured
 * on the running site at 1.53:1 -- the four paragraphs of the recorded panel,
 * reported from production as "very light text on a white background".
 *
 * Nothing else showed it because B4 and B5 are the ONLY body copy this panel
 * ever draws; the form state has labels, help text and a privacy notice, each
 * with a colour of its own. So the reset is declared where the surface changes
 * -- at the panel -- and restores the page's own light-surface value rather
 * than choosing a new one: `.ddm-body` is TEXT_MUTED on every other white
 * ground in this file. contrast.py measures that pair at 7.50:1.
 *
 * The mailto in B4_CHANGE was the browser's own #0000EE, the one colour on
 * this page that came from no token at all. It takes the treatment
 * `.ddm-privacy a` already carries: BLUE_700 on white, 6.51:1, underlined by a
 * rule rather than by `text-decoration`. */
.ddm-intake__panel .ddm-body { color: var(--ddm-text-muted); }
.ddm-outcome a {
  color: var(--ddm-blue-700); border-bottom: 1px solid var(--ddm-web-link-rule);
  text-decoration: none;
}

.ddm-outcome > * + * { margin-top: 16px; }
.ddm-outcome__label {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--ddm-font-mono); font-weight: 500; font-size: 10.5px;
  letter-spacing: .16em; text-transform: uppercase; margin-top: 28px;
}
.ddm-mark { width: 12px; height: 12px; flex: none; }
.ddm-mark--green { background: var(--ddm-green); }
.ddm-mark--sky { background: var(--ddm-sky); }
/* GREEN as the mark, GREEN_TEXT as the label: the pure hue is a fill, the
 * darkened variant is type. */
.ddm-outcome--success .ddm-outcome__label { color: var(--ddm-green-text); }
.ddm-outcome--already .ddm-outcome__label { color: var(--ddm-sky-text); }
.ddm-outcome__head {
  font-family: var(--ddm-font-display), "Instrument Fallback", Georgia, serif;
  font-weight: 400; font-size: 46px; line-height: 1.05;
}
/* THE HEADING DRAWS NO RING, IN EITHER FOCUS STATE. Script moves focus here
 * after a submit (ddm-launch.js §4) so the outcome is announced; the element
 * is tabindex="-1", so no keyboard user can Tab to it and 2.4.7 has nothing
 * to indicate. Chromium treats a script focus on a freshly loaded document as
 * keyboard-initiated and matched :focus-visible, which drew a blue rectangle
 * around a 46px heading -- the one line a visitor reads after handing over
 * their address (owner, 2026-09-05, Gmail and Proton renders). Every control
 * a keyboard can reach keeps the ring above; ACCESSIBILITY-CONTRACT §4 records
 * this as its one exception and test_launch_page.py holds `outline: none` to
 * these two selectors alone. Later in the file than the shared ring rule on
 * purpose: equal specificity, so source order decides. */
.ddm-outcome__head:focus,
.ddm-outcome__head:focus-visible { outline: none; }

/* --- Sticky CTA. Never in the served HTML's flow; revealed by script. ----- */
.ddm-sticky {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 15;
  display: none; align-items: center; gap: 16px;
  background: var(--ddm-white); border-top: 3px solid var(--ddm-blue);
  padding: 12px 20px;
  transform: translateY(100%); transition: transform 120ms;
}
.ddm-sticky[data-shown="1"] { transform: translateY(0); }
.ddm-sticky p { font-size: 13.5px; line-height: 1.35; color: var(--ddm-text); }
.ddm-sticky .ddm-btn { height: 46px; margin-left: auto; }

/* --- Footer --------------------------------------------------------------- */
/* --- Footer ----------------------------------------------------------------
 * TWO BLOCKS, NOT ONE STACK. 10-A sets the brand and the legal links across
 * from each other, then rules off a base row that carries the spectrum and the
 * copyright. The page stacked all four in a single column with the spectrum
 * loose at the bottom, which is the composition the owner read as unfinished --
 * nothing was wrong in it, but nothing was placed either. */
.ddm-lfooter { background: var(--ddm-footer); color: var(--ddm-on-footer); padding: 56px 56px 0; }
.ddm-lfooter__top {
  display: flex; align-items: start; justify-content: space-between; gap: 64px;
  padding-bottom: 44px;
}
.ddm-lfooter__mark {
  display: block; position: relative; width: 153px; height: 26px;
  overflow: hidden; margin-bottom: 16px;
}
.ddm-lfooter__mark img {
  position: absolute; top: -4.9px; left: -4.7px;
  width: 162px; height: 34.2px; max-width: none;
}
.ddm-lfooter__line { max-width: 380px; font-size: 14.5px; line-height: 1.6; }
.ddm-lfooter nav ul { display: flex; align-items: center; gap: 26px; }
.ddm-lfooter nav a, .ddm-lfooter nav .ddm-unavailable {
  font-size: 14px; color: var(--ddm-on-footer-link); text-decoration: none;
}
.ddm-lfooter nav a:hover { color: var(--ddm-white); }
/* The base row. The spectrum is INLAID ON THE RULE rather than parked under the
 * copyright: 232px of colour replacing the first 232px of the hairline. */
.ddm-lfooter__base {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  padding: 22px 0 30px; border-top: 1px solid var(--ddm-web-footer-rule);
}
.ddm-lfooter__copy { font-size: 13.5px; }
/* DP-9's 232px spectrum rule over the bottom border. */
.ddm-lfooter__rule {
  position: absolute; top: -1px; left: 0;
  display: flex; height: 2px; width: 232px;
}
.ddm-lfooter__rule span { flex: 1; }

/* ==========================================================================
 * ONE BREAKPOINT, at 900px (IMPLEMENTATION-SPEC §6).
 * ======================================================================== */
@media (max-width: 900px) {
  .ddm-act { padding: 44px 20px 40px; }

  /* 10-C's measurements, through the same window the desktop uses: 152x26 over
     a 161x34 image. No tap-target floor applies -- ACCESSIBILITY-CONTRACT §6
     forbids making an image a link, so the mark is a span and the hamburger
     beside it is the header's only target at this width. */
  .ddm-lheader__mark { width: 152px; height: 26px; }
  .ddm-lheader__mark img { top: -4.9px; left: -4.7px; width: 161px; height: 34px; }
  .ddm-lfooter__mark { width: 143px; height: 24px; margin-bottom: 14px; }
  .ddm-lfooter__mark img { top: -4.6px; left: -4.4px; width: 151px; height: 32px; }
  .ddm-hero { padding: 0; }
  .ddm-hero__copy { padding: 40px 20px 36px; }
  .ddm-hero__copy .ddm-h1 { margin-bottom: 20px; }
  .ddm-hero__copy .ddm-lede { margin-bottom: 16px; }
  .ddm-hero__support { font-size: 16.5px; line-height: 1.6; margin-bottom: 26px; }
  .ddm-h1 { font-size: 38px; line-height: 1.04; letter-spacing: -.018em; }
  .ddm-h2, .ddm-h2--sm { font-size: 36px; line-height: 1.04; }
  .ddm-act__head--cases .ddm-h2, .ddm-act__head--roster .ddm-h2 { max-width: none; }
  .ddm-lede { font-size: 16.5px; }
  .ddm-body, .ddm-act__head .ddm-body { font-size: 15.5px; line-height: 1.58; }
  .ddm-pull { font-size: 28px; line-height: 1.16; margin-top: 32px; padding-top: 26px; }
  .ddm-pull--navy { font-size: 28px; margin-top: 32px; padding-top: 26px; }
  .ddm-availability { font-size: 16px; padding: 14px 0 14px 16px; margin-bottom: 26px; }

  /* EVERY TWO-COLUMN ACT STACKS IN SOURCE ORDER. Heading first, supporting
   * paragraph second -- which is what the source order already is, so nothing
   * needs reordering and nothing can get it wrong. */
  .ddm-act__head, .ddm-hero__inner, .ddm-intent, .ddm-intake,
  .ddm-commit, .ddm-model, .ddm-cases, .ddm-roster, .ddm-sources {
    grid-template-columns: 1fr; gap: 24px;
  }
  .ddm-act__head, .ddm-act__head--wide, .ddm-act__head--practice,
  .ddm-act__head--roster, .ddm-act__head--cases { margin-bottom: 28px; }
  /* The one head that is a flex row on desktop has to be told to stack. */
  .ddm-act__head--cases { flex-direction: column; align-items: stretch; gap: 16px; }
  .ddm-act__head--cases .ddm-body { max-width: none; font-size: 15.5px; }
  .ddm-act__title > .ddm-eyebrow { margin-bottom: 18px; }
  .ddm-act__head--roster > .ddm-body { margin-bottom: 0; }
  .ddm-hero__inner { gap: 0; }
  .ddm-commit { gap: 16px; padding-top: 26px; }
  .ddm-commit__head { font-size: 26px; line-height: 1.12; }
  .ddm-commit ul { grid-column: auto; grid-template-columns: 1fr; gap: 0; }
  .ddm-commit li { padding: 14px 0; gap: 12px; }
  .ddm-commit li::before { margin-top: 7px; }
  .ddm-model { border-top: 1px solid var(--ddm-rule-alt); margin-bottom: 30px; gap: 0; }
  .ddm-model__part { border-left: 0; padding: 22px 0; border-bottom: 1px solid var(--ddm-rule-alt); }
  .ddm-model__part:last-child { padding-right: 0; }
  .ddm-model__title { font-size: 19px; margin-bottom: 8px; }

  /* The hero image becomes its own 300px band BELOW the copy, which is why
   * the LCP element on mobile is the H1's serif and not this. */
  .ddm-hero__figure { min-height: 300px; height: 300px; }

  /* The four-across steps become a stacked list, EACH KEEPING ITS OWN HUE as a
   * 3px rule on top. The shared rule does not fit; the sequence meaning has to
   * survive anyway (§6). */
  .ddm-rule4 { display: none; }
  .ddm-steps { grid-template-columns: 1fr; }
  .ddm-step { border-right: 0; padding: 20px 0 24px; border-top: 3px solid var(--ddm-blue); }
  .ddm-step + .ddm-step { padding-left: 0; }
  .ddm-step--sky { border-top-color: var(--ddm-sky); }
  .ddm-step--teal { border-top-color: var(--ddm-teal); }
  .ddm-step--green { border-top-color: var(--ddm-green); }

  .ddm-intent { gap: 32px; }
  .ddm-panels { gap: 24px; }
  .ddm-panels__row, .ddm-panels__row--wide, .ddm-panels__row--narrow {
    grid-template-columns: 1fr; gap: 24px;
  }
  .ddm-panel__figure { height: 214px; }
  .ddm-panel__copy { padding: 18px 18px 20px; }
  .ddm-panel__title { font-size: 17.5px; margin-bottom: 7px; }

  .ddm-cases { gap: 0; }
  .ddm-case, .ddm-case:nth-child(3n+1), .ddm-case:nth-child(3n) {
    border-left: 0; padding: 20px 0;
  }
  .ddm-cases .ddm-num { margin-bottom: 6px; }
  .ddm-case__title { font-size: 18px; }

  /* Six stacked rows, each a mono label over one line of names. */
  .ddm-roster { gap: 0; }
  .ddm-roster__col, .ddm-roster__col:last-child {
    border-right: 0; border-bottom: 1px solid var(--ddm-web-navy-rule);
    padding: 18px 0;
  }
  .ddm-roster h3 { margin-bottom: 10px; }
  .ddm-roster ul { display: flex; flex-wrap: wrap; }
  .ddm-roster li { padding: 0; }
  .ddm-roster li + li::before { content: " · "; color: var(--ddm-on-navy-muted); }

  .ddm-intake { gap: 28px; }
  .ddm-intake__copy .ddm-h2 { font-size: 42px; line-height: 1; margin-bottom: 18px; }
  .ddm-intake__lede { font-size: 16.5px; max-width: none; margin-bottom: 24px; }
  .ddm-intake__promises { max-width: none; }
  .ddm-intake__promises li { padding: 15px 0; gap: 12px; font-size: 15px; line-height: 1.58; }
  .ddm-intake__promises li::before { margin-top: 7px; }
  .ddm-intake__panel { padding: 26px 20px 28px; }
  .ddm-lheader__bar { height: 62px; padding: 0 20px; }
  .ddm-lheader__left { gap: 0; }
  .ddm-lheader__div, .ddm-lheader__nav, .ddm-lheader__cta { display: none; }
  .ddm-lheader__menu {
    display: inline-flex; align-items: center; justify-content: center;
    align-self: center; border: 1.5px solid var(--ddm-rule);
  }
  .ddm-lfooter { padding: 34px 20px 0; }
  .ddm-lfooter__top { flex-direction: column; gap: 22px; padding-bottom: 22px; }
  .ddm-lfooter__line { max-width: none; font-size: 14px; }
  .ddm-lfooter nav ul { gap: 22px; }
  .ddm-lfooter nav a, .ddm-lfooter nav .ddm-unavailable { font-size: 14.5px; }
  .ddm-lfooter__base { padding: 18px 0 26px; }
  .ddm-lfooter__copy { font-size: 13px; }
  .ddm-lfooter__rule { width: 168px; }

  /* Controls grow: 48px role rows, 52px inputs, 44px checkbox rows. */
  .ddm-roles { flex-direction: column; }
  .ddm-role, .ddm-role span { width: 100%; }
  .ddm-role span { height: 48px; }
  .ddm-field input[type="text"], .ddm-field input[type="email"], .ddm-field select {
    height: 52px;
    /* 16px, NOT 15.5px. iOS zooms the viewport on focus below 16px. This is the
     * one place mobile type is larger than desktop and it is not a mistake. */
    font-size: 16px;
  }
  .ddm-source { min-height: 44px; }
  .ddm-source span::before { width: 20px; height: 20px; }
  /* The free-text box drops under its checkbox rather than beside it: at 390
     the two share a row only by starving both. */
  .ddm-sources__other { grid-template-columns: 1fr; gap: 8px; }
  .ddm-sources__other input[type="text"] { height: 52px; font-size: 16px; }
  .ddm-submit { gap: 14px; }
  .ddm-submit .ddm-btn { align-self: stretch; width: 100%; }
  .ddm-hero__cta { flex-direction: column; align-items: stretch; gap: 14px; }
  .ddm-hero__cta .ddm-btn { width: 100%; height: 54px; }
  .ddm-hero__link {
    justify-content: center; min-height: 50px; border-bottom: 0;
    padding-bottom: 0; font-size: 15.5px;
  }

  .ddm-sticky { display: flex; }
  .ddm-outcome__head { font-size: 36px; }
}

/* Under 400% zoom a 1280px viewport is ~320 CSS px. Nothing above assumes a
 * minimum width, so this only has to stop the two remaining fixed boxes. */
@media (max-width: 380px) {
  .ddm-lheader__rule { width: 100%; }
  .ddm-hero__cta .ddm-btn { width: 100%; }
}

/* --- Reduced motion. Both transitions off; nothing else moves. ------------ */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .ddm-sticky { transform: none; }
  html { scroll-behavior: auto; }
}
