/* ===========================================================================
   HYPERINFRA - site.css
   ---------------------------------------------------------------------------
   The single stylesheet for the whole website.

   HOW THIS FILE IS ORGANISED (read top to bottom):
     01. Fonts .................. loading the two self-hosted typefaces
     02. Design tokens .......... all colours / sizes live here, change once
     03. Reset & base ........... sensible defaults for every element
     04. Paper texture .......... the faint grain over the whole page
     05. Layout ................. page width, sections, grids
     06. Typography ............. headings, paragraphs, small print
     07. Hand-drawn parts ....... sketch frames, wobbly rules, underlines
     08. Header & navigation .... top bar, including the mobile menu
     09. Buttons & links ........ all clickable things
     10. Hero ................... the big opening area on the home page
     11. Cards & lists .......... the boxed content blocks
     12. Prose .................. long text pages (Terms, Privacy)
     13. Contact ................ the email card
     14. Footer ................. the bottom of every page
     15. Accessibility & motion . focus rings, reduced motion, print

   If you only want to change colours, edit section 02 and nothing else.
   =========================================================================== */


/* ===========================================================================
   01. FONTS
   Both files live in this project (site/assets/fonts) so the browser never
   has to contact Google. Each file is a "variable" font, meaning one single
   file provides every weight from 300 (light) to 700 (bold).
   =========================================================================== */

@font-face {
  font-family: 'Fraunces';                          /* used for headings */
  src: url('../fonts/fraunces-latin.woff2') format('woff2');
  font-weight: 300 700;                             /* the range in the file */
  font-style: normal;
  font-display: swap;                               /* show fallback text first, swap when ready */
}

