/**
 * Pattern styles.
 *
 * Ported from components/blocks/Blocks.module.css and components/layout/Section.module.css.
 *
 * These style the TIER 1 patterns — the ones an editor composes freely. The class names
 * are the contract: a pattern's markup can be rewritten in the editor, but as long as the
 * classes survive, the design does. An editor who strips the classes gets unstyled core
 * blocks, which is a visible mistake rather than a silent one.
 */

/* ── Hero ─────────────────────────────────────────────────────────────────── */

.ss-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 600px;
  background: var(--surface-inverse);
  overflow: hidden;
}

.ss-hero--short {
  min-height: 380px;
}

.ss-hero__image,
.ss-hero__image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  object-fit: cover;
}

/**
 * A FLAT overlay at 55%, across the whole image.
 *
 * The design system rules out a protection gradient explicitly, and gradients are not
 * used anywhere on this site. A partial scrim reads as one. If the text is hard to read
 * over a particular photograph, the answer is a different photograph — stylelint bans
 * gradient functions in this file, so there is no way to reach for one here anyway.
 */
.ss-hero__overlay {
  position: absolute;
  inset: 0;
  background: var(--ss-ink);
  opacity: 0.55;

  /**
   * ── ZERO MARGIN IS LOAD-BEARING ─────────────────────────────────────────
   *
   * The overlay is the second child of a block-layout group, so WordPress gives it
   * `margin-block-start: var(--wp--style--block-gap)` — 32px here. On an absolutely
   * positioned box with `inset: 0` and no height, a top margin does not move the box, it
   * moves AND shrinks it: `top + margin-top + height + bottom` has to equal the
   * container, so the box starts 32px down and ends 32px short.
   *
   * The measured result was an overlay at top 186 inside a hero at top 154 — a 32px band
   * of unscrimmed photograph across the top of every hero on the site, under the white
   * heading. Nothing about the rule above is wrong; the margin is applied afterwards.
   *
   * Any absolutely positioned layer placed inside a block layout needs this. There is one
   * today; the reason is written here so the next one is not debugged from scratch.
   */
  margin: 0;
}

.ss-hero__inner {
  position: relative;
  width: 100%;

  /* Centred within the layout, like .container in the reference. Without the max-width
     the auto margins have nothing to centre and the hero copy ran to the viewport edge
     at 1920px — 80px from the left where the design puts it at 320px. */
  max-width: var(--layout-max);
  padding-block: var(--space-11);
  padding-inline: var(--layout-gutter);
  margin-inline: auto;
}

.ss-hero__eyebrow {
  color: var(--ss-zinc);
  margin-bottom: var(--space-4);
}

.ss-hero__heading {
  color: var(--text-inverse);
  max-width: 22ch;
}

.ss-hero__sub {
  color: var(--ss-zinc);
  margin-top: var(--space-5);
  max-width: 62ch;
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.ss-hero__actions {
  margin-top: var(--space-8);
}

@media (width <= 768px) {
  .ss-hero {
    min-height: 460px;
  }
}

/* ── Proof bar ────────────────────────────────────────────────────────────── */

.ss-proof {
  border-top: var(--hairline);
  border-bottom: var(--hairline);
  background: var(--surface-base);
}

.ss-proof__inner {
  max-width: var(--layout-max);
  padding-inline: var(--layout-gutter);
  margin-inline: auto;
}

.ss-proof__list {
  margin: 0;
  gap: 0;
}

.ss-proof__item {
  padding: var(--space-7) var(--space-5);
  border-left: var(--hairline);
}

.ss-proof__item:first-child {
  border-left: 0;
  padding-left: 0;
}

.ss-proof__value {
  font-family: var(--font-display);
  font-size: 34px;
  line-height: 40px;
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
  color: var(--ss-blue);
  font-variant-numeric: tabular-nums;
  display: block;
}

.ss-proof__label {
  font-family: var(--font-mono);
  font-size: var(--type-eyebrow-size);
  line-height: var(--type-eyebrow-line);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--text-secondary);
  display: block;
  margin-top: var(--space-2);
}

