/* ============================================================
   EQ DIRECT HIRE, page-scoped styles.

   Loaded by /direct-hire/ only, on top of landing.css, which all the
   landing pages share. Nothing in here can reach /sales/, /admin/,
   /accounting/ or /seo/. Same arrangement stage.css has with /sales/.

   MOST OF THIS PAGE IS NOT IN THIS FILE, and that is the point. The
   header, footer, hero grid, buttons, form panel, form fields, error
   states, eyebrows, ledes, inclusion lists, price panel, promo badge,
   FAQ accordion, sticky bar and reveal animations all come from
   landing.css unchanged, so this page inherits the brand rather than
   restating it. What follows is only the handful of components that
   page genuinely needs and landing.css does not already carry.
   ============================================================ */

/* Terracotta on cream measures 4.44:1 at the eyebrow's 12.5px size, just
   under the 4.5:1 WCAG AA threshold for small text. Maroon clears it
   comfortably. Page-scoped, because .eyebrow is shared in landing.css and
   a colour change there would move it on pages nobody audited. The same
   fix was applied to the hero eyebrow on /sales/ on 27 August 2026.

   .eyebrow-light is excluded from the maroon rule because maroon on olive
   would be unreadable. The original note here claimed the sage pairing
   "already passes"; measured, it does not. Sage #A3B18A on olive #4A5D32
   is 3.17:1, under the 4.5 AA floor for text this size, and Lighthouse
   flagged it on this page. Linen is 5.98:1 on the same band and stays
   quieter than the cream headings above it. */
.eyebrow:not(.eyebrow-light) { color: var(--maroon); }
.eyebrow-light { color: var(--linen); }

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

/* Matches /sales/: copy left, form right, both above the fold on a
   laptop, stacking to copy then form on a phone. The DOM order is
   copy then form, so the mobile stack needs no separate rule. */
.hero-form { width: 100%; }
.hero-form .form-panel { margin: 0; max-width: 480px; }

@media (min-width: 900px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr) 480px; align-items: start; }
  .hero-form .form-panel { max-width: 100%; }
}

.hero-form .form-panel h2 { font-size: 1.5rem; margin-bottom: 0.4rem; }
.form-explain {
  font-size: 0.93rem;
  color: var(--espresso-soft);
  margin-bottom: 1.4rem;
}
.optional { font-weight: 400; color: var(--espresso-soft); }

/* The benefit list sits directly under the hero lede, so it loses the
   top margin .inclusions carries when it follows a heading. */
.dh-benefits { margin-top: 1.2rem; }

/* select needs matching to the text inputs landing.css styles, which it
   does not cover. Appearance is reset so the control is ours on every
   platform, and the chevron is an inline SVG data URI rather than a
   separate request. */
.form-field select {
  width: 100%;
  font: inherit;
  padding: 0.75rem 2.2rem 0.75rem 0.9rem;
  border: 1px solid var(--linen);
  border-radius: 8px;
  background-color: var(--cream);
  color: var(--espresso);
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23231B18' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
}
.form-field.invalid select { border-color: var(--maroon); border-width: 2px; }
/* Until a role is chosen the select shows its disabled placeholder, which
   should read as placeholder text rather than as an answer. */
.form-field select:invalid { color: var(--espresso-soft); }

/* ---------- trust strip ---------- */

/* Wrapped flex, not a fixed four column grid, so it reflows on a phone
   instead of scrolling sideways. */
.dh-strip { padding: 2.2rem 0; }
.dh-strip ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem 2.2rem;
  padding: 0;
  margin: 0;
}
.dh-strip li {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--cream);
  white-space: nowrap;
}
@media (max-width: 599px) {
  .dh-strip li { white-space: normal; text-align: center; }
}

/* ---------- the three photographs ---------- */

.dh-photos {
  display: grid;
  gap: 1.2rem;
  margin-top: 2.4rem;
}
@media (min-width: 760px) {
  .dh-photos { grid-template-columns: repeat(3, 1fr); }
}
.dh-photos figure {
  background: #fff;
  border: 1px solid var(--linen);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  margin: 0;
  /* The three photographs are different shapes (1053x1024, 1200x800 and
     1000x1334). Left alone, the row would be as tall as the portrait and
     the other two would sit in dead space. A fixed frame with object-fit
     on the image gives one clean row instead. */
  display: flex;
  flex-direction: column;
}
.dh-photos img {
  width: 100%;
  height: 220px;
  object-fit: cover;
  display: block;
}
/* Sean's portrait is the only one where cover would crop a face, so it is
   anchored to the top of the frame rather than the centre. */
