/* Layer 2: section styles (SPEC §5.4), the only place these classes are styled.
   Written entirely in layer-1 custom properties from tokens.css.

   A section sets the colours that apply inside it as --section-* properties; block CSS
   in site.css uses only those, so every block works on every surface. */

.block {
  --section-bg: var(--color-background);
  --section-text: var(--color-text);
  --section-muted: var(--color-muted);
  --section-link: var(--color-link);
  --section-button-bg: var(--color-accent);
  --section-button-text: var(--color-on-accent);
  --section-card: var(--color-surface);
  --section-border: var(--color-border);

  /* Derived from the section's own text colour, which every surface guarantees is
     readable against it, so a placeholder is visible on any surface — including one
     nobody has tested. A fixed colour cannot promise that. */
  --section-placeholder: color-mix(in srgb, var(--section-text) 10%, transparent);
  --section-placeholder-edge: color-mix(in srgb, var(--section-text) 40%, transparent);

  /* How much of the surface's own colour is washed over a background picture, so the
     words on top stay readable whatever the photograph is (D-024). A token rather than a
     number in a rule: a character that needs more of it says so in one place. */
  --section-picture-veil: 0.55;
  --section-rhythm: var(--space-xl);
  --section-width: var(--container-width);
  --divider-depth: var(--space-xl);

  position: relative;
  padding-block: var(--section-rhythm);
  color: var(--section-text);
  background: var(--section-bg);
}

.block > .container {
  max-width: var(--section-width);
  padding-block: 0;
}

/* Site chrome is drawn by the same machinery, so it arrives wearing .block and takes the
   rule above — a band of content's rhythm and the content's measure. Neither suits a bar.
   These overrides live HERE, beside the rule they answer, and not in site.css: the same
   two properties set there never applied, because .block weighs exactly as much and this
   file is linked second. A rule that loses silently is worse than no rule, and it cost two
   slices — the header's height fell anyway, for an unrelated reason, which made the first
   one look like it had worked (PLAN.md D-028, D-030, D-031). Zero, because the chrome's
   height is the owner's density choice (D-032), drawn by site.css on the bar itself. */
.block-header,
.block-footer {
  --section-rhythm: 0;
}

/* The header runs to the content's measure or edge to edge: its own decision, not the
   content's (D-031). Through --section-width rather than a max-width override, so the one
   rule above still decides how a container is measured. */
.block-header {
  --section-width: var(--page-header-width, var(--container-width));
}

/* Surface */

.surface-tinted {
  --section-bg: var(--color-surface);
  --section-card: var(--color-background);
}

.surface-contrast,
.surface-image {
  --section-bg: var(--color-contrast);
  --section-text: var(--color-on-contrast);
  --section-muted: var(--color-muted-on-contrast);
  --section-link: var(--color-on-contrast);
  --section-button-bg: var(--color-on-contrast);
  --section-button-text: var(--color-contrast);
  --section-card: var(--color-contrast-raised);
  --section-border: var(--color-muted-on-contrast);
}

/* Over a photograph, nothing is muted. A lowered-contrast secondary colour is right on a
   flat surface and wrong on a picture: measured on the demo under `soft`, the subheading
   fell across the busiest part of the photograph and was hard to read while the heading
   and the button were fine. D-024 puts the legibility treatment in tokens only, so this is
   a token and not a shadow or an outline behind the words.

   surface-image alone, not surface-contrast: a contrast section is a flat colour, where a
   muted tone is doing its job. */
.surface-image {
  --section-muted: var(--color-on-contrast);
}

.surface-gradient {
  --section-text: var(--color-on-gradient);
  --section-muted: var(--color-on-gradient);
  --section-link: var(--color-on-gradient);
  --section-button-bg: var(--color-on-gradient);
  --section-button-text: var(--color-gradient-start);
  --section-card: var(--color-gradient-end);
  --section-border: var(--color-on-gradient);

  background-image: linear-gradient(135deg, var(--color-gradient-start), var(--color-gradient-end));
}

/* A section's background picture (D-024).

   A real <picture>, laid under the content, not a CSS background-image: a URL is a
   per-section value and nothing is inlined as a style attribute (SPEC §5.4). As an element
   it also gets srcset, true width and height, and lazy loading for nothing extra, which a
   background-image cannot have.

   The contrast tokens above stay exactly as they are. They ARE the legibility treatment —
   text, links and buttons already switch to colours guaranteed against the contrast
   surface — and they keep working when no picture resolves, which is what makes
   surface: image with nothing chosen render as contrast rather than as a hole. */