@media (width <= 768px) {
  /**
   * ── WHY THIS SELECTOR IS SO LONG ────────────────────────────────────────
   *
   * Core's columns stylesheet carries
   *
   *   @media (max-width: 781px) {
   *     .wp-block-columns:not(.is-not-stacked-on-mobile) > .wp-block-column {
   *       flex-basis: 100% !important;
   *     }
   *   }
   *
   * so the design's two-up — ported value for value — lost, and the proof bar became
   * five stacked rows on every tablet: 686px against the design's 413px.
   *
   * !important alone does not win it. Between two !important declarations the more
   * specific one takes it, and core's is three classes; a bare `.ss-proof__item` is
   * one. Hence the full path, which is four.
   *
   * The class core provides for opting out, is-not-stacked-on-mobile, is not the answer
   * either: it also sets `flex-wrap: nowrap !important`, which would put five figures
   * across a 360px phone.
   *
   * min-width is here for the same reason and needs the same selector: core sets
   * `min-width: 0` on every column and wins against a bare `.ss-proof__item`. It is what
   * makes the bar go two-up at 768 and ONE-up at 360 — at 360 a 50% column is 156px,
   * under the floor, so it wraps rather than squeezing five figures onto a phone. With
   * the floor missing the bar stayed two-up at 360, which the design does not do.
   */
  .wp-block-columns.ss-proof__list > .wp-block-column.ss-proof__item {
    flex-basis: 50% !important;
    min-width: 160px;
  }

  .ss-proof__item {
    border-left: 0;
    border-top: var(--hairline);
    padding-inline: 0;
  }

  .ss-proof__item:first-child {
    border-top: 0;
  }

  .ss-proof__value {
    font-size: 26px;
    line-height: 32px;
  }
}

/* ── Section ──────────────────────────────────────────────────────────────── */

.ss-section {
  padding-block: var(--section-pad-y);
  padding-inline: var(--layout-gutter);
}

.ss-section--paper {
  background: var(--surface-section);
  border-top: var(--hairline);
  border-bottom: var(--hairline);
}

/**
 * One part of a detail page — detail.module.css `.block`.
 *
 * A hairline and 80px, not the 120px a marketing section gets. A detail page has seven of
 * these and reads as a document; at section spacing it would read as seven pages.
 *
 * The first has no rule above it because the header already ends with one.
 */
.ss-detail-block {
  padding-block: var(--space-10);
  border-top: var(--hairline);
}

.ss-detail-block:first-of-type {
  border-top: 0;
}

.ss-section__title {
  max-width: 26ch;
  margin-bottom: var(--space-5);
}

.ss-section__lead {
  color: var(--text-secondary);
  max-width: var(--measure-prose);
  margin-bottom: var(--space-8);
}

/**
 * ── PROSE HAS A MEASURE ─────────────────────────────────────────────────────
 *
 * Body copy generated into a section inherited the section's contentSize — 1,280px,
 * about 190 characters a line where the design sets ~90. Measured across ten generated
 * pages, six were running the full width.
 *
 * A class rather than `p:not([class])`, which was the first attempt and matched nothing:
 * WordPress adds `wp-block-paragraph` to every paragraph it renders, so there is no such
 * thing as an unclassed one. The class is applied by SS\Pages_Command::section() to body
 * copy only — a callout is a box and takes the box's width, an eyebrow is a label, and
 * anything inside a block is laid out by the block that owns it.
 */
.ss-prose {
  max-width: var(--measure-prose);
}

/* ── Page header ──────────────────────────────────────────────────────────── */

.ss-page-header {
  padding-block: var(--space-10) var(--space-8);
  padding-inline: var(--layout-gutter);
  border-bottom: var(--hairline);
}

.ss-page-header__breadcrumb {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: var(--tracking-mono);
  color: var(--text-secondary);
  margin-bottom: var(--space-5);
}

.ss-page-header__breadcrumb a {
  color: var(--text-secondary);
}

.ss-page-header__breadcrumb a:hover {
  color: var(--ss-blue);
}

.ss-page-header__lead {
  color: var(--text-secondary);
  margin-top: var(--space-5);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  max-width: var(--measure-prose);
}

/* ── Call to action ───────────────────────────────────────────────────────── */

.ss-cta {
  padding-block: var(--section-pad-y-tight);
  padding-inline: var(--layout-gutter);
  background: var(--surface-section);
  border-top: var(--hairline);
}

.ss-cta__heading {
  max-width: 22ch;
}