@font-face {
  font-family: 'Inter';                             /* used for body text */
  src: url('../fonts/inter-latin.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}


/* ===========================================================================
   02. DESIGN TOKENS
   Every colour and repeated measurement in the site is named here.
   :root means "the whole document", so these are available everywhere.
   =========================================================================== */

:root {

  /* --- Paper colours (backgrounds) ------------------------------------- */
  --paper:        #F0EEE6;   /* the main warm ivory page background        */
  --paper-lift:   #F8F6F0;   /* slightly lighter - used for cards          */
  --paper-deep:   #E7E3D7;   /* slightly darker - used for alternate bands */

  /* --- Ink colours (text and drawn lines) ------------------------------
     These have been checked for contrast against every background used on
     the site. If you darken a background or lighten one of these, re-check:
     body text needs a contrast ratio of at least 4.5 to 1.
       --ink    on --paper  = 15.9 : 1
       --ink-2  on --paper  =  7.6 : 1     on --paper-deep = 7.2 : 1
       --ink-3  on --paper  =  5.5 : 1     on --paper-deep = 5.0 : 1        */
  --ink:          #191917;   /* main text, and the colour of pen strokes   */
  --ink-2:        #4A4740;   /* secondary text                             */
  --ink-3:        #635F58;   /* quiet text: captions, small print          */
  --rule:         #D3CDBD;   /* hairline dividers                          */

  /* --- Accent colours --------------------------------------------------- */
  --clay:         #CC785C;   /* the warm terracotta accent                 */
  --clay-deep:    #A6512F;   /* darker clay, used for text on paper        */
  --clay-wash:    #F0DCD2;   /* very pale clay, used as a highlight fill   */
  /* --kraft is used for DRAWN LINES ONLY (braces, rules, list dashes), never
     for text — it is too pale against ivory to be readable as type. */
  --kraft:        #C89A6B;   /* muted tan, a second accent                 */
  --sage:         #5E6B57;   /* muted green, used for ticks and the        */
                             /* "copied" confirmation — 5.1 : 1 on a card  */

  /* --- Widths ----------------------------------------------------------- */
  --wrap:         1140px;    /* normal content width                       */
  --wrap-wide:    1360px;    /* wider content, used by the hero            */
  --wrap-prose:   680px;     /* narrow column for long reading (legal)     */
  --gutter:       clamp(1.25rem, 4vw, 3rem);  /* side padding, grows with screen */

  /* --- Vertical rhythm --------------------------------------------------- */
  --band-pad:     clamp(3.5rem, 7vw, 6.5rem); /* space above/below a section */

  /* --- Stroke width used by all hand-drawn SVG -------------------------- */
  --pen:          1.9px;
  --pen-thin:     1.3px;

  /* --- Motion ------------------------------------------------------------ */
  --ease:         cubic-bezier(0.22, 0.61, 0.36, 1);
}


/* ===========================================================================
   03. RESET & BASE
   A short, modern reset so browsers all start from the same place.
   =========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;      /* padding/border count inside an element's width */
}

html {
  -webkit-text-size-adjust: 100%;  /* stop iOS enlarging text on rotate */
  scroll-behavior: smooth;         /* gentle scrolling for in-page links */
}

body {
  margin: 0;

  /* Makes the footer sit at the bottom of the window even when a page has
     very little content on it — otherwise a short page (the not-found page,
     for instance) leaves a strip of bare background below the footer. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;

  background-color: var(--paper);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: clamp(1rem, 0.96rem + 0.18vw, 1.1rem);
  line-height: 1.65;
  font-weight: 400;
  /* Slightly softer letterforms, closer to a printed page. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Stops any element ever pushing the page sideways on small screens. */
  overflow-x: hidden;
}

/* Images and SVGs never overflow their container. */
img,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Remove the default list bullets everywhere; we add our own where wanted. */
ul, ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The hidden SVG "sprite" at the top of each page holds reusable drawings.
   It must not take up any space or be read out by screen readers. */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* Utility: visually hidden, but still announced by screen readers. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ===========================================================================
   04. PAPER TEXTURE
   A very faint grain laid over the entire page so the ivory background
   reads as paper rather than flat colour. It is decorative only and
   cannot be clicked through.
   =========================================================================== */

body::after {
  content: "";
  position: fixed;              /* stays put while the page scrolls */
  inset: 0;                     /* covers the whole viewport */
  pointer-events: none;         /* clicks pass straight through it */
  z-index: 9;
  opacity: 0.4;
  mix-blend-mode: multiply;     /* darkens very slightly, like fibres in paper */
  /* An inline SVG that generates random noise - no image file needed. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E");
}


/* ===========================================================================
   05. LAYOUT
   =========================================================================== */

/* .wrap centres content and keeps it from getting too wide on big monitors.
   "margin-inline: auto" is what centres it - important on 1920px+ screens. */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.wrap--wide  { max-width: var(--wrap-wide); }
.wrap--prose { max-width: var(--wrap-prose); }

/* A "band" is one full-width horizontal stripe of the page.
   The background colour always spans the entire screen width, so there is
   never a block of colour on only one side. */
.band {
  position: relative;
  padding-block: var(--band-pad);
}

.band--deep  { background-color: var(--paper-deep); }
.band--lift  { background-color: var(--paper-lift); }

/* The default page tone, stated explicitly. Used for a section that sits
   between two tinted bands and needs to be visibly separate from both —
   in particular the closing call to action, which would otherwise merge
   into the footer behind it. */
.band--paper { background-color: var(--paper); }

/* The hand-cut top edge of a band: a wobbly shape filled with the band's own
   colour, sitting just above it, so the join looks torn rather than ruled. */
.band__edge {
  position: absolute;
  left: 0;
  right: 0;
  top: -22px;
  width: 100%;
  height: 23px;
  display: block;
  pointer-events: none;
}
.band--deep   > .band__edge { fill: var(--paper-deep); }
.band--lift   > .band__edge { fill: var(--paper-lift); }
.band--paper  > .band__edge { fill: var(--paper); }
.site-footer  > .band__edge { fill: var(--paper-deep); }

/* Takes up whatever height is left over, pushing the footer to the bottom.
   Works with the flex column set on <body> above. */
main { flex: 1 0 auto; }

/* Simple vertical spacing helper: puts a gap between all direct children. */
.stack > * + * { margin-top: 1.1rem; }
.stack-lg > * + * { margin-top: 2rem; }

/* The standard section heading block, centred with a comfortable measure. */
.section-head {
  max-width: 52ch;
  margin-inline: auto;
  text-align: center;
  margin-bottom: clamp(2.25rem, 4vw, 3.5rem);
}

/* A small all-caps label that sits above a heading. */
.eyebrow {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--clay-deep);
  margin-bottom: 0.9rem;
}


/* ===========================================================================
   06. TYPOGRAPHY
   Headings use Fraunces (a warm serif). Body text uses Inter.
   The clamp() function means: never smaller than X, never larger than Z,
   and scale smoothly in between based on screen width.
   =========================================================================== */

h1, h2, h3, h4 {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-optical-sizing: auto;   /* lets the font adjust its shapes by size */
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;          /* avoids a single lonely word on the last line */
}

h1 { font-size: clamp(2.5rem, 1.5rem + 4vw, 4.5rem); }
h2 { font-size: clamp(1.9rem, 1.35rem + 2.1vw, 3rem); }
h3 { font-size: clamp(1.2rem, 1.08rem + 0.5vw, 1.5rem); line-height: 1.25; }
h4 { font-size: 1.05rem; line-height: 1.3; }

p { margin: 0; }

/* An introductory paragraph - larger and lighter than normal body text. */
.lead {
  font-size: clamp(1.1rem, 1.02rem + 0.42vw, 1.35rem);
  line-height: 1.6;
  color: var(--ink-2);
  font-weight: 350;
}

/* Quiet supporting text. */
.muted { color: var(--ink-3); }

.small {
  font-size: 0.875rem;
  line-height: 1.6;
}

/* Text emphasised in the accent colour, used sparingly inside headings. */
.accent { color: var(--clay-deep); }


/* ===========================================================================
   07. HAND-DRAWN PARTS
   These are the pieces that give the site its sketched feel.

   The trick used throughout: an SVG is stretched to any size using
   preserveAspectRatio="none", but each drawn line carries
   vector-effect="non-scaling-stroke" so the pen line stays the same
   thickness no matter how far the shape is stretched. Without that, a wide
   box would have a thick top line and a thin side line.
   =========================================================================== */

/* Shared appearance for every hand-drawn line in the site. */
.pen {
  fill: none;
  stroke: var(--ink);
  stroke-width: var(--pen);
  stroke-linecap: round;        /* rounded ends, like a felt-tip pen */
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.pen--thin  { stroke-width: var(--pen-thin); }
.pen--clay  { stroke: var(--clay); }
.pen--kraft { stroke: var(--kraft); }
.pen--sage  { stroke: var(--sage); }
.pen--soft  { stroke: var(--ink-3); }

/* A broken line, used for something planned or provisional rather than built.
   This MUST be a class and not a stroke-dasharray="..." attribute in the HTML:
   the draw-in animation further down sets stroke-dasharray itself, and a CSS
   rule always beats an attribute, so an attribute-based dash pattern would be
   silently overwritten and the line would come out solid. */
.pen--dashed { stroke-dasharray: 6 8; }

/* Solid (filled) hand-drawn shapes, e.g. the dot inside an icon. */
.ink-fill  { fill: var(--ink);  stroke: none; }
.clay-fill { fill: var(--clay); stroke: none; }

/* --- The sketch frame: a wobbly rectangle drawn around a box ------------ */
/* The parent needs position:relative; the frame fills it exactly. */
.sketch-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;             /* sits behind the card's own text */
  pointer-events: none;   /* never blocks clicks on the content inside */
  overflow: visible;      /* lets the pen overshoot slightly past the corner */
}

/* The drawn shape is ALSO the card's surface, so the paper and the pen line
   are exactly the same shape. This matters: with an ordinary rectangular
   background behind it, the square corners of that rectangle poke out past
   the places where the hand-drawn line bows inwards, and the whole effect
   collapses into "a white box with a wonky box drawn on it".
   The selector is more specific than .pen, so it wins over its fill:none. */
.sketch-frame use { fill: var(--paper-lift); }

/* On the lighter band, cards take the standard paper tone instead so that
   they stay distinguishable from the band behind them. */
.band--lift .sketch-frame use { fill: var(--paper); }

/* --- A wobbly horizontal divider ---------------------------------------- */
.hand-rule {
  display: block;
  width: 100%;
  height: 11px;
  margin-block: clamp(2rem, 4vw, 3rem);
}

/* --- A hand-drawn underline sitting under a word ------------------------ */
/* Wrap the word in <span class="marked">word<svg class="mark">…</svg></span> */
.marked {
  position: relative;
  display: inline-block;
  white-space: nowrap;
}

.mark {
  position: absolute;
  left: -2%;
  width: 104%;
  bottom: -0.22em;
  height: 0.34em;
  pointer-events: none;
  overflow: visible;
}


/* ===========================================================================
   08. HEADER & NAVIGATION
   =========================================================================== */

/* Lets keyboard users jump straight past the menu to the content. */
.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -120%);
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: 0.7rem 1.2rem;
  font-size: 0.9rem;
  text-decoration: none;
  border-radius: 0 0 6px 6px;
  transition: transform 0.18s var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); }