.dh-photos figure:last-child img { object-position: 50% 22%; }
.dh-photos figcaption {
  padding: 0.85rem 1.1rem;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--espresso-soft);
  border-top: 1px solid var(--linen);
}

/* ---------- salary table ---------- */

/* Two columns, so it stays a readable table further down than the three
   column comparison on /sales/ does. It still restacks on the narrowest
   screens rather than scrolling sideways.

   The explicit ARIA roles in the markup are load bearing for that
   restack: display:block strips the implicit table semantics, and
   without the roles the stacked version would look right while being
   announced to a screen reader as loose text. */
.dh-salary {
  width: 100%;
  border-collapse: collapse;
  margin-top: 2rem;
  max-width: 880px;
  font-variant-numeric: tabular-nums;
}
/* Three columns now, and left alone the browser would give the middle one
   most of the width because it holds the longest strings. Explicit widths
   keep the profile readable and the figure column wide enough that "From
   A$600 per month" does not wrap mid-amount. */
.dh-salary th:first-child { width: 25%; }
.dh-salary th:nth-child(2) { width: 42%; }
.dh-salary th:last-child { width: 33%; }
.dh-caption {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.dh-salary th,
.dh-salary td {
  padding: 0.85rem 0.6rem;
  border-bottom: 1px solid var(--linen);
  text-align: left;
  /* Table cells default to vertical-align:middle. With a one-line profile
     name beside two lines of responsibilities, that floated the name half
     a line below the row's first line and the three columns stopped
     reading as one row. */
  vertical-align: top;
}
.dh-salary thead th {
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--espresso-soft);
  border-bottom: 1.5px solid var(--espresso-soft);
}
.dh-salary tbody th { font-weight: 500; font-size: 0.97rem; }

/* LEFT ALIGNED, DELIBERATELY, and this reverses the earlier rule.

   The value column used to hold nothing but a figure, so right alignment
   and nowrap were right: a column of numbers reads down a shared decimal
   edge. It now holds one figure and two sentences, and a right-aligned
   column of mixed lengths has a different starting point on every line,
   which is the hardest possible thing to read down. nowrap on a sentence
   is worse still: it sets the table's minimum width to the length of the
   longest sentence and drags the page sideways with it.

   The figure keeps its prominence through .dh-amount instead of through
   alignment. */
.dh-salary tbody td {
  color: var(--espresso);
  white-space: normal;
  overflow-wrap: break-word;
}

/* The dollar figure itself. Olive and slightly larger, so an amount is
   found at a glance without the row turning into a price tag. */
.dh-amount {
  font-weight: 700;
  color: var(--olive);
  font-size: 1.02em;
}

/* em, NOT px, and that is the whole point of the unit here.

   A media query in em resolves against the browser's default font size,
   so a reader who has set text to 200% gets 1em = 32px and this query
   fires at 1120px instead of 560px. The table therefore restacks into
   cards when the TEXT is too large for columns, not only when the SCREEN
   is. A px breakpoint leaves a 200% reader with a three-line-per-cell
   table on a laptop, which was the exact failure mode found at 200% on
   /sales/ in the week before this. */