.ss-cta__body {
  color: var(--text-secondary);
  margin-top: var(--space-4);
  max-width: var(--measure-prose);
}

.ss-cta__actions {
  margin-top: var(--space-7);
}

/* ── Buttons ──────────────────────────────────────────────────────────────
   Ported from components/core/Button.module.css, which the first pass did not port at
   all — it styled the two outline variants and let everything else fall through to core.

   Core gives .wp-block-button__link no size of its own, so every button inherited the
   18px body size and core's em-derived padding. The reference distinguishes `md` (16px)
   from `lg` (17px); at 18px both, that distinction was gone and every action on the site
   was a step too large. `md` is the base here and `lg` is applied where the reference
   asks for it, at the end of this section so it wins on source order.

   "A pressed control changes colour, not geometry." Every variant carries a 1px border,
   transparent where it is not drawn, so nothing shifts between states. */

.wp-block-button__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  border: 1px solid transparent;
  font-size: 16px;
  line-height: 24px;
  padding: var(--space-3) var(--space-5);
  transition:
    background-color var(--motion-hover) var(--ease-standard),
    border-color var(--motion-hover) var(--ease-standard),
    color var(--motion-hover) var(--ease-standard);
}

/**
 * Secondary — a hairline that goes to ink on hover.
 *
 * The port had ink at rest, so every secondary action on the page read as a primary one:
 * "Open the library", "All projects" and "Read more" were all drawn in a 1px black box
 * where the design draws them in --ss-zinc. The padding is repeated because core's
 * `.wp-block-button.is-style-outline > .wp-block-button__link` out-specifies the base
 * rule above and would otherwise reinstate its own em-based padding and 2px border.
 */
.is-style-outline .wp-block-button__link {
  background: transparent;
  color: var(--action-secondary-fg);
  border: 1px solid var(--border-hairline);
  padding: var(--space-3) var(--space-5);
}

.is-style-outline .wp-block-button__link:hover {
  background: transparent;
  color: var(--action-secondary-fg);
  border-color: var(--action-secondary-border);
}

/**
 * Secondary on photography — Button.module.css `.onDark.secondary`.
 *
 * --action-secondary-fg is ink, and ink on a 55% ink overlay is unreadable. White at 55%
 * for the border, solid white text; on hover the border goes to full white over a 10%
 * white wash rather than filling solid, which would be a geometry-free but very loud
 * state change on a photograph.
 */
.is-style-outline-inverse .wp-block-button__link {
  background: transparent;
  color: var(--text-inverse);
  border: 1px solid rgb(255 255 255 / 55%);
  padding: var(--space-3) var(--space-5);
}

.is-style-outline-inverse .wp-block-button__link:hover {
  background: rgb(255 255 255 / 10%);
  color: var(--text-inverse);
  border-color: var(--ss-white);
}

/**
 * The reference's `lg`: the hero's two actions and the closing "Request a quote".
 *
 * Last in the section on purpose — these carry the same specificity as the variant rules
 * above and must win, exactly as .onDark does in Button.module.css for the same reason.
 */
.ss-hero__actions .wp-block-button__link,
.ss-contact-row .wp-block-button__link,
.ss-cta__actions .wp-block-button__link {
  font-size: 17px;
  padding: var(--space-4) 28px;
}

@media print {
  /* A hero is 600px of photograph at the top of a printed detail sheet. Architects
     print these to read the build-up, not the marketing. */
  .ss-hero,
  .ss-cta {
    display: none;
  }
}

/* ── Callouts ────────────────────────────────────────────────────────────────
   Ported from components/layout/Section.module.css (.callout, .pendingCallout)
   value for value, because the twenty static pages carry three things that are
   neither body copy nor a heading: a clarification, a warning, and the standing
   "not yet stated" notice on the legal stubs.

   The reference had these; the WordPress theme did not, so the pages had no way
   to say "this bit matters" other than by making it another paragraph. */

.ss-callout {
  border: var(--hairline);
  border-left: 2px solid var(--ss-blue);
  background: var(--surface-section);
  padding: var(--space-5) var(--space-6);
  font-size: 17px;
  line-height: 27px;
}