.site-header {
  position: sticky;            /* stays visible at the top while scrolling */
  top: 0;
  z-index: 50;
  background-color: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease);
}

/* A hairline appears under the header only once the page has scrolled.
   The .is-scrolled class is added by site.js. */
.site-header.is-scrolled {
  border-bottom-color: var(--rule);
  background-color: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 68px;
}

/* --- Logo --------------------------------------------------------------- */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--ink);
  flex-shrink: 0;
}

.logo__mark {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  overflow: visible;
}

.logo__text {
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  line-height: 1;
  padding-top: 2px;   /* optically centres the caps against the mark */
}

/* --- Navigation links ---------------------------------------------------- */
.nav {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.5vw, 2.25rem);
}

.nav__link {
  position: relative;
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 450;
  padding-block: 0.4rem;
  transition: color 0.18s var(--ease);
}

.nav__link:hover { color: var(--ink); }

/* The hand-drawn underline that appears under a nav link on hover,
   and stays put on the page you are currently viewing. */
.nav__link .mark {
  bottom: -0.05em;
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}
.nav__link:hover .mark,
.nav__link:focus-visible .mark,
.nav__link[aria-current="page"] .mark { opacity: 1; }
.nav__link[aria-current="page"] { color: var(--ink); font-weight: 500; }