@media (max-width: 35em) {
  .dh-salary,
  .dh-salary thead,
  .dh-salary tbody,
  .dh-salary tr,
  .dh-salary th,
  .dh-salary td { display: block; width: auto; }
  .dh-salary thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .dh-salary tr {
    border: 1px solid var(--linen);
    border-radius: var(--radius);
    padding: 0.85rem 1rem;
    margin-bottom: 0.7rem;
    background: #fff;
  }
  /* THE COLUMN WIDTHS MUST BE UNDONE HERE, and they were not.

     The group rule above sets width:auto on every th, but
     ".dh-salary th:first-child" is one selector more specific and kept
     winning, so on a phone the card heading was still pinned to 25% of
     the width. At that size "administration" does not fit, and the
     overflow-wrap the reflow pass added obligingly broke it: cards headed
     "General administra / tion" and "Experienc / ed administra / tion".
     A column width has no meaning once the cell is a full-width block. */
  .dh-salary th:first-child,
  .dh-salary th:nth-child(2),
  .dh-salary th:last-child { width: auto; }
  .dh-salary tbody th {
    border: 0;
    padding: 0 0 0.5rem;
    font-weight: 600;
    font-size: 1rem;
  }
  /* Two values per card now. Without the separation the responsibilities
     and the salary ran together as one block of text. */
  .dh-salary tbody td + td { margin-top: 0.55rem; }
  .dh-salary tbody td {
    border: 0;
    padding: 0;
    text-align: left;
    white-space: normal;
  }
  /* The column heading is hidden on the stacked layout, so each value
     carries its own label. Without this the card shows a profile name
     and a bare figure with nothing saying what the figure is. */
  .dh-salary tbody td::before {
    content: attr(data-label);
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--espresso-soft);
    margin-bottom: 0.25rem;
  }
}

.dh-disclaimer {
  margin-top: 1.1rem;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--espresso-soft);
  max-width: 72ch;
}

/* ---------- numbered steps ---------- */

/* Numbered because these four genuinely happen in this order, unlike the
   inclusion lists elsewhere on the page, which do not. */
.dh-steps {
  list-style: none;
  display: grid;
  gap: 1.5rem;
  margin: 2.4rem 0 0;
  padding: 0;
  max-width: 760px;
}
.dh-steps li {
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 1rem;
  align-items: start;
}
.dh-steps li > span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  border: 1.5px solid var(--sage);
  color: var(--sage);
  font-family: var(--font-display);
  font-weight: 600;
  flex-shrink: 0;
}
.dh-steps h3 { font-size: 1.12rem; margin-bottom: 0.35rem; color: var(--cream); }
.dh-steps p { font-size: 0.95rem; color: rgba(253, 251, 247, 0.8); margin: 0; }

/* ---------- two column inclusion lists ---------- */

@media (min-width: 700px) {
  .dh-two-col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 2.6rem;
  }
}

/* ---------- pricing ---------- */

.dh-price-for {
  text-align: center;
  margin-inline: auto;
  color: var(--espresso-soft);
  font-size: 0.95rem;
  margin-top: 0.4rem;
}
.dh-std-note {
  margin: 1.1rem auto 0;
  text-align: center;
  font-size: 0.82rem;
  color: var(--espresso-soft);
}
/* The fee explanation and the currency label. Quiet, but in normal
   reading flow rather than behind a disclosure: they are what make the
   $500 line unambiguous, so hiding them would defeat the point. */
.dh-fee-note {
  margin: 1.2rem auto 0;
  text-align: center;
  font-size: 0.84rem;
  line-height: 1.55;
  color: var(--espresso-soft);
}
.dh-currency-note {
  margin: 0.6rem auto 0;
  text-align: center;
  font-size: 0.78rem;
  color: var(--espresso-soft);
}
.dh-price-cta { margin-top: 1.6rem; text-align: center; }

/* ---------- pricing card ---------- */

/* THE CARD WAS ALREADY CENTRED. Its CONTENTS were not, and that is what
   read as off-centre: landing.css leaves .promo-badge and .price-now at
   their default left alignment, while .dh-price-for and the button below
   them were centred, so the card mixed two alignments down its length.

   The equivalent centring for /sales/ lives in stage.css, which this page
   does not load. Restated here rather than promoted into landing.css,
   because /admin/, /accounting/ and /seo/ also use .price-panel and were
   not part of this review.

   The badge sits astride the top edge, which needs the panel as its
   positioning context and a little clear space above so the overhanging
   half does not collide with the section before it. */
.price-panel { position: relative; margin-top: 1.4rem; }
.price-panel .promo-badge {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  white-space: nowrap;
}
/* margin-inline:auto, not just text-align. landing.css caps every <p> at
   62ch, so these boxes are narrower than the panel, and a narrower box
   with no auto margins sits flush left no matter what text-align its
   parent carries. The auto margin is the half that actually moves it.
   This exact trap has been logged repeatedly across this codebase. */