.section-picture {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.section-picture img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* A wash between the picture and the words, in the surface's own background colour. The
   amount is a token, so a character that needs more of it says so once. */
.section-picture::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--section-bg);
  opacity: var(--section-picture-veil, 0.55);
}

/* The content sits above the picture. .block is already position: relative, so this needs
   nothing else. */
.surface-image > .container {
  position: relative;
  z-index: 1;
}

/* Where a crop holds its subject. object-position travels as a CLASS because a focal point
   is a per-picture value and a style attribute is not allowed (SPEC §5.4). Two axes at 10%
   steps is 22 rules rather than the 121 a grid of pairs would need, and 10% is finer than
   anyone can pick out of the thumbnail they set it on. MediaPicture::FOCAL_STEP rounds to
   these; if that constant changes, these change with it. */

.focal-x-0 { object-position: 0% var(--focal-y, 50%); }
.focal-x-10 { object-position: 10% var(--focal-y, 50%); }
.focal-x-20 { object-position: 20% var(--focal-y, 50%); }
.focal-x-30 { object-position: 30% var(--focal-y, 50%); }
.focal-x-40 { object-position: 40% var(--focal-y, 50%); }
.focal-x-50 { object-position: 50% var(--focal-y, 50%); }
.focal-x-60 { object-position: 60% var(--focal-y, 50%); }
.focal-x-70 { object-position: 70% var(--focal-y, 50%); }
.focal-x-80 { object-position: 80% var(--focal-y, 50%); }
.focal-x-90 { object-position: 90% var(--focal-y, 50%); }
.focal-x-100 { object-position: 100% var(--focal-y, 50%); }

.focal-y-0 { --focal-y: 0%; }
.focal-y-10 { --focal-y: 10%; }
.focal-y-20 { --focal-y: 20%; }
.focal-y-30 { --focal-y: 30%; }
.focal-y-40 { --focal-y: 40%; }
.focal-y-50 { --focal-y: 50%; }
.focal-y-60 { --focal-y: 60%; }
.focal-y-70 { --focal-y: 70%; }
.focal-y-80 { --focal-y: 80%; }
.focal-y-90 { --focal-y: 90%; }
.focal-y-100 { --focal-y: 100%; }

/* Rhythm */

.rhythm-tight {
  --section-rhythm: var(--space-l);
}

.rhythm-airy {
  --section-rhythm: var(--space-3xl);
}

/* Width */

.width-narrow {
  --section-width: var(--container-narrow);
}

.width-wide {
  --section-width: var(--container-wide);
}

.width-full {
  --section-width: none;
}

/* A narrow measure is a reading column: two columns inside it leave neither the picture
   nor the text enough room, so a picture-and-text block stacks. */
.width-narrow .image-text {
  grid-template-columns: 1fr;
}

/* Align */

.align-center {
  text-align: center;
}

/* Centre the section's own children. Deliberately not justify-items: that resolves a
   nested grid's columns to their content width, which collapses a media placeholder
   sized as a percentage of the column it sits in. */
.align-center .container > * {
  margin-inline: auto;
}

/* A rule down the left edge of a centred quote reads as detached from it. */
.align-center .richtext blockquote {
  padding-inline-start: 0;
  border-inline-start: 0;
}

/* Divider: drawn on the top edge of the section it belongs to. */

.divider-line {
  border-top: var(--border-width) solid var(--color-border);
}

.divider-slant,
.divider-curve {
  margin-top: calc(var(--divider-depth) * -1);
  padding-top: calc(var(--section-rhythm) + var(--divider-depth));
}

/* The section above a shaped edge keeps extra room at its bottom, so the edge never
   covers its content, whatever that section's rhythm. */
.block:has(+ .divider-slant),
.block:has(+ .divider-curve) {
  padding-bottom: calc(var(--section-rhythm) + var(--divider-depth));
}

.divider-slant {
  clip-path: polygon(0 var(--divider-depth), 100% 0, 100% 100%, 0 100%);
}

.divider-curve {
  border-top-left-radius: 50% var(--divider-depth);
  border-top-right-radius: 50% var(--divider-depth);
}

/* A divider marks a transition between two sections. The first section has nothing to
   transition from, and a shaped edge there is simply clipped by the top of the page, so
   the first section never draws one whatever its stored style says. */
main > .block:first-child {
  margin-top: 0;
  padding-top: var(--section-rhythm);
  border-top: 0;
  clip-path: none;
  border-start-start-radius: 0;
  border-start-end-radius: 0;
}
