/* =============================================================================
   COMPONENTS
   Each block below is a pattern lifted from the reference site's vocabulary and
   rebuilt as plain CSS. Class names are BEM-ish: .block__element--modifier.
   ========================================================================== */

/* --- Page shell ----------------------------------------------------------- */

.page {
  display: grid;
  min-height: 100vh;
  /* minmax(0, 1fr) rather than 1fr: stops any long unbreakable child from
     growing the track past the viewport. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 1fr auto;
  gap: var(--space-16);
}

.shell {
  min-width: 0;
  width: 100%;
  max-width: var(--width-page);
  margin-inline: auto;
  padding: var(--space-4) var(--space-4) var(--space-20);
}

@media (min-width: 40rem) {
  .shell {
    padding: var(--space-6) var(--space-6) var(--space-24);
  }
}

@media (min-width: 48rem) {
  .shell {
    padding: var(--space-10) var(--space-10) var(--space-32);
  }
}

.section {
  margin-top: var(--space-32);
}

.section--tight {
  margin-top: var(--space-16);
}

/* --- Masthead ------------------------------------------------------------- */

.masthead {
  display: grid;
  gap: var(--space-6);
  align-items: end;
  padding-bottom: var(--space-10);
}

@media (min-width: 64rem) {
  .masthead {
    grid-template-columns: 1fr 1fr;
    gap: var(--gutter);
  }
}

/* The wordmark is set in mono, tracked in tight, and scales with the viewport
   so it always fills its column. Rendered as text, not an image. */
.wordmark {
  font-family: var(--font-mono);
  font-size: clamp(2rem, 9vw, 3.75rem);
  line-height: var(--leading-flush);
  letter-spacing: var(--tracking-tighter);
  text-transform: uppercase;
  color: var(--accent);
}

.masthead__standfirst {
  color: var(--ink-body);
}

.masthead__byline {
  font-weight: var(--weight-medium);
}

@media (min-width: 64rem) {
  .masthead__blurb {
    text-align: right;
  }
}

/* --- Shade rule ----------------------------------------------------------- */
/* A horizontal rule drawn from the ░ block character, as on the source site.
   Decorative, so it is hidden from assistive tech. */

/* The glyph run is deliberately longer than any viewport. It lives on an
   absolutely positioned pseudo-element so it contributes nothing to the
   element's intrinsic width — otherwise it forces the whole grid track wider
   than the page and everything to its right gets clipped. */
/* Height tracks --text-xs exactly: the ░ glyph fills its em box, so a shorter
   line box clips it. */
.shade-rule {
  position: relative;
  display: block;
  min-width: 0;
  block-size: 0.8125rem;
  overflow: hidden;
  user-select: none;
}

.shade-rule::before {
  content: "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░"
    "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░"
    "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░";
  position: absolute;
  inset: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 0.8125rem;
  color: var(--ink-subtle);
  white-space: nowrap;
}

/* Rule with a centred mono label: ░░░░ LABEL ░░░░ */
.banner-rule {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--space-4);
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.banner-rule > * {
  min-width: 0;
}

/* --- Figure --------------------------------------------------------------- */
/* A framed technical plate. The frame is four dithered strips rather than a
   border, which is what gives the printed-screen quality. */

.figure {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  padding: var(--space-8) var(--space-6);
  /* Flat tint for the ground so the dithered frame strips read against it.
     Ground and frame sharing one texture makes the frame disappear. */
  background-color: var(--accent-tint);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.figure__frame {
  position: absolute;
  background-image: url("/texture.svg");
  background-repeat: repeat;
  pointer-events: none;
}

.figure__frame--top {
  inset-inline: 0;
  top: 0;
  height: 2px;
}

.figure__frame--bottom {
  inset-inline: 0;
  bottom: 0;
  height: 2px;
}

.figure__frame--left {
  inset-block: 0;
  left: 0;
  width: 2px;
}

.figure__frame--right {
  inset-block: 0;
  right: 0;
  width: 2px;
}

/* Captions run up the sides of the plate, printed on the paper colour so the
   dither is knocked out behind them. */
.figure__caption {
  position: absolute;
  top: var(--space-1);
  left: 1.125rem;
  transform-origin: 0 0;
  rotate: 90deg;
  padding-inline: var(--space-1);
  background: var(--background);
}

.figure__caption--right {
  top: var(--space-1);
  right: 1.125rem;
  left: auto;
  transform-origin: 0 100%;
  translate: 100% -100%;
}

.figure__plate {
  width: 100%;
  max-width: 26rem;
  height: auto;
}

/* A plate that stands on its own between blocks of text rather than sitting
   inside a column. */
.figure--spread {
  max-width: 40rem;
  margin-inline: auto;
  padding-block: var(--space-10);
}

.figure--spread .figure__plate {
  max-width: 28rem;
}

/* --- Prose ---------------------------------------------------------------- */

.prose {
  max-width: var(--measure);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink-body);
}

.prose > * + * {
  margin-top: var(--space-6);
}

.prose strong {
  font-weight: var(--weight-semibold);
  color: var(--ink);
}

/* --- Statement ------------------------------------------------------------ */
/* A single load-bearing claim. Larger than body copy, still the serif — there
   is no display face in this system, so scale and tighter leading do the work.
   Held to the prose measure so it never runs the full page width. */

.statement {
  max-width: var(--measure);
  font-size: clamp(var(--text-lg), 3.2vw, var(--text-2xl));
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
  color: var(--ink);
}

/* --- Split ---------------------------------------------------------------- */
/* Two columns of independent blocks — not flowing text, so this is a grid
   rather than `columns`. Collapses to one column below 48rem. */

.split {
  display: grid;
  gap: var(--space-10) var(--gutter);
  max-width: var(--width-content);
}

.split > * {
  min-width: 0;
}

@media (min-width: 48rem) {
  .split {
    grid-template-columns: 1fr 1fr;
  }
}

/* Justified multi-column text with a two-line drop cap. Columns balance so the
   last one is never a stub. */
/* Single column on small screens is set flush left. Justifying a ~40-character
   measure opens rivers that hyphenation cannot close, so justification and
   hyphens only switch on once there are at least two columns to work with. */
.columns {
  columns: 1;
  column-gap: var(--gutter);
  column-fill: balance;
  max-width: none;
  font-size: var(--text-sm);
  line-height: var(--leading-column);
  text-align: start;
}

@media (min-width: 40rem) {
  .columns {
    columns: 2;
    text-align: justify;
    hyphens: auto;
  }
}

@media (min-width: 80rem) {
  .columns {
    columns: 3;
  }
}

.columns > * + * {
  margin-top: var(--space-6);
}

.columns > * {
  break-inside: avoid;
}

.columns__lead::first-letter {
  -webkit-initial-letter: 2;
  initial-letter: 2;
  padding-right: var(--space-1);
  color: var(--accent);
}

/* --- Section heading ------------------------------------------------------ */

.heading {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-4);
  align-items: center;
  margin-bottom: var(--space-8);
}

