/* ==========================================================================
   Norwood Design & Development — site styles

   Depends on tokens.css. Every value here comes from a token; see
   /docs/BRAND-ADDENDUM.md for the two deliberate deviations (mono font for
   code, and the fluid heading scale).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Shell — left-anchored, never centred

   BRAND.md section 4: "content hugging the left edge, whitespace carried on
   the right - do not centre page content." So no `margin-inline: auto`. The
   start gutter grows with the viewport but caps, so on an ultra-wide monitor
   the content sits off the edge rather than glued to it, and the slack still
   falls to the right.
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--container);
  margin-inline-end: auto;
  /* The start gutter grows further than the old 5vw/128px cap. On a wide
     monitor a small gutter made the content read as stuck to the edge rather
     than deliberately placed, which is the difference between composed
     asymmetry and an unfinished page. */
  padding-inline-start: clamp(var(--space-5), 6vw, 180px);
  padding-inline-end: var(--space-6);
}

/* The composition edge.

   On a wide display the content column occupies roughly half the screen and the
   remainder is empty. Left as-is that reads as an unfinished page; marked with a
   single fading hairline it reads as deliberate placement — the void becomes
   part of the composition rather than an absence.

   Consistent with BRAND.md 4 (rules fade out) and 8 (the accent is a line, never
   a flood). Only appears where there is actually surplus space to explain.

   If this proves too clever, deleting this block is the entire revert. */
@media (min-width: 1100px) {
  main.shell {
    position: relative;
  }

  main.shell::after {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    width: 1px;
    background: linear-gradient(180deg, var(--accent), transparent 55%);
    opacity: 0.45;
    pointer-events: none;
  }
}

.skip-link {
  position: absolute;
  inset-inline-start: var(--space-5);
  inset-block-start: calc(var(--space-5) * -4);
  z-index: 10;
  padding: var(--space-3) var(--space-5);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  color: var(--text);
  transition: inset-block-start var(--dur) var(--ease);
}

.skip-link:focus-visible {
  inset-block-start: var(--space-5);
}

/* --------------------------------------------------------------------------
   2. Header and footer
   -------------------------------------------------------------------------- */

.site-header {
  padding-block: var(--space-6);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-7);
  flex-wrap: wrap;
}

.site-header__logo {
  display: inline-flex;
  /* Clear space = one module, a quarter of the stamp height (BRAND.md 6). */
  padding: var(--space-3);
  margin-inline-start: calc(var(--space-3) * -1);
  border-radius: var(--radius);
}

.site-nav__list {
  display: flex;
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  color: var(--text-muted);
  font-size: var(--text-small);
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
  color: var(--text);
  text-decoration: none;
}

.site-nav a[aria-current="page"] {
  /* A short solid mark, not a full rule (BRAND.md 4). */
  box-shadow: 0 2px 0 -1px var(--accent);
}

.site-footer {
  margin-block-start: var(--space-9);
  padding-block: var(--space-7) var(--space-8);
}

.site-footer__rule {
  margin-block-end: var(--space-6);
}

.site-footer__inner {
  display: flex;
  gap: var(--space-8);
  flex-wrap: wrap;
  font-size: var(--text-small);
}

.site-footer__block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.site-footer__name {
  font-weight: var(--weight-heading);
}

.site-footer__links {
  display: flex;
  gap: var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__legal {
  margin-block-start: var(--space-7);
  font-size: var(--text-small);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.site-footer__address {
  white-space: pre-line;
}

.site-footer p {
  margin: 0;
  max-width: var(--measure);
}

/* --------------------------------------------------------------------------
   3. Block grid

   Twelve columns. Column spans come from the Block Grid data type, which caps
   prose at 8 so it can never break the 68ch measure.
   -------------------------------------------------------------------------- */

.grid,
.grid-areas {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns, 12), minmax(0, 1fr));
  gap: var(--space-8) var(--space-6);
  align-items: start;
}

.grid__item,
.grid-area {
  grid-column: span var(--col-span, 12);
  min-width: 0;
}

/* Blocks size their type against the space they sit in, not the viewport. A
   statement in a 4-column aside and the same statement at 10 columns are the
   same width on a phone but need very different type sizes.

   The queries themselves live at the end of this file — see the note there. */
.grid__item {
  container-type: inline-size;
}

.grid__item--tight {
  margin-block-start: calc(var(--space-7) * -1);
}