.price-panel .price-now {
  text-align: center;
  margin-inline: auto;
  margin-top: 0.9rem;
}
/* The inclusion list stays LEFT aligned inside the centred card. A centred
   list of bullets is hard to scan, since every line starts in a different
   place; only the block is centred, by the panel's own padding. */
.price-panel .inclusions { text-align: left; }

/* ---------- the two models ---------- */

.dh-compare {
  display: grid;
  gap: 1.2rem;
  margin-top: 2.2rem;
}
@media (min-width: 820px) {
  .dh-compare { grid-template-columns: 1fr 1fr; }
}
.dh-card {
  background: #fff;
  border: 1px solid var(--linen);
  border-radius: var(--radius);
  padding: 1.8rem;
}
/* The accent marks which model this page is actually selling. A border,
   not a background fill, so the two cards stay comparable at a glance. */
.dh-card-accent { border-color: var(--maroon); border-width: 2px; }
.dh-card h3 { font-size: 1.25rem; margin-bottom: 0.9rem; }
.dh-card .inclusions { margin-top: 0; }
.dh-card .inclusions li { font-size: 0.92rem; }
.dh-best {
  margin-top: 1.1rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--espresso-soft);
}
/* QUIET, deliberately. This was a bordered white card when it pointed at
   Embedded Sales. Directly beneath the comparison table a boxed panel
   reads as a second offer with its own frame, which is the one thing
   this section must not become. Plain text and an underline is enough:
   the reader who wants the managed model is already looking for it. */
.dh-sales-note {
  margin-top: 1.2rem;
  font-size: 0.95rem;
  max-width: 900px;
}
.dh-sales-note a {
  color: var(--maroon);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}


/* ---------- the two models, comparison table ----------

   Three columns, so this restacks a good deal earlier than the two column
   salary table above it. Same em-based reasoning, one size wider: at a
   200% text setting this fires at 1472px, which stacks it even on a
   desktop, and that is correct. Three columns of doubled text on a
   1440px screen is not a table anybody can read.

   NOT COLOUR ALONE. The Direct Hire column is marked three ways: the
   words "This page" in its heading, a heavier type weight, and a tinted
   panel with real side borders. Remove the tint and the column is still
   identifiable from the text, which is the test.

   The explicit ARIA roles in the markup are load bearing for the stacked
   layout, exactly as they are for the salary table: display:block strips
   the implicit table semantics, and without the roles the cards would
   look right while being announced as loose text. */
.dh-models {
  width: 100%;
  border-collapse: collapse;
  margin-top: 2rem;
  max-width: 900px;
  font-variant-numeric: tabular-nums;
}
.dh-models th,
.dh-models td {
  padding: 0.85rem 0.9rem;
  border-bottom: 1px solid var(--linen);
  text-align: left;
  vertical-align: top;
  overflow-wrap: break-word;
}
.dh-models thead th {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--espresso-soft);
  border-bottom: 1.5px solid var(--espresso-soft);
}
.dh-models tbody th {
  font-weight: 600;
  font-size: 0.94rem;
  width: 26%;
}
.dh-models tbody td {
  font-size: 0.94rem;
  color: var(--espresso);
}
/* The column this page is actually selling. */
/* The figure leads, the qualifier follows in normal weight on its own
   line. Inline, the two ran together and the eye could not find where the
   number stopped. */
.dh-models .dh-amount { font-size: 1em; display: block; margin-bottom: 0.2rem; }
.dh-models tbody td { font-weight: 400; }
.dh-models tbody td .dh-amount { font-weight: 700; }

@media (max-width: 46em) {
  .dh-models,
  .dh-models thead,
  .dh-models tbody,
  .dh-models tr,
  .dh-models th,
  .dh-models td { display: block; width: auto; }
  .dh-models thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .dh-models tr {
    border: 1px solid var(--linen);
    border-radius: var(--radius);
    padding: 0.95rem 1.1rem;
    margin-bottom: 0.7rem;
    background: #fff;
  }
  .dh-models tbody th {
    border: 0;
    padding: 0 0 0.6rem;
    width: auto;
    font-size: 1rem;
  }
  .dh-models tbody td {
    border: 0;
    padding: 0.55rem 0 0;
  }
  /* Each value names its own column, since the header row is hidden. */
  .dh-models tbody td::before {
    content: attr(data-label);
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--espresso-soft);
    margin-bottom: 0.15rem;
  }
  /* The side borders make no sense once the cell is a full-width block.
     A single left rule marks the same column instead, and the label
     above it already names it in words. */
  }