/* --- Mobile menu button --------------------------------------------------- */
/* Hidden on desktop; shown by the media query further down. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--ink);
}

.nav-toggle__icon { width: 26px; height: 26px; overflow: visible; }

/* The two icons (three lines / a cross) swap depending on menu state. */
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-open  { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }


/* ===========================================================================
   09. BUTTONS & LINKS
   =========================================================================== */

/* Text links inside normal copy. */
.link {
  color: var(--clay-deep);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--clay) 45%, transparent);
  transition: border-color 0.18s var(--ease), color 0.18s var(--ease);
}
.link:hover {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* All buttons share this base. The irregular border-radius values are the
   trick that makes a plain CSS box look as if it was drawn by hand: each
   corner gets a different curve. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.78rem 1.5rem;
  font-family: 'Inter', sans-serif;
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  border: var(--pen) solid var(--ink);
  border-radius: 225px 14px 200px 16px / 16px 190px 14px 220px;
  background: transparent;
  color: var(--ink);
  transition: transform 0.16s var(--ease), background-color 0.18s var(--ease),
              color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

/* A tiny tilt and lift on hover, as if the sticker were being peeled up. */
.btn:hover {
  transform: translateY(-2px) rotate(-0.4deg);
  box-shadow: 3px 4px 0 color-mix(in srgb, var(--ink) 16%, transparent);
}
.btn:active { transform: translateY(0) rotate(0deg); box-shadow: none; }

/* Filled, high-emphasis button. */
.btn--primary {
  background-color: var(--clay);
  border-color: var(--clay-deep);
  color: #FFF9F5;
}
.btn--primary:hover { background-color: var(--clay-deep); }

/* Outlined, lower-emphasis button. */
.btn--ghost:hover { background-color: color-mix(in srgb, var(--ink) 5%, transparent); }

/* The little arrow drawn inside some buttons. */
.btn__arrow {
  width: 17px;
  height: 11px;
  flex-shrink: 0;
  overflow: visible;
  transition: transform 0.2s var(--ease);
}
.btn:hover .btn__arrow { transform: translateX(3px); }

/* A row of buttons that wraps neatly on narrow screens. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  align-items: center;
}


/* ===========================================================================
   10. HERO (home page opening area)
   =========================================================================== */

.hero {
  position: relative;
  padding-block: clamp(2.75rem, 6vw, 5.5rem) clamp(3rem, 6vw, 5rem);
}

/* Two columns on wide screens, one stacked column on narrow screens.
   Both halves sit on the same background - there is no block of colour
   filling one side. */
.hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.5rem, 5vw, 4rem);
  align-items: center;
}

/* The grid column already limits how wide this gets, so the heading is free
   to use the full column. Only the paragraph needs a reading measure. */
.hero__copy { min-width: 0; }
.hero h1 { margin-bottom: 1.4rem; }
.hero .lead { max-width: 46ch; margin-bottom: 2rem; }

/* The large drawing. */
.hero__art { width: 100%; overflow: visible; }

/* A short line of context under the buttons. */
.hero__note {
  margin-top: 1.75rem;
  font-size: 0.875rem;
  color: var(--ink-3);
}


