@layer layout {
  /* Page shell: header, main, footer; footer sticks to the bottom on short pages. */
  .page {
    display: grid;
    grid-template-rows: auto 1fr auto;
    min-block-size: 100dvh;
  }

  .page__main {
    container: main / inline-size;
    padding-block: var(--space-l) var(--space-2xl);
  }

  /* Horizontally centred, width-limited wrapper with side gutters. */
  .center {
    --center-max: 72rem;
    inline-size: min(100% - 2 * var(--gutter), var(--center-max));
    margin-inline: auto;

    &.center--narrow { --center-max: 27rem; }
    &.center--text   { --center-max: 44rem; }
  }

  /* Vertical rhythm via gap. Override spacing with --stack-gap. */
  .stack {
    display: flex;
    flex-direction: column;
    gap: var(--stack-gap, var(--space-m));

    &.stack--s { --stack-gap: var(--space-s); }
    &.stack--xs { --stack-gap: var(--space-xs); }
    &.stack--l { --stack-gap: var(--space-l); }
  }

  /* Wrapping inline group (buttons, nav items, badges). */
  .cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cluster-gap, var(--space-xs));

    &.cluster--between { justify-content: space-between; }
    &.cluster--end { justify-content: flex-end; }
  }

  /* Responsive grid without media queries. */
  .auto-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--auto-grid-min, 16rem)), 1fr));
    gap: var(--auto-grid-gap, var(--space-m));

    /* Keep empty tracks so a lone item keeps its card size instead of stretching. */
    &.auto-grid--fill {
      grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--auto-grid-min, 16rem)), 1fr));
    }
  }

  /* Skip link for keyboard users, visible on focus only. */
  .skip-link {
    position: absolute;
    inset-block-start: var(--space-2xs);
    inset-inline-start: var(--space-2xs);
    z-index: 100;
    padding: var(--space-2xs) var(--space-xs);
    border-radius: var(--radius-m);
    background: var(--color-surface);
    box-shadow: var(--shadow-m);
    translate: 0 calc(-100% - var(--space-s));
    transition: translate var(--duration-base) var(--ease-out);

    &:focus-visible {
      translate: 0 0;
    }
  }

  /* Site header */
  .site-header {
    position: sticky;
    inset-block-start: 0;
    z-index: 10;
    view-transition-name: site-header;
    background: color-mix(in oklab, var(--color-bg) 82%, transparent);
    backdrop-filter: saturate(1.4) blur(12px);
    border-block-end: var(--border-width) solid color-mix(in oklab, var(--color-border) 70%, transparent);
  }

  .site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-s);
    min-block-size: 3.75rem;
  }

  /* Site footer */
  .site-footer {
    border-block-start: var(--border-width) solid var(--color-border);
    padding-block: var(--space-m);
    color: var(--color-text-muted);
    font-size: var(--step--1);

    & a {
      color: inherit;
    }
  }

  /* Auth screens: one centred card, vertically centred on tall viewports. */
  .auth-shell {
    display: grid;
    align-content: center;
    gap: var(--space-l);
    min-block-size: 100dvh;
    padding-block: var(--space-xl);
    background:
      radial-gradient(60rem 30rem at 50% -10%, color-mix(in oklab, var(--color-accent) 9%, transparent), transparent 70%),
      var(--color-bg);
  }

  .auth-shell__brand {
    justify-self: center;
  }

  .auth-shell__footer {
    justify-self: center;
    color: var(--color-text-muted);
    font-size: var(--step--1);

    & a { color: inherit; }
  }
}