.heading__title {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
}

.heading__line {
  height: 1px;
  background: var(--rule-strong);
}

.heading__meta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* --- Button --------------------------------------------------------------- */
/* One control style. The inset bevel is the entire affordance — no drop
   shadow, no fill change until :active. */

.button {
  display: inline-grid;
  grid-auto-flow: column;
  gap: var(--space-2);
  align-items: center;
  width: fit-content;
  min-height: 1.75rem;
  padding-inline: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  background: rgb(255 255 255 / 0.5);
  border: var(--border-hairline) solid var(--ink-muted);
  border-radius: var(--radius-sm);
  box-shadow: var(--bevel);
  transition:
    border-color var(--duration) var(--ease-out),
    background-color var(--duration) var(--ease-out),
    color var(--duration) var(--ease-out);
}

@media (hover: hover) {
  .button:hover:not(:disabled) {
    border-color: var(--rule-strong);
    color: var(--ink);
  }
}

.button:active:not(:disabled) {
  background: rgb(0 0 0 / 0.1);
}

.button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.button--accent {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent-strong);
}

@media (hover: hover) {
  .button--accent:hover:not(:disabled) {
    color: #fff;
    background: var(--accent-strong);
  }
}

/* --- Leader list ---------------------------------------------------------- */
/* Table-of-contents rows: label, dotted leader that eats the slack, value. */

.leaders {
  display: grid;
  gap: var(--space-2);
  max-width: var(--width-content);
}

.leaders__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-2);
  align-items: baseline;
}

.leaders__label {
  min-width: 0;
  overflow-wrap: break-word;
}

.leaders__label a {
  text-decoration-color: color-mix(in oklab, var(--accent) 50%, transparent);
}

/* The leader itself. repeating-linear-gradient rather than a row of periods,
   so it stays crisp and is never read aloud. */