/* ===========================================================================
   11. CARDS & LISTS
   =========================================================================== */

/* A fixed 2-column grid rather than an automatic one.
   "auto-fit" was tried first and rejected: with four cards it produced three
   across and one stranded alone on a second row at common laptop widths.
   One column on phones, two above that, always balanced. */
.grid {
  display: grid;
  gap: clamp(1.1rem, 2vw, 1.6rem);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Card ---------------------------------------------------------------- */
/* position:relative is required so the .sketch-frame can sit behind it.
   There is no background-color here on purpose — the hand-drawn frame
   provides the card's surface. See .sketch-frame use, in section 07. */
.card {
  position: relative;
  padding: clamp(1.6rem, 2.6vw, 2.1rem);
  transition: transform 0.2s var(--ease);
}

/* Keep the card's own content above the drawn frame behind it. */
.card > *:not(.sketch-frame) { position: relative; z-index: 1; }

/* Very slight lift, plus a hair of rotation so it feels drawn, not printed. */
.card:hover { transform: translateY(-3px) rotate(-0.22deg); }

.card__icon {
  width: 54px;
  height: 54px;
  margin-bottom: 1.15rem;
  overflow: visible;
}

.card h3 { margin-bottom: 0.6rem; }

.card p {
  color: var(--ink-2);
  font-size: 0.97rem;
}

/* --- Numbered principle list --------------------------------------------- */
/* Two columns, for the same reason as .grid above: four items in an
   automatic grid strand one of them on a row by itself. */
.principles {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem) clamp(1.5rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .principles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.principle {
  display: grid;
  grid-template-columns: auto 1fr;   /* the circled number, then the text */
  gap: 1.1rem;
  align-items: start;
}

/* The hand-drawn circle around each number. */
.principle__num {
  position: relative;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--clay-deep);
}

.principle__num svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.principle h3 { margin-bottom: 0.45rem; }
.principle p  { color: var(--ink-2); font-size: 0.97rem; }

/* --- A simple checklist with hand-drawn ticks ----------------------------- */
.ticks { display: grid; gap: 0.9rem; }

.tick {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.85rem;
  align-items: start;
  color: var(--ink-2);
}

.tick__icon {
  width: 21px;
  height: 21px;
  margin-top: 0.32rem;
  flex-shrink: 0;
  overflow: visible;
}

/* --- Split of heading text and supporting text, side by side -------------- */
.two-col {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
  align-items: start;
}


/* ===========================================================================
   12. PROSE (Terms and Privacy pages)
   A narrow, comfortable reading column.
   =========================================================================== */

.page-head {
  padding-block: clamp(2.5rem, 5vw, 4.5rem) clamp(1.5rem, 3vw, 2.5rem);
  text-align: center;
}

.page-head .lead {
  max-width: 46ch;
  margin-inline: auto;
  margin-top: 1.1rem;
}

.prose { padding-bottom: clamp(3.5rem, 7vw, 6rem); }

.prose h2 {
  font-size: clamp(1.35rem, 1.15rem + 0.75vw, 1.7rem);
  margin-top: 2.75rem;
  margin-bottom: 0.85rem;
}

.prose h3 {
  font-size: 1.1rem;
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
}

.prose p,
.prose li {
  color: var(--ink-2);
  font-size: 1rem;
  line-height: 1.75;
}

.prose p + p { margin-top: 1rem; }

/* Bulleted lists inside prose get a small hand-drawn dash instead of a dot. */
.prose ul { margin: 1rem 0; display: grid; gap: 0.6rem; }

.prose ul li {
  position: relative;
  padding-left: 1.5rem;
}

.prose ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 13px;
  height: 2px;
  background-color: var(--kraft);
  border-radius: 2px;
  transform: rotate(-1.5deg);   /* a dash that is not perfectly level */
}

/* A jump-to-section list at the top of the legal pages. */
.toc {
  position: relative;
  padding: 1.4rem 1.6rem;
  margin-bottom: 2.5rem;
  background-color: var(--paper-lift);
}

.toc h2 {
  font-size: 0.75rem !important;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 0.85rem !important;
}

.toc ol {
  display: grid;
  gap: 0.45rem;
  counter-reset: toc;   /* start our own numbering */
}

.toc li { counter-increment: toc; }

.toc a {
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.93rem;
  border-bottom: 1px solid transparent;
}