/* ---------- founder ---------- */

/* landing.css frames .feature-photo at 3:2 for landscape photographs.
   Sean's portrait is 3:4 the other way, and in that frame object-fit:
   cover crops his head off. Same override /sales/ carries, for the same
   reason and on the same image. */
.founder .feature-photo {
  aspect-ratio: 3 / 4;
  max-width: 400px;
  width: 100%;
  margin-inline: auto;
}
.dh-photo {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
/* The greeting only. The founder note on /sales/ was set fully italic and
   narrowed to the greeting on 27 August 2026, because a long block of
   slanted text is tiring and stops reading as personal. Same treatment
   here from the start rather than repeating the mistake. */
.founder .lede { font-style: italic; color: var(--espresso); }
.founder p { color: var(--espresso); max-width: 58ch; }

/* ---------- below-the-fold render deferral ----------
   Skips layout and paint for sections that are not near the viewport
   yet. contain-intrinsic-size is not optional: without a size estimate a
   skipped section reports zero height and the scrollbar jumps as
   sections render. The "auto" keyword makes the browser remember each
   section's real height once it has been rendered once. The hero is
   excluded, since it must render immediately. */
main > section:not(.hero) {
  content-visibility: auto;
  contain-intrinsic-size: auto 640px;
}

/* ---------- centring the constrained blocks ----------
   landing.css centres the section furniture (eyebrow, h2, lede) by
   giving each BOTH text-align:center and margin-inline:auto, and its own
   comment explains why: a block narrower than the container sits flush
   left regardless of the text-align on its parent, so the auto margin is
   the half that actually moves it.

   These four blocks are all narrower than the 1140px container, so
   without this they sat hard against the left gutter underneath a
   centred heading, which reads as a mistake rather than a layout. Caught
   by measuring the boxes against the container on 27 August 2026, not by
   eye: at a glance a left-aligned table under a centred heading looks
   deliberate until you notice the heading is not above its own content.

   Only the BOX is centred. The text inside the table and the steps stays
   left aligned, because a column of figures and a numbered sequence both
   need a stable left edge to be read down. */
.dh-salary,
.dh-models,
.dh-steps,
.dh-sales-note,
.dh-disclaimer { margin-inline: auto; }

/* ---------- thank-you page ----------
   Shares this stylesheet because it is the same product and needs the
   same handful of tokens; it is a short page and does not justify a file
   of its own. */
.ty-hero { padding-bottom: 4rem; }
.ty-hero h1 { max-width: 20ch; }
.ty-hero .lede { max-width: 58ch; }
.ty-card {
  background: #fff;
  border: 1px solid var(--linen);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 2rem;
  margin-top: 2.4rem;
  max-width: 560px;
}
.ty-card h2 { font-size: 1.35rem; margin-bottom: 0.5rem; }
.ty-card p { color: var(--espresso-soft); font-size: 0.97rem; }
.ty-card .btn { margin-top: 1.4rem; }
.ty-card .form-note { margin-top: 1rem; }
.ty-back { margin-top: 2rem; font-size: 0.92rem; }
.ty-back a { color: var(--maroon); }

/* ---------- the on-demand Calendly embed, thank-you page ----------
   min-height reserves the space the iframe fills once Calendly
   initialises, so the loading state does not collapse to a thin strip
   and then jump when the widget appears. The equivalent rule for
   /sales/ lives in stage.css, which this page does not load. */
.eq-calendar {
  min-height: 640px;
  margin-top: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--espresso-soft);
  font-size: 0.9rem;
}
.eq-calendar iframe { width: 100%; height: 100%; border: 0; }