.leaders__fill {
  height: 1px;
  translate: 0 -0.25em;
  background-image: repeating-linear-gradient(
    to right,
    var(--ink-subtle) 0 1px,
    transparent 1px 4px
  );
}

.leaders__value {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-muted);
}

/* --- Marks list ----------------------------------------------------------- */
/* Short statements, each opened by a mono mark. The mark is a real element
   rather than a ::before so it can be hidden from assistive tech — the meaning
   lives in the group's heading, not in the glyph. */

.marks {
  display: grid;
  gap: var(--space-4);
}

.marks__row {
  display: grid;
  grid-template-columns: 1rem 1fr;
  gap: var(--space-2);
  align-items: baseline;
  max-width: var(--measure);
  line-height: var(--leading-column);
}

.marks__mark {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--accent);
}

/* The negative set. Same shape, stated in the muted ink so the two columns are
   distinguishable at a glance and not only by reading. */
.marks--negative .marks__mark {
  color: var(--ink-subtle);
}

.marks--negative .marks__row {
  color: var(--ink-muted);
}

/* --- Spec table ----------------------------------------------------------- */
/* Label/value pairs in mono, numbers right-aligned and tabular so columns of
   figures line up. */

.spec {
  display: grid;
  gap: var(--space-6) var(--space-24);
  padding: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  line-height: 1.4;
}

@media (min-width: 40rem) {
  .spec {
    grid-template-columns: 1fr 1fr;
  }
}

.spec__group {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-2);
  align-content: start;
}

.spec__key {
  text-transform: uppercase;
  color: var(--ink-muted);
}

.spec__value {
  justify-self: end;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* --- Progress bar --------------------------------------------------------- */
/* Drawn from block characters so it matches the shade rule. The accessible
   value lives on the element, not in the glyphs. */

.progress {
  display: grid;
  grid-template-columns: auto auto;
  gap: var(--space-2);
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2);
  border-bottom: var(--border-hairline) solid var(--rule-strong);
}

.progress__label {
  color: var(--ink);
}

.progress__track {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.2;
  letter-spacing: -0.08px;
  color: var(--accent);
  outline: 0.5px solid var(--accent);
}

/* --- Panel --------------------------------------------------------------- */

.panel {
  max-width: var(--width-prose);
  padding: var(--space-6);
  background: var(--accent-tint);
  border: var(--border-hairline) solid var(--rule);
  border-radius: var(--radius-sm);
}

.panel__title {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--ink);
}

/* --- Field --------------------------------------------------------------- */
/* Label and control share one hit target; the label is always rendered. */

.field {
  display: grid;
  gap: var(--space-2);
}

.field__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.field__control {
  width: 100%;
  min-height: 1.75rem;
  padding: var(--space-1) var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: rgb(255 255 255 / 0.5);
  border: var(--border-hairline) solid var(--ink-muted);
  border-radius: var(--radius-sm);
  box-shadow: var(--bevel);
}

.field__control:user-invalid {
  outline: 2px solid color-mix(in oklab, oklch(57.7% 0.245 27.325) 50%, transparent);
  outline-offset: 1px;
}

.field__row {
  display: grid;
  gap: var(--space-2);
}

@media (min-width: 30rem) {
  .field__row {
    grid-template-columns: 1fr auto;
    align-items: end;
  }
}

/* Async status messages announce themselves once, politely. */
.field__status {
  min-height: 1.25rem;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* --- Footer -------------------------------------------------------------- */

.footer {
  width: 100%;
  padding: var(--space-8) var(--space-4) var(--space-10);
  padding-bottom: max(var(--space-10), env(safe-area-inset-bottom));
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  color: var(--ink);
  text-align: center;
}

.footer__colophon {
  margin-top: var(--space-16);
  line-height: 2;
}

/* --- Swatches (style-guide page only) ------------------------------------ */

.swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: var(--space-2);
  max-width: var(--width-content);
}

.swatch {
  display: grid;
  gap: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.swatch__chip {
  height: 3.5rem;
  border: var(--border-hairline) solid var(--rule);
  border-radius: var(--radius-xs);
}

.specimens {
  display: grid;
  gap: var(--space-6);
  max-width: var(--width-content);
}

.specimen {
  display: grid;
  gap: var(--space-1);
  padding-bottom: var(--space-4);
  border-bottom: var(--border-hairline) solid var(--rule);
}

.specimen__meta {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  color: var(--ink-muted);
}