/* Prefix each entry with its own number, e.g. "01."
   Clay rather than kraft: these are real characters that have to be read, and
   kraft is too pale against the card to pass a contrast check. */
.toc a::before {
  content: counter(toc, decimal-leading-zero) ".";
  color: var(--clay-deep);
  margin-right: 0.55rem;
  font-variant-numeric: tabular-nums;
}

.toc a:hover { color: var(--ink); border-bottom-color: var(--kraft); }

/* A boxed aside used to explain something in plain language. */
.callout {
  position: relative;
  padding: 1.4rem 1.6rem;
  margin: 2rem 0;
  background-color: var(--clay-wash);
}

.callout p { color: var(--ink-2); font-size: 0.95rem; }

.callout__label {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--clay-deep);
  margin-bottom: 0.5rem;
}


/* ===========================================================================
   13. CONTACT
   =========================================================================== */

/* Like .card, the surface comes from the hand-drawn frame rather than from a
   background colour, so the paper and the pen line share one shape. */
.email-card {
  position: relative;
  max-width: 560px;
  margin-inline: auto;
  padding: clamp(1.9rem, 4vw, 2.9rem);
  text-align: center;
}

.email-card > *:not(.sketch-frame) { position: relative; z-index: 1; }

.email-card__icon {
  width: 62px;
  height: 62px;
  margin: 0 auto 1.35rem;
  overflow: visible;
}

/* The address itself - the single most important thing on the page. */
.email-address {
  display: inline-block;
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.2rem, 0.95rem + 1.15vw, 1.85rem);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -0.01em;
  margin-block: 0.4rem 1.5rem;
  /* Long addresses break rather than overflow on a narrow phone. */
  word-break: break-word;
}

.email-address:hover { color: var(--clay-deep); }

/* The "copied" confirmation. It is a normal element in the page, not a
   browser pop-up, and it is announced politely to screen readers. */
.copy-status {
  display: block;
  min-height: 1.35rem;
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--sage);
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}
.copy-status.is-visible { opacity: 1; }

.copy-status__inner {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.copy-status__tick { width: 15px; height: 15px; overflow: visible; }


/* ===========================================================================
   14. FOOTER
   =========================================================================== */

.site-footer {
  background-color: var(--paper-deep);
  padding-block: clamp(2.75rem, 5vw, 4rem) 2rem;
  margin-top: 0;
  position: relative;
}

.site-footer__grid {
  display: grid;
  gap: 2.25rem;
  grid-template-columns: 1fr;
  padding-bottom: 2.25rem;
}

.site-footer h4 {
  font-family: 'Inter', sans-serif;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.95rem;
}

.footer-links { display: grid; gap: 0.55rem; }

.footer-links a {
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.93rem;
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: color 0.16s var(--ease), border-color 0.16s var(--ease);
}
.footer-links a:hover { color: var(--ink); border-bottom-color: var(--kraft); }

.site-footer__about { max-width: 32ch; }
.site-footer__about p { font-size: 0.9rem; color: var(--ink-3); margin-top: 0.85rem; }

/* The bottom strip with the copyright line. */
.site-footer__base {
  border-top: 1px solid color-mix(in srgb, var(--ink) 11%, transparent);
  padding-top: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  font-size: 0.83rem;
  color: var(--ink-3);
}


/* ===========================================================================
   14b. THE "PAGE NOT FOUND" PAGE
   =========================================================================== */

.error-page { padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3.5rem, 7vw, 6rem); }

/* Stacked and centred on phones; side by side on wider screens. */
.error-page__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
  justify-items: center;
  text-align: center;
}

.error-page__art  { width: 100%; max-width: 440px; overflow: visible; }
.error-page__copy { max-width: 46ch; }

.error-page h1 {
  font-size: clamp(1.9rem, 1.4rem + 2.2vw, 3.1rem);
  margin-bottom: 1.15rem;
}

.error-page__actions { justify-content: center; margin-top: 2rem; }

@media (min-width: 860px) {
  .error-page__inner {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
    justify-items: start;
    text-align: left;
  }
  .error-page__actions { justify-content: flex-start; }
}


/* ===========================================================================
   14c. SMALL UTILITY CLASSES
   A handful of one-job classes, so the HTML files do not need any inline
   style="..." attributes. Named for what they do.
   =========================================================================== */

.pt-0  { padding-top: 0 !important; }
.pb-0  { padding-bottom: 0 !important; }
.mb-0  { margin-bottom: 0 !important; }
.mt-sm { margin-top: 1rem; }
.mt-lg { margin-top: 2rem; }