.grid__item--loose {
  padding-block-start: var(--space-8);
}

/* Card treatment. Off by default — the page should read as one ground. */
.grid__item--surface {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

.grid-areas {
  margin-block-start: var(--space-6);
}

/* One column below the tablet breakpoint; spans stop meaning anything. */
@media (max-width: 900px) {
  .grid__item,
  .grid-area {
    grid-column: 1 / -1;
  }
}

/* --------------------------------------------------------------------------
   4. Buttons — outlined, never filled (BRAND.md 5)
   -------------------------------------------------------------------------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-block-start: var(--space-6);
}

.button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font-size: var(--text-body);
  font-weight: var(--weight-heading);
  line-height: 1.4;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}

.button:hover {
  border-color: var(--text-muted);
  text-decoration: none;
  color: var(--text);
}

.button--primary {
  border-color: var(--accent);
  color: var(--accent-300);
}

.button--primary:hover {
  background: var(--accent-tint);
  border-color: var(--accent-hover);
  color: var(--accent-300);
}

.button--primary:active {
  border-color: var(--accent-press);
}

.button[disabled],
.button[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   5. Blocks
   -------------------------------------------------------------------------- */

/* Hero ------------------------------------------------------------------- */
.hero__heading {
  margin-block-start: var(--space-4);
  max-width: 20ch;
}

.hero__standfirst {
  margin-block-start: var(--space-6);
  max-width: var(--measure);
  font-size: var(--text-section);
  line-height: var(--text-section-lh);
  color: var(--text-muted);
}

/* Prose ------------------------------------------------------------------ */
.prose {
  max-width: var(--measure);
}

.prose > * + * {
  margin-block-start: var(--space-5);
}

.prose h2 {
  margin-block-start: var(--space-7);
}

.prose h3 {
  margin-block-start: var(--space-6);
}

.prose ul,
.prose ol {
  padding-inline-start: var(--space-6);
}

.prose li + li {
  margin-block-start: var(--space-2);
}

/* Statement -------------------------------------------------------------- */
.statement {
  margin: 0;
  max-width: 28ch;
}

.statement__text {
  font-size: var(--text-h1);
  line-height: var(--text-h1-lh);
  letter-spacing: var(--text-h1-ls);
  font-weight: var(--weight-heading);
  /* Accent text at paragraph size must be the lighter step (BRAND.md 3). */
  color: var(--accent-300);
}

.statement__attribution {
  margin-block-start: var(--space-5);
  font-size: var(--text-small);
}

/* Service ---------------------------------------------------------------- */

/* Short solid accent mark (BRAND.md 4: marks under ~48px stay solid). It gives
   an iconless service something to open with. */
.service::before {
  content: "";
  display: block;
  width: var(--space-7);
  height: 1px;
  background: var(--accent);
  margin-block-end: var(--space-5);
}

/* When an icon is present it already does that job, and stacking both reads as
   two competing marks rather than one deliberate one. */
.service:has(.service__icon)::before {
  display: none;
}

.service__icon {
  display: block;
  font-size: 24px;
  color: var(--accent);
  margin-block-end: var(--space-4);
}

.service__heading {
  margin-block-start: var(--space-3);
  font-size: var(--text-section);
  line-height: var(--text-section-lh);
}

.service__body {
  margin-block-start: var(--space-4);
}

/* Fact ------------------------------------------------------------------- */
.fact__value {
  font-size: var(--text-h1);
  line-height: var(--text-h1-lh);
  letter-spacing: var(--text-h1-ls);
  font-weight: var(--weight-heading);
}

.fact__label {
  margin-block-start: var(--space-3);
}

/* Image ------------------------------------------------------------------ */
.figure {
  margin: 0;
}

.figure img {
  display: block;
  width: 100%;
  border-radius: var(--radius-lg);
}

/* For photographs shot on black — dark values fall away (BRAND.md 5). */
.figure--blend img {
  mix-blend-mode: lighten;
  border-radius: 0;
}

.figure__caption {
  margin-block-start: var(--space-4);
  font-size: var(--text-small);
}

/* Code ------------------------------------------------------------------- */
.code {
  margin: 0;
}

.code__language {
  margin-block-end: var(--space-3);
}

.code__pre {
  margin: 0;
  padding: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
  /* Deviation from "Inter for everything": code needs consistent advance
     widths. Documented in BRAND-ADDENDUM.md. */
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--text-small);
  line-height: 1.6;
  tab-size: 4;
}