/* ============================================================
   TEXT-SIZE REFLOW. Added 3 September 2026.

   MEASURED, NOT GUESSED. At a 200% text setting on a 390px viewport this
   page reported a 480px document. The offender list named three elements
   and only one of them was the cause:

     .sticky-cta  480px wide, position:fixed. NOT the cause. A fixed box
                  with left:0;right:0 resolves against the initial
                  containing block, and the ICB grows with the document,
                  so an overflowing page makes the sticky bar wide rather
                  than the other way around. Chasing this first is the
                  standing trap in this codebase.

     .dh-tag      490px right edge, inside the comparison table's head.
                  Also NOT the cause. On the stacked layout that thead is
                  the clipped visually-hidden pattern, so the tag has a
                  layout rectangle but contributes nothing to scrollWidth.
                  Proved by hiding the thead outright: the document stayed
                  at 480px.

     .l-header .btn   451px right edge. THE CAUSE. landing.css gives the
                  header call to action white-space:nowrap below 430px,
                  which is correct at normal size and keeps it on one line
                  beside the wordmark. At 200% text "Get my hiring plan"
                  no longer fits beside anything, and being unable to wrap
                  it pushed the document to 480px and took the sticky bar
                  with it.

   /sales/ hit this exact failure the week before and the fix lives in
   stage.css, which this page does not load. Restated here rather than
   promoted into landing.css, because /admin/, /accounting/ and /seo/ share
   that file and were not part of this review.

   NOTHING CHANGES AT NORMAL SIZE. The button already fits on one line at
   every tested width, so allowing it to wrap costs nothing until the text
   is genuinely too large; flex-wrap only engages once the row cannot fit.
   ============================================================ */
.l-header { flex-wrap: wrap; }
.l-header .btn {
  white-space: normal;
  text-align: center;
  max-width: 100%;
}

/* Long unbroken strings in the tables and the hero cannot be allowed to
   set a minimum width the viewport has to grow to meet. */
.dh-models th,
.dh-models td,
.dh-salary th,
.dh-salary td,
.dh-benefits li,
.terms-line { overflow-wrap: break-word; min-width: 0; }

/* Two more owners of the same failure, each found by hiding one element at
   a time and re-measuring rather than by reading the stylesheet.

   THE HERO HEADLINE. At a 200% setting the h1 renders at 73.6px, and
   "professional" is then a single 480px word. A word cannot wrap unless it
   is allowed to break, so it set the document width and every ancestor
   simply inherited the number. Breaking a word is ugly; a page that
   scrolls sideways is worse, and this only ever engages when one word is
   genuinely wider than the screen.

   THE FOOTER. landing.css already gives .l-footer flex-wrap, so the two
   groups stack correctly. What it cannot do is let either group shrink:
   flex items default to min-width:auto, so each group stayed at its
   min-content width and overhung the 4vw padding by about 5px. */
.hero h1 { overflow-wrap: break-word; }

/* "anywhere", NOT "break-word", and the difference is the whole fix.

   break-word lets a long word break once the box has already been sized;
   it does NOT reduce the box's min-content width. A flex or grid item is
   sized FROM its min-content width, so break-word leaves the floor exactly
   where it was and the page still scrolls. anywhere is the one that counts
   the break when the minimum is calculated.

   The footer is the case that proves it. "sean@expandquickly.com.au" is a
   single unbreakable 379px token at a 200% setting, which held the
   document at 392px no matter how narrow the viewport got. Adding
   min-width:0 and break-word changed nothing; anywhere fixed it. Neither
   property does anything at normal size, where the address fits. */
.l-footer > * { min-width: 0; overflow-wrap: anywhere; }

/* The same min-width:auto floor, in the two grids this page owns. A grid
   item cannot shrink below its content's min-content width unless it is
   told it may, so at a 200% setting one long word in a card or a step
   pushed the whole track wider than the screen. */
.dh-compare > *,
.dh-card,
.dh-card *,
.dh-steps li,
.dh-steps li > div,
.dh-steps li > div * { min-width: 0; }
.dh-card li,
.dh-card h3,
.dh-card p,
.dh-steps h3,
.dh-steps p { overflow-wrap: anywhere; }

/* Each note lines up with the table it belongs to. landing.css caps a
   paragraph at 62ch, which is narrower than either table, so an auto
   margin centred the note on the container and left it visibly indented
   from the table's own left edge. Matching the table widths puts the two
   left edges on the same line. */
#salaries .dh-disclaimer { max-width: 880px; }
.dh-models ~ .dh-disclaimer { max-width: 900px; }