/* Shrinks the top padding of a band without removing it entirely. */
.pt-tight { padding-top: clamp(1rem, 2vw, 2rem) !important; }

/* Centres a row of buttons. */
.btn-row--center { justify-content: center; }

/* A heading that should sit a size smaller than its level would suggest. */
.h-sm { font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.55rem); }

/* Makes a drawn line take the colour of the surrounding text. Used for the
   arrow inside a button, which must be white on the filled clay button and
   dark on the outlined one. */
.pen--current { stroke: currentColor; }


/* ===========================================================================
   15. ACCESSIBILITY, MOTION & PRINT
   =========================================================================== */

/* A clear, on-brand focus ring for people navigating with a keyboard. */
:focus-visible {
  outline: 2px dashed var(--clay-deep);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Give the sticky header room so anchor links do not land under it. */
[id] { scroll-margin-top: 90px; }

/* --- The "draw yourself in" animation for the hero artwork ---------------- */
/* Each path is set to pathLength="1" in the HTML, so one dash value works
   for every line regardless of how long it really is. */
@keyframes draw-in {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Every solid line draws itself in. Deliberately dashed lines are excluded,
   because this rule would replace their dash pattern with its own. */
.draw .pen:not(.pen--dashed) {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: draw-in 1.15s var(--ease) forwards;
}

/* Shapes that cannot be "drawn" — filled dots, and dashed lines whose pattern
   must be preserved — fade in instead. */
.draw .ink-fill,
.draw .clay-fill,
.draw .pen--dashed {
  opacity: 0;
  animation: fade-in 0.5s var(--ease) forwards;
}

/* Stagger the strokes so the picture appears to be sketched in stages. */
.draw [data-delay="1"] { animation-delay: 0.05s; }
.draw [data-delay="2"] { animation-delay: 0.22s; }
.draw [data-delay="3"] { animation-delay: 0.40s; }
.draw [data-delay="4"] { animation-delay: 0.58s; }
.draw [data-delay="5"] { animation-delay: 0.76s; }
.draw [data-delay="6"] { animation-delay: 0.94s; }

/* Respect the operating-system setting "reduce motion": show everything
   immediately with no animation at all. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .draw .pen { stroke-dashoffset: 0; }
  .draw .ink-fill,
  .draw .clay-fill,
  .draw .pen--dashed { opacity: 1; }

  .btn:hover,
  .card:hover { transform: none; }
}


/* ===========================================================================
   RESPONSIVE ADJUSTMENTS
   Written mobile-first: the rules above are the phone layout, and these
   media queries add to them as the screen gets wider.
   =========================================================================== */

/* --- Phones: collapse the navigation into a menu ------------------------- */
@media (max-width: 767px) {

  /* Show the hamburger button. */
  .nav-toggle { display: inline-flex; }

  /* The menu panel drops down below the header. */
  .nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem var(--gutter) 1.25rem;
    background-color: var(--paper);
    border-bottom: 1px solid var(--rule);
  }

  .nav__link {
    padding-block: 0.85rem;
    font-size: 1.05rem;
    border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
  }

  .nav__link:last-child { border-bottom: none; }

  /* Hide the hover underline in the stacked menu - it would sit oddly. */
  .nav__link .mark { display: none; }

  /* When JavaScript is available the menu starts closed and only opens when
     the button is pressed. If JavaScript is unavailable the .js class is
     never added, so the links simply remain visible and usable. */
  .js .nav { display: none; }
  .js .nav.is-open { display: flex; }
}

/* --- Small tablets and up ------------------------------------------------ */
@media (min-width: 620px) {
  .site-footer__grid { grid-template-columns: 1.4fr 1fr 1fr; }
  .two-col { grid-template-columns: 1fr 1fr; }
}

/* --- Desktop: the hero becomes two columns ------------------------------- */
@media (min-width: 900px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
    gap: clamp(2rem, 4vw, 4.5rem);
  }

  .two-col--sticky > :first-child {
    position: sticky;
    top: 110px;   /* keeps the heading in view while the text scrolls */
  }
}

/* --- Very large monitors --------------------------------------------------
   Content is already centred by .wrap, so all that is needed is a little
   extra breathing room and slightly larger body text.                      */
