/*
 * Shared presentation for every oversing.com public page.
 *
 * runcible.com grew eighteen route stylesheets that are each about 80% the
 * same file, which is how the palette ended up with six values for --muted.
 * The split here is deliberate: everything a second page could plausibly want
 * lives in this file, and a route sheet is only allowed to carry what is
 * genuinely unique to that one page. If two route sheets ever need the same
 * rule, it belongs here instead.
 *
 * Colour, measure, and type scale come from runcible-tokens.css.
 */

/* ------------------------------------------------------------------ ground */

/* Every runcible.com route stylesheet opens with `* { box-sizing: border-box }`.
   Consolidating those eighteen sheets into this file dropped it, and the rest
   of the CSS here was written on the assumption that it was still in force —
   `.exhibit-panel` sets `width: 100%` and a horizontal padding of
   `--section-pad-x`, which under content-box makes the panel 256px wider than
   the track that holds it and pushes the media column off the right edge.
   That `oversing-layout.php` declares `box-sizing: border-box` by hand on a
   single element is the same omission showing through in another place. */
body[class*="oversing-public-"],
body[class*="oversing-public-"] *,
body[class*="oversing-public-"] *::before,
body[class*="oversing-public-"] *::after {
  box-sizing: border-box;
}

body[class*="oversing-public-"] {
  color: var(--ink);
  background: var(--paper);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------ WordPress isolation

   Twenty Twenty-Five wraps page content in
   `.entry-content.wp-block-post-content.has-global-padding.is-layout-constrained`.
   Each of those last two classes imposes a measure of its own: one a max-width
   from theme.json's contentSize, the other a horizontal gutter. Nested inside
   the measure the design system already defines, the result is several column
   widths stacked on one page — header at one width, rail at another, the
   theme's constrained wrapper at a third, the page body at a fourth.

   The fix is the one runcible.com uses: strip the theme's containers back to
   nothing and let `.section` be the single element that decides the measure.
   Everything above `.section` is full-bleed by definition. */

body[class*="oversing-public-"] .wp-site-blocks,
body[class*="oversing-public-"] .wp-site-blocks > main,
body[class*="oversing-public-"] #wp--skip-link--target,
body[class*="oversing-public-"] .wp-block-post-content,
body[class*="oversing-public-"] .oversing-page-body {
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* `has-global-padding` applies theme.json's root padding, and the page
   template puts it on a wrapper between <main> and the content. It insets on
   every side: 50px horizontally, which pushed the section bands off both edges
   while the header and rail stayed flush, and 70px on top, which opened a band
   of dead page background between the rail and the first section. Sections
   supply all of their own padding, so none of this is wanted — runcible.com
   zeroes the same wrapper with
   `#wp--skip-link--target > .wp-block-group { padding: 0 !important }`.
   Scoped under main so the footer, which uses the same class and sets its
   gutter deliberately, is untouched. */
body[class*="oversing-public-"] .wp-site-blocks > main,
body[class*="oversing-public-"] .wp-site-blocks > main .has-global-padding {
  padding: 0 !important;
}

html body[class*="oversing-public-"] .entry-content.wp-block-post-content {
  width: 100% !important;
  max-width: none !important;
  margin-inline: 0 !important;
  padding: 0 !important;
}

/* `alignfull` is the theme's way of escaping a constrained parent, and it does
   it with 100vw plus a negative margin. 100vw counts the scrollbar and the
   parent's 100% does not, so once the containers above are already full-bleed
   the escape overshoots by the scrollbar width and the page gains a horizontal
   scrollbar of its own. Nothing here needs to escape anything any more, so
   full width is simply full width. */
body[class*="oversing-public-"] .wp-site-blocks .alignfull {
  width: 100% !important;
  max-width: none !important;
  margin-inline: 0 !important;
}

/* The theme prints the post title above the content. Every page here opens
   with its own designed masthead inside the first section, so leaving this in
   renders two titles, at two different widths, in two different typefaces.
   runcible.com suppresses it with the MM Title Manager plugin, which is not
   installed here. */
body[class*="oversing-public-"] .wp-block-post-title {
  display: none !important;
}

/* --------------------------------------------------------------- sections */

body[class*="oversing-public-"] .section {
  padding: var(--section-pad-y) var(--section-pad-x);
  border-bottom: 1px solid var(--rule);
}

body[class*="oversing-public-"] .section.is-ink {
  color: var(--white);
  background: var(--ink);
  border-bottom-color: var(--rule-dark);
}

body[class*="oversing-public-"] .section.is-coal {
  color: var(--white);
  background: var(--coal);
  border-bottom-color: var(--rule-dark);
}

body[class*="oversing-public-"] .section.is-white {
  background: var(--white);
}

body[class*="oversing-public-"] .section-inner,
body[class*="oversing-public-"] .inner {
  max-width: 1080px;
  margin: 0 auto;
}

body[class*="oversing-public-"] .section-inner.is-narrow {
  max-width: var(--content-width);
}

/* ------------------------------------------------------------------- type */

body[class*="oversing-public-"] .eyebrow,
body[class*="oversing-public-"] .coord {
  margin: 0 0 14px;
  color: var(--red);
  font-family: var(--mono);
  font-size: var(--fs-mono-label);
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
}

body[class*="oversing-public-"] .section.is-ink .eyebrow,
body[class*="oversing-public-"] .section.is-coal .eyebrow {
  color: var(--gold);
}

body[class*="oversing-public-"] .question {
  margin: 0 0 10px;
  max-width: 46ch;
  color: var(--muted);
  font-family: var(--slab);
  font-size: clamp(1.02rem, 1.6vw, 1.24rem);
  font-weight: 400;
  font-style: italic;
}

body[class*="oversing-public-"] h1 {
  margin: 0 0 18px;
  font-family: var(--slab);
  font-size: var(--fs-h1);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -.015em;
}

body[class*="oversing-public-"] h2 {
  margin: 0 0 16px;
  font-family: var(--slab);
  font-size: var(--fs-h2);
  font-weight: 700;
  line-height: 1.1;
}

body[class*="oversing-public-"] h3 {
  margin: 0 0 12px;
  font-family: var(--slab);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.2;
}

body[class*="oversing-public-"] .kicker {
  margin: 0 0 20px;
  max-width: 40ch;
  color: var(--red);
  font-family: var(--slab);
  font-size: clamp(1.3rem, 2.2vw, 1.9rem);
  font-weight: 700;
  line-height: 1.22;
}

body[class*="oversing-public-"] .section.is-ink .kicker,
body[class*="oversing-public-"] .section.is-coal .kicker {
  color: var(--gold);
}

body[class*="oversing-public-"] .lede {
  max-width: 62ch;
  margin: 0 0 24px;
  font-size: var(--fs-lede);
  line-height: 1.5;
}

body[class*="oversing-public-"] p {
  max-width: 68ch;
}

body[class*="oversing-public-"] .section.is-ink p,
body[class*="oversing-public-"] .section.is-coal p {
  color: #ddd9d0;
}

body[class*="oversing-public-"] .section.is-ink .muted,
body[class*="oversing-public-"] .section.is-coal .muted {
  color: var(--muted-on-dark);
}

body[class*="oversing-public-"] .muted {
  color: var(--muted);
}

/* ---------------------------------------------------------------- buttons */

body[class*="oversing-public-"] .button {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  min-height: 50px;
  padding: 13px 22px;
  border: 1px solid var(--teal-dark);
  color: var(--white);
  background: var(--teal-dark);
  font-family: var(--mono);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: var(--ls-mono);
  line-height: 1.2;
  text-decoration: none;
  text-transform: uppercase;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}

body[class*="oversing-public-"] .button:hover {
  border-color: var(--ink);
  background: var(--ink);
}

body[class*="oversing-public-"] .button.secondary {
  color: var(--ink);
  background: transparent;
  border-color: var(--ink);
}

body[class*="oversing-public-"] .button.secondary:hover {
  color: var(--white);
  background: var(--ink);
}

body[class*="oversing-public-"] .section.is-ink .button.secondary,
body[class*="oversing-public-"] .section.is-coal .button.secondary {
  color: var(--white);
  border-color: rgba(255, 253, 247, .45);
}

body[class*="oversing-public-"] .section.is-ink .button.secondary:hover,
body[class*="oversing-public-"] .section.is-coal .button.secondary:hover {
  color: var(--ink);
  background: var(--white);
  border-color: var(--white);
}

body[class*="oversing-public-"] .cta-pair {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: clamp(28px, 4vw, 44px);
}

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

/*
 * Every interface figure carries an evidence label. The label is not optional
 * decoration -- the message spine requires each capture to declare whether it
 * is the current production interface, illustrative data, or archive -- so the
 * component renders a visible warning when the attribute is missing rather
 * than failing silently in review.
 */
body[class*="oversing-public-"] .figure {
  margin: clamp(28px, 4vw, 44px) 0;
  border: 1px solid var(--rule);
  background: var(--white);
}

body[class*="oversing-public-"] .figure img {
  display: block;
  width: 100%;
  height: auto;
}

body[class*="oversing-public-"] .figure figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  padding: 12px clamp(14px, 2vw, 20px);
  border-top: 1px solid var(--rule);
  background: var(--paper);
  font-size: .88rem;
}

body[class*="oversing-public-"] .figure[data-evidence]::before {
  content: attr(data-evidence);
  display: block;
  padding: 8px clamp(14px, 2vw, 20px);
  border-bottom: 1px solid var(--rule);
  color: var(--white);
  background: var(--teal-dark);
  font-family: var(--mono);
  font-size: .58rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
}

body[class*="oversing-public-"] .figure[data-evidence="illustrative"]::before {
  content: "Illustrative — not a customer record";
  background: var(--gold-dark);
}

body[class*="oversing-public-"] .figure[data-evidence="production"]::before {
  content: "Current production interface";
}

body[class*="oversing-public-"] .figure[data-evidence="archive"]::before {
  content: "Historical archive — not current product evidence";
  background: var(--red);
}

/* A frame reserved for a capture that does not exist yet. It declares itself
   rather than sitting there looking like a broken image, and it is visually
   loud enough that nobody mistakes the page for finished. */
body[class*="oversing-public-"] .figure[data-evidence="pending"]::before {
  content: "Capture pending — see EVIDENCE-BACKLOG.md";
  color: var(--ink);
  background: var(--paper-2);
}

body[class*="oversing-public-"] .figure:not([data-evidence])::before {
  content: "MISSING EVIDENCE LABEL";
  display: block;
  padding: 8px clamp(14px, 2vw, 20px);
  color: var(--white);
  background: var(--red);
  font-family: var(--mono);
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* Placeholder frame for figures whose capture is still in the evidence
   backlog. Deliberately unattractive: it should not survive to release. */
body[class*="oversing-public-"] .figure.is-pending {
  display: grid;
  place-items: center;
  min-height: 240px;
  border-style: dashed;
  border-width: 2px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}

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

body[class*="oversing-public-"] .stack {
  display: grid;
  gap: clamp(18px, 2.6vw, 30px);
  margin: clamp(24px, 3.4vw, 38px) 0 0;
  padding: 0;
  list-style: none;
}

body[class*="oversing-public-"] .stack > li {
  padding-left: 18px;
  border-left: 2px solid var(--gold);
  max-width: 68ch;
}

body[class*="oversing-public-"] .stack > li > strong {
  display: block;
  margin-bottom: 4px;
  font-family: var(--slab);
  font-size: 1.06rem;
}

body[class*="oversing-public-"] .grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(20px, 3vw, 36px);
  margin-top: clamp(24px, 3.4vw, 38px);
}

/* --------------------------------------------------------------- boundary */

/*
 * The maturity boundary appears on most pages. It is a component so that it
 * reads the same everywhere and cannot be quietly softened on the pages where
 * it is least convenient.
 */
body[class*="oversing-public-"] .boundary {
  margin: clamp(32px, 4.5vw, 56px) 0 0;
  padding: clamp(18px, 2.6vw, 26px);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--red);
  background: var(--white);
}