/* ---------- round two, 3 September 2026 ---------- */

/* THE HEADLINE WAS TOO BIG ON A PHONE, not too long. landing.css sets
   clamp(2.3rem, 5.2vw, 3.9rem), and on a 390px screen 5.2vw is 20px, so
   the 2.3rem floor wins and every phone gets 36.8px. That ran the headline
   to five and six lines and, with the old four-line footnote under it,
   pushed the form 825px down: past the fold on every phone tested.

   Page-scoped and phone-only. The desktop headline is untouched, and so is
   every other page that shares landing.css.
   ONE SIZE, NOT TWO. A first attempt stepped the size down again below
   380px, which made the 390px case worse than the 360px one: 32px wrapped
   to four lines where 29px fitted in three, and 390 is the commonest phone
   width there is. A single size across the phone range wraps consistently
   and is the simpler thing to reason about. */
@media (max-width: 599px) {
  .hero h1 { font-size: 1.8rem; line-height: 1.15; }
  .hero .lede { font-size: 1rem; }
  .hero .terms-line { font-size: 0.84rem; }
  .dh-benefits { margin-top: 1rem; }
}

/* The full disclosure that used to sit in the hero footnote, now under the
   price it qualifies. Quieter than body copy, but in normal reading flow:
   this is the material a customer is entitled to read before paying, so it
   does not belong behind a disclosure widget. */
.dh-terms-full {
  margin: 1.8rem auto 0;
  max-width: 62ch;
  text-align: left;
  padding-top: 1.4rem;
  border-top: 1px solid var(--linen);
}
.dh-terms-full h3 {
  font-size: 1rem;
  margin-bottom: 0.7rem;
}
.dh-terms-full p {
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--espresso-soft);
  margin-bottom: 0.7rem;
}
.dh-terms-full p:last-child { margin-bottom: 0; }
.dh-terms-full strong { color: var(--espresso); }


/* ============================================================
   ALIGNMENT. Centred, 3 September 2026.

   The page was centred, then pulled back to left-aligned body text,
   then centred again at the owner's instruction. This is the third
   state and the one that ships.

   The trade is real and worth writing down rather than rediscovering:
   a centred list or column has no stable left edge, so the eye has to
   find the start of every line afresh. That costs scanning speed on
   long lists and on tables of figures. The owner has seen both and
   prefers the symmetry. Do not quietly revert it.

   Two things stay as they are. The hero keeps its two-column layout,
   copy beside the form, because centring text next to a form panel
   reads as a mistake rather than a choice. And the numbered steps
   were already centred.
   ============================================================ */

/* ---- bullet lists ----
   The marker is an absolutely positioned dot at left:0 in
   landing.css. Centring the text alone would strand the dots at the
   far left, so each row becomes a centred inline pair instead. */
.dh-two-col li,
.price-panel .inclusions li,
.inclusions li {
  text-align: center;
}
.inclusions li {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.55rem;
  padding-left: 0;
  /* A FLEX ROW HAS A MIN-CONTENT FLOOR, AND THIS ONE OVERFLOWED.
     Centring puts the marker back in flow, so the row's minimum width
     became marker + gap + longest word. Absolutely positioned, as it
     was, the marker cost nothing. At a 200% text setting on a 320px
     screen that floor pushed the document to 336px: measured, and the
     only cause once every other centring rule was ruled out one at a
     time. Allowing the row to wrap and to shrink below its content
     removes the floor without giving up the centring. */
  flex-wrap: wrap;
  min-width: 0;
  overflow-wrap: anywhere;
}
.inclusions li::before {
  position: static;
  flex: 0 0 auto;
}
.price-panel .inclusions { text-align: center; }

/* ---- tables, every column including the first ---- */
.dh-salary th,
.dh-salary td,
.dh-models th,
.dh-models td { text-align: center; }
.dh-salary caption, .dh-models caption { text-align: center; }

/* ---- numbered steps ----
   Restored. The centring for these lived in the block this one
   replaced, and dropping it left the steps ranged left while
   everything around them was centred. The number sits above its text
   rather than beside it, so the pair centres as one unit. */
.dh-steps li {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
  gap: 0.7rem;
}
.dh-steps p { margin-inline: auto; }