@media (min-width: 1800px) {
  :root {
    --wrap:      1240px;
    --wrap-wide: 1480px;
  }
  body { font-size: 1.14rem; }
}

/* --- Printing ------------------------------------------------------------- */
@media print {
  .site-header,
  .site-footer,
  .nav-toggle,
  .skip-link,
  .band__edge,
  .hand-rule,
  .hero__art { display: none !important; }

  body::after { display: none; }   /* no paper grain when printing on paper */

  body { background: #fff; color: #000; font-size: 11pt; }
  .band, .card, .toc, .callout, .email-card { background: #fff !important; }
  a { color: #000; text-decoration: underline; }
}


/* ===========================================================================
   16. THE STAFF SIGN-IN BUTTON  (footer)
   ---------------------------------------------------------------------------
   THIS SECTION IS THE ENTIRE CHANGE MADE TO THIS STYLESHEET.

   It was written and agreed first as mockup/assets/site-addition.css, and then
   appended here unchanged in spirit. Not one line above this comment was
   edited, moved or deleted -- including the contents list at the top of the
   file, which therefore still stops at 15. That is deliberate rather than an
   oversight: the promise made about this change was that it is additive only,
   and a stylesheet whose every existing byte is untouched can be proved
   identical with a file comparison. A contents list is easier to correct later
   than a promise is to re-make.

   Everything the new "Staff sign in" button needs, and nothing else.

   Three choices worth stating, because each was a decision rather than a
   default:

   1. It is .btn--ghost, never .btn--primary. The filled clay button is the
      site's "do this next" button. Pointing it at a door that almost every
      reader cannot open would be misleading.

   2. It sits in the existing .site-footer__base flex row rather than in a new
      band of its own. A new band would change the shape of every page; adding
      one item to a row that already wraps changes nothing else.

   3. It is smaller than a normal button. In that strip it sits beside 0.83rem
      small print, and a full-size button next to small print reads as an
      advertisement.
   =========================================================================== */

/* The wrapper exists for two reasons: so the button can be ordered
   independently of the two paragraphs either side of it as the row wraps on a
   narrow screen, and so there is something to hide that is not the button
   itself.

   IT STARTS HIDDEN, AND THAT IS THE POINT.

   The button's address is not written into the page. It is set when the page
   loads from assets/js/origins.generated.js, because the console lives on a
   different hostname in each environment and six hand-written copies of a
   hostname means five of them go stale.

   So there is a moment -- and on a slow connection it is not a short one --
   between the page being painted and that address arriving. Showing the button
   during it would put a control on the page that looks pressable and does
   nothing, which is the worst of the three possible states: somebody presses
   it, nothing happens, and they have no way to tell whether the fault is the
   site's or their own. Starting hidden means that state cannot occur.

   The first version of this rule was ".no-js .footer-staff { display: none }",
   which read plausibly and was wrong. The one-line script in every page's
   <head> swaps "no-js" for "js" before the footer has even been parsed, so by
   the time the button exists that rule has already stopped applying. It
   covered only the case where JavaScript is switched off altogether. Hiding by
   default covers that case too, and needs no class on <html> to do it. */
.footer-staff {
  display: none;
  align-items: center;
  /* It sits directly under the paragraph describing what HYPERINFRA is, so it
     needs a gap that reads as "related to the block above, but a separate
     thing". Matches the space the footer already puts between a heading and
     its list of links. */
  margin-top: 0.9rem;
}

/* Added by assets/js/site.js on the same line that puts the address on, so the
   button becomes visible and becomes pressable in the same breath. A browser
   cannot paint between two statements in one function, so there is no frame in
   which it is one but not the other. */
.footer-staff--ready { display: inline-flex; }

/* A smaller button, for use inside the footer's first column. */
.btn--staff {
  padding: 0.42rem 0.9rem;
  font-size: 0.82rem;
  gap: 0.45rem;
  /* The footer sits on --paper-deep, one shade darker than the page. The
     button's outline is the same ink as everywhere else, so it needs no
     special colour -- but it does need to not look like a text link, hence
     keeping the full .btn border. */
}

.btn__staff-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  overflow: visible;   /* the drawn line overshoots its corners on purpose */
}

/* Nothing is needed here for a phone any more. The button used to be a flex
   item in the footer's bottom strip and had to be ordered last as that row
   wrapped; in the first column it simply follows the paragraph above it at
   every width. The rule that used to live here set "order" on something that
   is no longer a flex item, which would have done nothing while looking as
   though it did. */
