@font-face{font-family:'Bitter';src:url('../fonts/heading-bitter.woff2') format('woff2');font-style:normal;font-weight:100 900;font-display:swap}
@font-face{font-family:'Roboto';src:url('../fonts/body-roboto.woff2') format('woff2');font-style:normal;font-weight:100 900;font-display:swap}
/* =====================================================================
   base.css — reset, accessibility mechanics and form plumbing.
   Shared, unchanged, by every site in this set. It carries no colour, no
   type family and no spacing of its own: those belong to design.css, which
   is what makes each site look like itself.
   ===================================================================== */

/* --- reset ---------------------------------------------------------- */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100%;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ol, ul, fieldset {
  margin: 0;
}

/* The UA stylesheet gives <figure> margin: 1em 40px. Eighty horizontal
   pixels of margin inside a grid cell overflowed the document at 320px. */
figure { margin: 0; padding: 0; }

ol, ul { padding: 0; list-style: none; }

/* A long email address, file name or URL inside running text overflows a
   320px viewport. It has to be set on the text elements themselves. */
p, li, dd, dt, td, th, address, blockquote, figcaption, summary, label,
.measure {
  overflow-wrap: break-word;
  word-break: normal;
}

address { font-style: normal; }

/* `height: auto` is load-bearing. Every <img> ships explicit width and height
   attributes so the box is reserved before the bytes arrive (CLS 0); without
   this rule the intrinsic height stays fixed while max-width narrows the
   element, and the picture distorts. */
img, svg, video, canvas {
  display: block;
  max-width: 100%;
  height: auto;
}

/* <picture> is an inline wrapper with no height of its own: an aspect-ratio
   or a percentage height set on it does nothing at all. Take it out of the
   box tree and let the <img> inside be the box. */
picture { display: contents; }

table { border-collapse: collapse; width: 100%; }

hr { border: 0; border-top: 1px solid currentColor; opacity: 0.25; margin: 0; }

/* --- typography defaults -------------------------------------------- */

h1, h2, h3, h4, h5, h6 {
  font-weight: 700;
  text-wrap: balance;
}

a { color: inherit; }

strong, b { font-weight: 700; }

/* --- fonts ---------------------------------------------------------- */
/* `optional` is the CLS-0 choice and the reason every page measures zero.
   `swap` reflows the whole page when the file lands; `block` shows nothing
   and then reflows. `optional` gives the font one very short window and
   otherwise keeps the fallback for that page load, moving nothing. */

/* --- accessibility mechanics ---------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  font-weight: 700;
}

.skip:focus {
  left: 0;
  outline-offset: 2px;
}

.vh {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: var(--focus-width, 3px) solid var(--focus-ring, currentColor);
  outline-offset: var(--focus-offset, 3px);
}

/* Every interactive target clears 44x44 CSS pixels. Stated as a minimum on
   the control itself rather than as padding, so a short label cannot shrink
   it below the floor. */

/* :where() and not a bare selector list, because this rule exists only to
   beat the USER AGENT -- a button's grey, an anchor's blue -- and must lose
   to every design rule that follows it. Written plainly, `a.btn` scores
   (0,1,1) and silently outranks a design's own `.btn--book` at (0,1,0): the
   design sets a white label, the browser keeps the inherited ink, and the
   contrast sweep reports 2.56:1 on a palette that is actually fine. Inside
   :where() the whole list scores zero and the design always wins.

   Note it is `color`, not `font`, that needs the zero: a design that wants a
   different font on a control states it on a class, which beats (0,1,1)
   nowhere near as reliably as it beats (0,0,0). Both are wrapped for the
   same reason. */
:where(a.btn, button, input, select, textarea, summary) {
  font: inherit;
  color: inherit;
}

a.btn, button, summary, select, input[type="submit"] {
  min-height: 44px;
}

button, summary, a.btn, label, select { cursor: pointer; }

summary { display: block; }
summary::-webkit-details-marker { display: none; }

/* --- grid primitives ------------------------------------------------ */
/* A bare `1fr` track has min-width: auto, so one wide child pushes the track
   past its share and the whole grid overflows the document. Every track in
   this build is minmax(0, 1fr). */

.grid { display: grid; gap: var(--gap, 24px); }
.grid > * { min-width: 0; }

/* A grid item's min-height resolves to auto, which defeats aspect-ratio: the
   ratio is ignored and the item grows to fit its content instead. */
.grid > .ratio, .ratio { min-height: 0; }

/* `grid-column: span N` writes BOTH edges of the placement -- it sets the
   start to `span N` as well, which is not what a span class means. Span
   classes therefore write the END only, and start classes the START only. */
.span-2 { grid-column-end: span 2; }
.span-3 { grid-column-end: span 3; }
.span-4 { grid-column-end: span 4; }
.span-6 { grid-column-end: span 6; }
.span-8 { grid-column-end: span 8; }
.span-12 { grid-column-end: span 12; }

/* --- forms ---------------------------------------------------------- */

.field { display: block; }

.field > label {
  display: block;
  font-weight: 700;
}

.field input,
.field select,
.field textarea {
  display: block;
  width: 100%;
  max-width: 100%;
  min-height: 44px;
  font: inherit;
  border-radius: inherit;
}

.field textarea {
  min-height: 132px;
  resize: vertical;
}

.field .hint { display: block; }

.field .err:empty { display: none; }

[aria-invalid="true"] { border-width: 2px; }

[data-state="idle"]:empty { display: none; }

/* --- reduced motion -------------------------------------------------- */
/* A hard stop, not a softening. The audit fails on any element reporting an
   animation-duration or a transition-duration above 0.02s here, and fails
   again on any text element below opacity 0.99 -- both correct, because the
   animation-off state each specification names is the FINISHED arrangement,
   never a slower approach to it. Anything that reveals itself by animating
   must therefore also be fully present with no animation at all. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- print ----------------------------------------------------------- */

@media print {
  .skip, .drawer, .sub-band { display: none; }
  body { background: #FFFFFF; color: #000000; }
}
/* Catalogue typography identity — headings and reading text. */
:root{--catalog-font-heading:'Bitter', Georgia, 'Times New Roman', serif;--catalog-font-body:'Roboto', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif}
html body,input,select,textarea,button{font-family:var(--catalog-font-body)}
h1,h2,h3,h4,h5,h6,.display,.disp,.brand,.logo{font-family:var(--catalog-font-heading)}