body[class*="oversing-public-"] .boundary > strong {
  display: block;
  margin-bottom: 6px;
  color: var(--red);
  font-family: var(--mono);
  font-size: .6rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
}

body[class*="oversing-public-"] .boundary p:last-child {
  margin-bottom: 0;
}

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

body[class*="oversing-public-"] .oversing-page-body {
  padding: clamp(40px, 6vw, 80px) var(--gutter-x);
}

/* Direct children of a page body are one of two kinds, and they want opposite
   things.
 *
 * A `.section` is a full-bleed band: it carries its own background colour and
 * its own bottom rule, and its measure belongs to the `.section-inner` inside
 * it. Constraining it produces a centred 860px colour block floating in the
 * page instead of a band running edge to edge, which was the most visible way
 * this page stopped resembling runcible.com.
 *
 * Anything else is prose sitting directly in the body, and it does need the
 * reading measure. It also needs its own gutter now that the page body is
 * full-bleed, hence the width expression rather than a bare max-width. */
body[class*="oversing-public-"] .oversing-page-body > *:not(.section):not(.exhibit) {
  width: min(var(--content-width), 100% - (2 * var(--gutter-x)));
  margin-left: auto;
  margin-right: auto;
}

/* Bands must butt against each other. Core's flow layout puts a
   `margin-block-start` of 1.2rem on every child after the first, and because
   it bakes the computed length straight into the generated rule rather than
   reading `--wp--style--block-gap`, the block-gap override at the top of
   `oversing-page-progress.css` cannot reach it. Each section carries its own
   background colour, so the margin showed as a 19px strip of page background
   between them — the exact failure that override was written to prevent.
   Vertical rhythm belongs to `--section-pad-y` inside each band. */
body[class*="oversing-public-"] .oversing-page-body > .section,
body[class*="oversing-public-"] .oversing-page-body > .exhibit {
  margin-block: 0;
}

/* ---------------------------------------------------------------- motion */

@media (prefers-reduced-motion: reduce) {
  body[class*="oversing-public-"] * {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