/**
 * A callout is a panel, not a paragraph.
 *
 * theme.css sets `p { max-width: var(--measure-prose) }` — 68ch — and so does the
 * reference's globals.css, byte for byte. It never reaches the reference's callouts
 * because those are `<div>`s; here they are `<p>`s, so every callout on the site was
 * capped at 530px inside containers up to 1,280 wide. On the material register that put
 * the same sentence on four lines where the design has it on two.
 *
 * The measure exists so a paragraph of body copy is readable at length. A boxed 13px
 * mono statement is scanned, not read at length, and it is bounded by its own border.
 */
.ss-callout,
.ss-callout--pending {
  max-width: none;
}

/* The gate's own voice. Monospaced on purpose: a figure that is not yet stated
   should not look like prose, because prose is what a reader skims. */
.ss-callout--pending {
  border: 1px solid var(--border-pending);
  border-left: 1px solid var(--border-pending);
  background: var(--surface-pending);
  padding: var(--space-5) var(--space-6);
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 21px;
  letter-spacing: var(--tracking-mono);
  color: var(--text-pending);
}

/* A footnote, not a callout. LibraryIndex.tsx sets the in-preparation remark 12px mono
   secondary — it is a note ABOUT the page rather than a paragraph of it, and at body size
   it competes with the thing it is annotating. `note:<key>` in the composition table. */
.ss-footnote {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 19px;
  letter-spacing: var(--tracking-mono);
  color: var(--text-secondary);
}