/* ---- FAQ ----
   The disclosure marker sits at the right, so only the text moves. */
.faq-list summary { text-align: center; }
.faq-list p { text-align: center; margin-inline: auto; }

/* ---- prose blocks ---- */
.dh-terms-full,
.dh-terms-full p { text-align: center; }
.dh-disclaimer { text-align: center; }
.dh-sales-note { text-align: center; }
.dh-photos figcaption { text-align: center; }

/* ---- BULLET LISTS READ LEFT TO RIGHT ON A PHONE ----

   Centring a bulleted list works on a wide column, where almost every
   item is one line and the dots land in a tidy vertical band. On a
   phone it falls apart, and checking on a real handset is what showed
   it: items wrap to two and three lines, every dot sits at a different
   x position, and a row that wraps puts its dot alone on a line above
   its own text. The wrap was added deliberately, to cure a 320px
   overflow at 200% text, so the two problems are the same problem.

   Below 720px the markers go back where they came from: out of flow,
   at the left, with the text ranged beside them. That restores the
   stable left edge a list needs, and it removes the min-content floor
   that caused the overflow in the first place, so both fixes hold.

   Headings, ledes, tables and the steps stay centred. This is about
   the dots only. */
@media (max-width: 719px) {
  .dh-two-col li,
  .price-panel .inclusions li,
  .inclusions li {
    display: list-item;
    text-align: left;
    padding-left: 1.6rem;
    flex-wrap: nowrap;
  }
  .inclusions li::before { position: absolute; }
  .price-panel .inclusions { text-align: left; }
}

/* ---- the stacked cards a phone gets ----
   Both tables collapse to cards below their breakpoints. The label
   and its value are centred with everything else, and the salary
   column keeps the centring it has on desktop. */
@media (max-width: 719px) {
  .dh-models tbody th,
  .dh-models tbody td { text-align: center; }
}
@media (max-width: 559px) {
  .dh-salary tbody th,
  .dh-salary tbody td { text-align: center; }
}

/* ---- compact closing call to action ----
   Replaces the large closing section removed on 3 September 2026.
   It is deliberately NOT given id="book": that id is what the
   sticky bar hides against, and the owner asked for the sticky bar
   to stay visible all the way down. */
.dh-final {
  text-align: center;
  padding-block: 3.4rem;
}
.dh-final h2 {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  margin-bottom: 0.6rem;
}
.dh-final p {
  margin-inline: auto;
  color: var(--espresso-soft);
  max-width: 46ch;
}
.dh-final .btn { margin-top: 1.5rem; }

/* THE STICKY BAR MUST NOT SIT ON TOP OF THE LAST THING ON THE PAGE.
   It is fixed to the bottom of the viewport and, with no closing
   section left to hide against, it is still showing when the
   visitor reaches the footer. Reserving its height at the foot of
   the document keeps the final call to action and the footer
   reachable and readable on a phone. Measured, not guessed: the bar
   renders 72px tall at 390px wide, and the value below carries a
   margin over that. */
@media (max-width: 719px) {
  .l-footer { padding-bottom: 6rem; }
}

/* ---- one-column "Who does what" table ----
   The Embedded Admin column was removed on 3 September 2026, so the
   accent-column and column-tag rules that used to live here are gone with
   the markup they styled.

   The stacked mobile card repeats data-label above every value. With two
   columns that label was the only way to tell which product a value
   belonged to. With one it says "Direct Hire Admin" seven times on a page
   about Direct Hire Admin, so it is hidden: the row heading above it
   already names the category, which is the part a reader needs. */
@media (max-width: 719px) {
  .dh-models tbody td::before { display: none; }
  .dh-models tbody td { padding-top: 0; }
}

/* The candidate salary inside the hero headline. Colour only: the display
   face supplies its own weight and size, and .dh-amount would override
   both. Same olive the salary figures use in the tables below. */
.hero h1 .dh-figure,
.hero .dh-benefits .dh-figure { color: var(--olive); }
/* The bullet sits in body text rather than the display face, so it
   also takes a little weight to read as a figure rather than as a
   colour accident. The headline already has weight of its own. */
.hero .dh-benefits .dh-figure { font-weight: 600; }