.code__caption {
  margin-block-start: var(--space-4);
  font-size: var(--text-small);
}

/* Divider ---------------------------------------------------------------- */
.divider {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.divider__label {
  flex: none;
}

.divider__rule {
  flex: 1 1 auto;
}

/* Section ---------------------------------------------------------------- */
.section__header {
  max-width: var(--measure);
}

.section__heading {
  margin-block-start: var(--space-3);
}

/* Call to action --------------------------------------------------------- */
.cta__heading {
  max-width: 24ch;
}

.cta__body {
  margin-block-start: var(--space-5);
  max-width: var(--measure);
}

/* --------------------------------------------------------------------------
   6. Coming soon — TEMPORARY

   Delete this whole section, and the anchor on the block, once the real home
   page is published.

   Activated by setting the block's Anchor (in Block settings) to
   "coming-soon". No document type change and no separate template: the anchor
   field already exists, and :has() lets the page respond to it.

   Centring is a deliberate exception to BRAND.md section 4. That rule protects
   editorial layout — the 68ch measure, the asymmetry, whitespace carried right.
   A holding page has no editorial content for those to act on, and a single
   mark with two lines under it reads as off-centre rather than composed when
   pushed left. It must not become a precedent for real pages.
   -------------------------------------------------------------------------- */

body:has(#coming-soon) .shell {
  max-width: none;
  margin-inline: auto;
  padding-inline: var(--space-6);
}

/* The composition edge explains surplus space beside content. There is no
   content column here for it to relate to, so it would read as a stray line. */
body:has(#coming-soon) main.shell::after {
  display: none;
}

/* The header lockup is hidden rather than centred.

   The animated stamp below is the identity on this page, so a second static
   stamp above it duplicates the motif and competes with it — and its home link
   goes nowhere while the site is a single holding page. The footer still
   carries the company name, so nothing is lost.

   This also sidesteps an optical-centring problem: the horizontal lockup is a
   300-wide box whose ink stops around x=230, because the fading rule and
   descriptor trail off. Centring the box leaves the mark visibly left of centre.
   If a lockup is ever wanted in a centred context, use
   norwood-lockup-stacked-dark.svg — its rule fades symmetrically from the
   middle, which is exactly what centring needs. */
body:has(#coming-soon) .site-header {
  display: none;
}

#coming-soon {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 58vh;
  text-align: center;
}

/* The stamp draws its own N in stroke order. CSS animations inside an SVG run
   when it is used as a background image, so no inline SVG or markup needed. */
#coming-soon::before {
  content: "";
  display: block;
  width: clamp(120px, 14vw, 176px);
  aspect-ratio: 1;
  margin-block-end: var(--space-8);
  background: url("/brand/svg/norwood-stamp-draw.svg") center / contain no-repeat;
}

/* Measure caps and left-aligned maxima fight the centring, so lift them here
   only. */
#coming-soon .hero__heading,
#coming-soon .cta__heading {
  max-width: 24ch;
}

#coming-soon .hero__standfirst,
#coming-soon .prose,
#coming-soon p {
  max-width: 46ch;
  margin-inline: auto;
}

#coming-soon .actions {
  justify-content: center;
}

/* The short accent mark is a left-aligned device; centred it reads as a stray
   dash floating above the text. */
#coming-soon .service::before {
  display: none;
}

/* --------------------------------------------------------------------------
   7. Narrow containers

   MUST stay at the end of this file. A container query adds no specificity of
   its own, so `.statement__text` inside @container and `.statement__text` in
   section 5 above have identical weight and source order decides the winner.
   Placed earlier, every one of these rules is silently overridden.

   Triggered by the width of the block's own .grid__item, not the viewport — so
   a statement in a 4-column aside shrinks while the page around it stays wide.
   -------------------------------------------------------------------------- */

@container (max-width: 460px) {
  .statement__text,
  .fact__value {
    font-size: var(--text-h2);
    line-height: var(--text-h2-lh);
    letter-spacing: var(--text-h2-ls);
  }

  .statement {
    max-width: none;
  }

  .hero__heading {
    font-size: var(--text-h1);
    line-height: var(--text-h1-lh);
    letter-spacing: var(--text-h1-ls);
  }

  .hero__standfirst {
    font-size: var(--text-body);
    line-height: var(--text-body-lh);
  }
}