.ss-note-list {
  margin: 0;
  padding-left: var(--space-5);
  font-size: 17px;
  line-height: 27px;
  max-width: var(--measure-prose);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* ── Left, not centred ───────────────────────────────────────────────────────
   WordPress's constrained layout puts `margin-left: auto; margin-right: auto` —
   with !important — on every child of the group. A child that fills the content
   width is unaffected; one with its own narrower max-width (a heading capped at
   26ch, a standfirst capped at the prose measure) drifts into the middle of the
   page. Every generated page shipped with its leads floating mid-canvas.

   The section keeps its full-bleed background, so it cannot simply be given a
   max-width — the alternating white/paper grounds must span the viewport. Instead
   the padding does the centring, exactly as .container does in the reference
   (styles/globals.css): the content box becomes layout-max minus two gutters,
   centred, and the children then align to its left edge like normal text.

   The doubled class out-specifies `.is-layout-constrained > *`; the !important
   answers WordPress's own. */

/* Not .ss-main: it is a bare wrapper with no padding of its own, and the sections
   inside it carry theirs. Padding both stacked two gutters and pushed every page's
   content in by 104px. The detail archive's <main> is itself an .ss-section, so it
   is still padded — once. */
.wp-block-group.ss-section,
.wp-block-group.ss-page-header,
.wp-block-group.ss-detail-block,
.wp-block-group.ss-detail {
  padding-inline: max(
    var(--layout-gutter),
    calc((100% - var(--layout-max)) / 2 + var(--layout-gutter))
  );
}

.wp-block-group.ss-section > *,
.wp-block-group.ss-page-header > *,
.wp-block-group.ss-detail-block > *,
.wp-block-group.ss-detail > *,
.wp-block-group.ss-main > *,
.wp-block-group.ss-hero__inner > *,
.wp-block-group.ss-proof__inner > * {
  margin-inline: 0 !important;
}

/* ── Home page ───────────────────────────────────────────────────────────────
   Ported value for value from components/layout/Section.module.css. These are
   the compositions the home page makes that no other page does: two audience
   doors, a photograph pair, an action row and the contact line. */

.ss-doors {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

.ss-door {
  display: block;
  height: 100%;
  border: var(--hairline);
  border-radius: var(--radius-sm);
  padding: var(--space-7);
  color: var(--ss-ink);
  transition: border-color var(--motion-hover) var(--ease-standard);
}

.ss-door:hover {
  border-color: var(--ss-ink);
}

.ss-door__title {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 32px;
  font-weight: var(--weight-semibold);
  margin: 0;
}

.ss-door__title a {
  color: inherit;
  text-decoration: none;
}

.ss-door__body {
  color: var(--text-secondary);
  margin-top: var(--space-3);
  font-size: 17px;
  line-height: 27px;
  max-width: 46ch;
}

.ss-media-grid {
  gap: var(--space-8);
}

/**
 * Section.module.css `.split` — two equal columns that become one at 1024.
 *
 * Both halves of that need answering, because core's columns block has its own opinion in
 * two places: it stacks below 781px, and above 781px it runs `flex-wrap: nowrap
 * !important`. Left alone, a split would be two columns from 782 up, where the design has
 * one until 1025.
 */
.ss-split {
  gap: var(--space-9);
  align-items: start;
}

/* Section.module.css .splitWide — 1fr 340px, for a wide thing beside a narrow one.
   The project page pairs the photographs with a data card, and an equal split gave the
   card half the page: the section came to 845px against the design's 1,530, because the
   photographs had only half the width to be tall in. */
.ss-split--wide > .wp-block-column:last-child {
  flex-basis: 340px !important;
  flex-grow: 0;
}

@media (width <= 1024px) {
  .ss-split {
    flex-wrap: wrap !important;
  }

  .ss-split > .wp-block-column {
    flex-basis: 100% !important;
  }
}

/**
 * ── FIGURES ARE CROPPED, NOT LET LOOSE ──────────────────────────────────────
 *
 * Ported from Section.module.css `.figureImage`, which the theme never carried. Without
 * it every photograph on the site rendered at whatever aspect the camera happened to
 * produce: the thermal-break pair came out 4:3 against the design's 16:9 (+151px at
 * 1440, +310px at 768), and the INSULTERM photograph rendered 1280 × 1707 — a portrait
 * the height of two viewports where the design has a 640px square.
 *
 * A general rule rather than a per-section one. The site photographs are site
 * photographs: they are illustrative, they arrive in whatever shape a phone took them
 * in, and the design crops them so a page's rhythm does not depend on that. Drawings —
 * which carry information and must never be cropped — are not .ss-figure; they go
 * through the detail blocks.
 */
.ss-figure img,
.ss-media-grid .wp-block-image img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* The one square in the design: the INSULTERM surface, beside its material register. */
.ss-figure--square img {
  aspect-ratio: 1 / 1;
}

.ss-figure figcaption,
.ss-media-grid figcaption {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: var(--tracking-mono);
  color: var(--text-secondary);
  margin-top: var(--space-3);
  text-align: left;
}

.ss-actions {
  margin-top: var(--space-8);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Section.module.css `.contactRow`. The number and the action sit on one line, because
   the action is what the number is there to prompt. */
.ss-contact-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-9);
  align-items: center;
}

/* The wp:buttons wrapper inside the row brings its own top margin from the flow layout,
   which would push the button off the baseline it shares with the number. */
.ss-contact-row .wp-block-buttons {
  margin-block: 0;
}

.ss-contact-phone {
  font-family: var(--font-mono);
  font-size: 26px;
  letter-spacing: var(--tracking-mono);
  color: var(--ss-ink);
  margin-top: var(--space-2);
}

.ss-contact-phone a {
  color: inherit;
  text-decoration: none;
}

@media (width <= 768px) {
  .ss-doors {
    grid-template-columns: 1fr;
  }
}

/* ── Definition lists ─────────────────────────────────────────────────────
   Section.module.css `.definitionList`. Term and value, mono throughout, because
   everything in one of these is data: a specification, a total, a material property. */

/* Section.module.css .subheading — a point INSIDE a section, not a section of its own.
   The sub: body form emits these, so Placner's three functions read as one argument about
   one sheet rather than as three sections that happen to be adjacent. */
.ss-subheading {
  font-family: var(--font-display);
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-line);
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-4);
}

/* The paragraph a subheading introduces sits tighter to it than to the next subheading. */
.ss-subheading + .ss-prose {
  margin-top: 0;
}

.ss-deflist {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4) var(--space-8);
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--type-data-size);
  letter-spacing: var(--tracking-mono);
}

.ss-deflist dt {
  color: var(--text-secondary);
}

.ss-deflist dd {
  margin: 0;
}

/* ── Process steps ────────────────────────────────────────────────────────
   The manufacturing sequence: photographs with numbered captions, auto-fit so the row
   reflows rather than breaking to a fixed column count. */

.ss-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-5);
}

.ss-steps__step {
  margin: 0;
}

.ss-steps__step img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
  display: block;
}

.ss-steps__step figcaption {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: var(--tracking-mono);
  color: var(--text-secondary);
  margin-top: var(--space-3);
}
