/*
 * Layout: structure only. No typefaces, colors, or borders here; those
 * belong to the style.
 *
 * Built from Every Layout's primitives, under the book's names: Stack,
 * Box, Center, Cluster, Sidebar (.with-sidebar, .sidebar, .not-sidebar),
 * Switcher, Cover (.centered), Grid, and Frame. Size modifiers name a
 * step on our space scale (.stack-l, .cluster-xs) rather than the
 * book's .stack-large style, so the CSS has one size vocabulary.
 */

/* A basic reset, so every browser starts from the same place (Rutter,
   "Use a basic reset to ensure consistency"). */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Hidden visually but still read by screen readers, for a control
   whose visible label is an icon. */
.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The skip link: off screen until it has keyboard focus, then at the
   top of the page, so keyboard users can jump past the header. */
.skip-link {
  position: absolute;
  inset-inline-start: var(--space-s);
  inset-block-start: var(--space-s);
  z-index: 2;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

/* The measure axiom (Every Layout, "Axioms"): no line of text runs
   longer than the measure, except in elements that only hold layout. */
* {
  margin: 0;
  padding: 0;
  max-inline-size: var(--measure);
}

html,
body,
div,
header,
nav,
main,
footer,
section,
article,
aside,
figure,
picture,
table,
ul,
ol,
dl,
details {
  max-inline-size: none;
}

/* ---------------------------------------------------------------------
 * Primitives (Every Layout). Each is configured with a custom property
 * set by a modifier class, since inline styles aren't allowed.
 * ------------------------------------------------------------------ */

/* Stack: vertical space between siblings, nothing outside them. Every
   Layout sets the space as a margin on each child; a gap on the Stack
   itself does the same job without a nested Stack's own spacing
   overriding its parent's. */
.stack {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--stack-space, var(--space-s));
}

.stack-2xs {
  --stack-space: var(--space-2xs);
}

.stack-xs {
  --stack-space: var(--space-xs);
}

.stack-m {
  --stack-space: var(--space-m);
}

.stack-l {
  --stack-space: var(--space-l);
}

.stack-xl {
  --stack-space: var(--space-xl);
}

/* Box: padding on all sides. */
.box {
  padding: var(--box-space, var(--space-m));
}

.box-l {
  --box-space: var(--space-l);
}

/* Center: a centered column with a maximum width and minimum gutters. */
.center {
  box-sizing: content-box;
  max-inline-size: var(--center-width, var(--measure));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.center-wide {
  --center-width: var(--width-wide);
}

.center-narrow {
  --center-width: var(--measure-narrow);
}

/* Cluster: items in a row that wrap, with even gaps. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cluster-space, var(--space-s));
  align-items: center;
}

.cluster-between {
  justify-content: space-between;
}

.cluster-l {
  --cluster-space: var(--space-l);
}

.cluster-xs {
  --cluster-space: var(--space-xs);
}

/* Sidebar: a fixed-ish side and a fluid main part that stack when the
   main part would be narrower than half the container. */
.with-sidebar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sidebar-gap, var(--gutter));
}

.with-sidebar > .sidebar {
  flex-basis: var(--sidebar-width, 20rem);
  flex-grow: 1;
}

.with-sidebar > .not-sidebar {
  flex-basis: 0;
  flex-grow: 999;
  min-inline-size: var(--sidebar-content-min, 50%);
}

.with-sidebar-gap-xl {
  --sidebar-gap: var(--space-xl);
}

/* Switcher: side by side above a threshold width, stacked below it. */
.switcher {
  display: flex;
  flex-wrap: wrap;
  gap: var(--switcher-gap, var(--gutter));
}

.switcher > * {
  flex-grow: 1;
  flex-basis: calc((var(--switcher-threshold, 40rem) - 100%) * 999);
}

.switcher-gap-xl {
  --switcher-gap: var(--space-xl);
}

/* For three items: all three side by side, or all stacked, never two
   and one (Rutter, "Beware of the tablet problem"). The threshold
   allows about 15rem per item. */
.switcher-three {
  --switcher-threshold: 48rem;
}

/* Cover: a block with a minimum height and one vertically centered
   child, with optional content above and below. */
.cover {
  display: flex;
  flex-direction: column;
  min-block-size: var(--cover-height, 80vh);
  padding-block: var(--space-l);
}

.cover > * {
  margin-block: var(--space-s);
}

.cover > :first-child:not(.centered) {
  margin-block-start: 0;
}

.cover > :last-child:not(.centered) {
  margin-block-end: 0;
}

.cover > .centered {
  margin-block: auto;
}

/* Grid: as many columns as fit at a minimum width. */
.grid {
  display: grid;
  gap: var(--grid-gap, var(--gutter));
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--grid-min, 16rem), 100%), 1fr)
  );
}

.grid-min-s {
  --grid-min: 11rem;
}

.grid-min-l {
  --grid-min: 22rem;
}

.grid-gap-xl {
  --grid-gap: var(--space-xl);
}

/* Frame: a fixed aspect ratio that crops its content. */
.frame {
  aspect-ratio: var(--frame-n, 3) / var(--frame-d, 2);
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}

.frame > img,
.frame > video {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.frame-square {
  --frame-n: 1;
  --frame-d: 1;
}

.frame-portrait {
  --frame-n: 4;
  --frame-d: 5;

  /* A portrait frame that has stacked under its text shouldn't fill a
     tablet-width column and run a screen and a half tall. */
  max-inline-size: 24rem;
}

.frame-wide {
  --frame-n: 16;
  --frame-d: 9;
}

/* ---------------------------------------------------------------------
 * Page regions
 * ------------------------------------------------------------------ */

.region {
  padding-block: var(--region-space, var(--space-2xl));
}

.region-s {
  --region-space: var(--space-l);
}

.region-l {
  --region-space: var(--space-3xl);
}

/* ---------------------------------------------------------------------
 * Compositions specific to particular layout options
 * ------------------------------------------------------------------ */

/* Numbered steps: across on wide screens, down on narrow ones. */
.steps {
  counter-reset: step;
  list-style: none;
}

.steps > li {
  counter-increment: step;
}

/* Header option H1, the chosen header: the links in a row where they
   fit on one line, a menu button where they don't. The header is a
   container (Every Layout, "The Container"), so the switch follows the
   header's own width, in ems of its own text size, which tracks the
   type scale (Rutter, "Use ems rather than pixels to determine the
   screen width"). Only one of the two navigations is displayed, so
   assistive technology meets only one. */
.site-header {
  container-type: inline-size;
  position: relative;
}

.site-header .header-links {
  display: none;
}

/* An icon-only menu button: no disclosure triangle. */
.menu-button {
  display: flex;
  list-style: none;
}

.menu-button::-webkit-details-marker {
  display: none;
}

/* The wordmark, the five links in nav.js, and the button measured
   43.9em, plus 3em of side gutters; 48em leaves a little room. Measure
   again if the links change. */
@container (min-width: 48em) {
  .site-header .header-links {
    display: block;
  }

  .site-header .header-menu {
    display: none;
  }
}

/* Header option H2: the menu button sits in the bar, and its panel
   opens below the whole header. */
.header-compact {
  position: relative;
}

.menu > nav {
  position: absolute;
  z-index: 1;
  inset-inline: 0;
  inset-block-start: 100%;
  padding-block: var(--space-m);
}

/* Header option H3: everything centered. */
.header-centered {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-s);
  text-align: center;
}

/* Figures: the number above its label. The label comes first in the
   markup (a dt has to precede its dd) and is shown second, so labels
   that wrap don't push the numbers out of line. */
.figure-stat {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  gap: var(--space-2xs);
}

/* Timeline: year beside the event, aligned on a shared column. */
.timeline {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-m) var(--space-l);
  align-items: baseline;
}

/* Comparison table: let wide tables scroll rather than squash (Rutter,
   "Let the browser handle tables with horizontal scrolling"). */
.table-scroll {
  overflow-x: auto;
}

/* Questions: each one a disclosure. */
.questions > details + details {
  margin-block-start: var(--space-xs);
}

/* ---------------------------------------------------------------------
 * Running text
 * ------------------------------------------------------------------ */

/* Prose: space between blocks in ems, so it follows the text size.
   Paragraphs are separated by no more than 1em (Rutter, "Separate
   paragraphs by no more than 1 em"); headings get more space above than
   below, so each belongs to the text it introduces (Rutter, "Show
   relationships and draw attention"). */
.prose > * + * {
  margin-block-start: 1em;
}

.prose > :is(h2, h3, h4, h5) {
  margin-block-start: 2em;
}

.prose > :is(h2, h3, h4, h5) + * {
  margin-block-start: 0.5em;
}

.prose > :is(figure, .breakout) {
  margin-block: 2em;
}

.prose :is(ul, ol) {
  padding-inline-start: 1.25em;
}

.prose li + li {
  margin-block-start: 0.25em;
}

.prose blockquote {
  padding-inline-start: 1em;
}

/* A figure that extends past the text column into the margins, up to a
   wider limit (Rutter, "Bring the design into the margins", "Allow
   embedded media to break the rhythm"). Works inside a centered column. */
.breakout {
  inline-size: min(56rem, 100vw - 2 * var(--gutter));
  margin-inline-start: 50%;
  transform: translateX(-50%);
}

.breakout > figcaption {
  max-inline-size: var(--measure);
  margin-inline: auto;
  margin-block-start: var(--space-xs);
}
