/* portal.css — the whole look of Adaptly, in one file.
   =================================================================================================
   NO BUILD STEP AND NO DEPENDENCY. The two worlds this page points at are hand written and
   toolchain free for reasons that are load bearing there; this is not going to be the loud thing in
   that arrangement. Every colour is a token, declared once.

   WHAT CHANGED IN THIS PASS, AND WHY. The founder read the page and said it felt like an unfinished
   blog page rather than a project. What was thin was structure and density, so:

     · THE PAGE IS WIDE AND THE PROSE IS NARROW. `.page` is now 64rem and a line of text is still
       capped at `--column`. That is the shape both reference sites have: a broad field with a
       narrow column of reading in it, and room beside the column for a label rail.
     · SECTIONS HAVE A LEFT RAIL AT DESKTOP WIDTH. `.band` puts the small typewriter label in a
       column of its own beside the prose. It stacks on a phone. This is the single thing that makes
       a run of sections read as a document rather than as a stack of posts.
     · THE TWO WORLDS SIT SIDE BY SIDE. Stacked, they read as two blog entries. Side by side, they
       read as two things to choose between, which is what they are. They stack on a phone and
       nowhere else.
     · THE WAY IN IS A BLOCK, NOT A LINK. `.launch` is the loudest thing on the page.

   THE FACES ARE THE COMPANY'S OWN, THEY ARE OPEN, AND THEY ARE SERVED FROM THIS ORIGIN. DM Sans,
   DM Mono and Nunito, all three under the SIL Open Font License, all three already in use on
   `bygamex.com`. He asked for Thinking Machines' face; that is GT America, which is commercial and
   licensed, so it was never a candidate. These are subset and self hosted, and `DEPLOYING.md` §15
   records what they cost, what was cut out of them, and the one command that makes them again.
   NOTHING IS FETCHED FROM ANOTHER HOST: the control refuses a `url()` that leaves this origin, and
   the policy in `_headers` carries `font-src 'self'` so the browser refuses one too.

   ONE GROUND, AND IT IS LIGHT. There is no dark variant. The founder chose the paper; a second
   ground that nobody has looked at is a second design maintained by nobody, and this site is small
   enough that the honest answer is to have one and get it right. `color-scheme: light` is declared
   so the browser's own furniture, scrollbars and focus rings, matches rather than fighting it.

   THE NAME IS NOT IN THIS FILE, AND THAT IS A REVERSAL. It used to be: a `--brand-name` custom
   property drawn into an empty <span> with `content:`, so the site had one place to change. The
   trade was written down at the time and it has now been called the wrong way round. Text drawn by
   CSS is NOT in the document's text: not selected when a reader drags across the page, not returned
   by a text extractor, not indexed by a search engine, and only mostly announced by assistive
   technology. That is an acceptable price for a decoration. IT IS NOT AN ACCEPTABLE PRICE FOR THE
   NAME OF THE SITE. So the name is typed into the markup, where it is real text, and the single
   source is kept by a CONTROL instead of by a variable: `the_front_door…mjs` declares the string
   once and refuses any page that spells it differently or leaves it out. A machine that compares
   four copies is a stronger check than one copy nobody can select. */

/* =================================================================================================
   THE FACES. Five files, one weight each, all under `fonts/`, all subset, all from this origin.

   `font-display: swap` paints the fallback stack immediately and swaps when the file lands. The
   alternative, `optional`, never reflows and also never uses the face on a first visit over a slow
   connection, which would mean the page draws its own name in the wrong letters for most of the
   people who ever see it once. Swap is the right trade at 64 kB from the same origin, and the three
   faces that carry text above the fold are preloaded in the markup of every page so the swap lands
   inside the first paint rather than after it.

   EVERY `src` HERE IS A RELATIVE PATH AND IT HAS TO BE. Assertion 4 refuses a `url()` in a
   stylesheet that names a host, carries a scheme, or is a `data:` blob, and it refuses one that is
   not a `.woff2`; assertion 1 then resolves what is left against the published set, so a font file
   that is declared and missing, or present and undeclared, stops the build rather than 404ing live.
   ============================================================================================== */

@font-face {
  font-family: "DM Sans";
  src: url("fonts/dm-sans-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("fonts/dm-sans-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "DM Mono";
  src: url("fonts/dm-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "DM Mono";
  src: url("fonts/dm-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;

  /* --- the two inks and the one green -----------------------------------------------------------

     ==============================================================================================
     THE GREEN, AND THE RULE THAT GOVERNS IT. READ THIS BEFORE REACHING FOR IT.
     ==============================================================================================

     `#3FFF90` IS THE COMPANY'S GREEN AND IT IS THE SAME HEX AS THE MARK. It sits at 1.21:1 against
     this paper, and `draw_the_mark.mjs` prints the same figure from its own arithmetic. The brief
     that asked for it carried the number as 1.26:1; either says the same thing, which is that there
     is almost no difference in LIGHTNESS between this green and this paper. What separates them is
     hue and saturation, and that is why the company's own site can put it on an off white ground
     and have it work.

     SO: A LOW RATIO MAKES IT UNUSABLE FOR TEXT AT READING SIZE AND IT DOES NOT MAKE IT UNUSABLE.
     Three uses, and they are the whole list:

       1 · AS A FILL BEHIND DARK TEXT. A block, a pill, a highlight. The contrast that matters then
           is the ink ON the green, and `#141414` on `#3FFF90` is 13.9:1, which is better than the
           body text on this page. `.launch` is exactly this ON HOVER AND ON FOCUS. It used to be
           the fill at rest, the full width of a card, and the founder's note was that the block is
           far too loud; the colour is the reward for reaching for the control now rather than the
           state it sits in. Both states are legible and both were computed rather than eyeballed:
           ink on paper at rest, ink on the green when it lights.
       2 · AS DISPLAY TYPE AT VERY LARGE SIZES, where a word is a shape rather than a paragraph.
           Nothing here does this today. The room is left for it deliberately.
       3 · AS SMALL SOLID MARKS. A rule, a dot, a bullet, the mark itself. Nothing has to be read
           out of any of those, and the hue carries them where the lightness does not.

     NEVER AS BODY TEXT. NEVER AS A LINK COLOUR, INCLUDING THE UNDERLINE UNDER ONE. NEVER AS
     ANYTHING A PERSON READS A SENTENCE OF. Links on this site are ink with an ink underline, and
     that is the reason: the next person to touch this file will reach for the green as a link
     colour, because every stylesheet they have ever read had one.

     THERE ARE TWO GREENS DECLARED IN THIS PROJECT AND THIS TOKEN PICKS ONE OF THEM.
     `draw_the_mark.mjs` declares `BRAND`, which is his green exactly, and `ON_LIGHT`, which is his
     green darkened until it clears 4.5:1 on this paper. The control refuses any third value and
     leaves the choice between the two open, because it is the founder's. THIS FILE CHOOSES `BRAND`,
     and the choice is not free:

       · WHAT IT BUYS. One green on the site, the same hex as the tab icon, and a `.launch` block
         that works, because a dark green fill under dark ink would be unreadable. Every green thing
         here is a fill or a mark, which is what the rule above allows.
       · WHAT IT COSTS. The letter in the masthead is drawn in it, at 1.21:1, so it reads as a pale
         shape rather than as a crisp mark. That is the one place on the page where the choice is
         visibly a trade, and it is written here so that whoever dislikes it knows it was seen.
       · AND SWAPPING TO `ON_LIGHT` IS ONE LINE HERE PLUS ONE DECISION ABOUT `.launch`, which would
         then need light text on it rather than ink. That is not a find and replace. */
  --green:      #3FFF90;

  --paper:      #F7F5F0;
  --paper-lift: #FFFFFF;
  --ink:        #141414;
  --ink-soft:   #57544C;
  --ink-faint:  #8B8779;
  --rule:       #E2DED3;
  --rule-firm:  #C9C4B6;

  /* THE THREE FACES, AND WHAT EACH IS FOR. Every one falls back to a system stack, so a page that
     cannot reach its own fonts is plain rather than broken.
       · SANS for everything a person reads.
       · MONO for labels, dates, navigation and the small print. It is what makes this read as a
         project's page rather than a product page.
       · DISPLAY for headings, which is where the founder asked for weight. */
  --sans:    "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica,
             Arial, sans-serif;
  --mono:    "DM Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
             "DejaVu Sans Mono", monospace;
  --display: "Nunito", "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
             Helvetica, Arial, sans-serif;

  /* The width of a line of prose, in characters rather than pixels: the one number that decides
     whether a page is comfortable. Everything else here is spacing around it. */
  --column: 34rem;

  /* The label rail, at desktop width. Below the breakpoint it does not exist. */
  --rail: 11rem;

  --step:  clamp(1rem, 0.95rem + 0.3vw, 1.0625rem);
  --gap-s: 0.6rem;
  --gap-m: 1.4rem;
  --gap-l: clamp(2.25rem, 6vw, 3.5rem);
  --gap-xl: clamp(3.5rem, 9vw, 6rem);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step);
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/* THE FIELD IS WIDE AND THE READING IS NARROW. The page pads generously on both sides at every
   size, so the text never runs to the edge of a phone; the column inside it stops at a readable
   width whatever the window does. */
.page {
  width: 100%;
  max-width: 64rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1.25rem, 5vw, 2.5rem) clamp(3rem, 8vw, 5rem);
}

p, li, dd, dt, blockquote { max-width: var(--column); }

/* --- the masthead and the bar -------------------------------------------------------------------
   THE TWO BARS ARE NO LONGER THE SAME MARKUP, AND THAT IS THE CHANGE TO KNOW ABOUT. The one at the
   top carries two links, into the two worlds, and nothing else: the top of a one-page site is for
   getting into a world, and a bar of five items there is a table of contents for a document the
   reader is already inside. The one at the FOOT carries the whole of this site, because a long page
   that ends in a copyright line dead ends and the reader has to go back up to move.

   BOTH WERE CHECKED AT PHONE WIDTH IN A REAL BROWSER rather than assumed. At 375 pixels the foot bar
   wraps onto three lines and the document is still exactly 375 wide. `flex-wrap: wrap` below does
   that on its own and needs no help.

   A `min-width: 0` WAS WRITTEN HERE FOR A BUG THAT DOES NOT EXIST, AND TAKING IT OUT AGAIN IS THE
   note worth keeping. The page appeared to scroll sideways in a headless screenshot at 380 pixels.
   It does not: that renderer will not make a window narrower than 500, so it laid the page out at
   500 and cropped the picture to the size it had been asked for. Everything past 380 was simply
   outside the crop. A cropped screenshot is not evidence about a width. */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--gap-m);
  padding-bottom: var(--gap-m);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--gap-l);
}

.mast {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  color: var(--ink);
}
/* THE MASTHEAD IS THE WHOLE WORDMARK NOW, AND IT USED TO BE THE LETTER PLUS SOME TYPE.
   Every page opened with the stepped A and then said the name in DM Mono beside it: one drawn
   letter and six typed ones, in a face that has nothing to do with the module the letter is built
   on. The founder read it as what it was. Every letter is drawn now, from `draw_the_mark.mjs`,
   including the stepped corners on the T and the L, and the control compares the whole element
   against what that file draws rather than the first path in it.

   THE HEIGHT IS THE ONLY NUMBER HERE, AND THE WIDTH FOLLOWS FROM THE viewBox. The drawing is
   482 x 96 including its own margin, so a 1.5rem tall word is about 7.5rem wide, which is the same
   room the letter and the typed name took between them.

   THE COLOUR IS INHERITED RATHER THAN WRITTEN INTO THE MARKUP. `fill` is an inherited SVG property,
   so the word takes the ink from the element and the A takes the green from the one class. Seven
   paths on four pages carrying a hex each would be twenty eight copies of a colour this site
   declares once. */
.mast-word { display: block; height: 1.5rem; width: auto; fill: var(--ink); }
.mast-word .mast-a { fill: var(--green); }

/* THE NAME IS STILL TYPED IN THE MARKUP AND IT IS NO LONGER DRAWN ON THE PAGE. A drawn word is a
   picture: unselectable, unextractable, unindexed, and silent to a screen reader. That trade was
   already called once, when the name stopped being a CSS custom property and became text, and
   letting a nicer masthead undo it in SVG would be the same mistake in a different medium. So the
   span stays, holding the name, out of the picture and in the document, and it is what a screen
   reader reads for this link because the drawing beside it is `aria-hidden`.

   `clip-path` RATHER THAN `display: none` OR A NEGATIVE INDENT. Anything that removes the element
   from layout removes it from the accessibility tree with it, which is the whole thing this rule is
   protecting. This is the one shape that keeps the text rendered, keeps it read, and draws nothing. */
.mast-name {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 1.5rem;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.bar a {
  color: var(--ink-soft);
  text-decoration: none;
  padding: 0.4rem 0;
  border-bottom: 1px solid transparent;
}
.bar a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* WHERE YOU ARE, MARKED WITH A DOT. `aria-current="page"` is the real signal and the dot is what a
   person sees. A solid green dot is the third sanctioned use of the green: nothing is read out of
   it. */
.bar a[aria-current="page"] { color: var(--ink); }
.bar a[aria-current="page"]::before {
  content: "";
  display: inline-block;
  width: 0.3rem;
  height: 0.3rem;
  border-radius: 50%;
  background: var(--green);
  margin-right: 0.45rem;
  vertical-align: 0.1em;
}

/* --- type --------------------------------------------------------------------------------------
   The hierarchy is carried by SIZE, SPACE AND FACE. The display face is where the weight lives; the
   body face stays at one weight, and the only bold inside a sentence is a word that has to be found
   in a hurry. */

/* THE GAP UNDER A HEADLINE IS ITS OWN NUMBER, AND IT IS NOT `--gap-m`. Every h1 on this site is
   followed immediately by the one line that explains it, and at `--gap-m` the two were a block of
   text rather than a statement with a note under it: the founder read the hero as dense and he is
   right. A headline set at three rems needs a gap you can see past, and it needs the same gap on a
   world's page, where the h1 is a world's name and the line under it is what that world is.

   IT IS A CLAMP RATHER THAN A CONSTANT because the headline itself is one: at 1.9rem on a phone a
   56 pixel gap would push the lede off the first screen, and at 3rem on a desktop 22 pixels is what
   he objected to. This tracks the type. */
h1 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.9rem, 1.15rem + 3vw, 3rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 clamp(1.9rem, 1.3rem + 2.2vw, 2.9rem);
  max-width: 20ch;
}

/* THE OPENING IS CENTRED IN THE PAGE, and the two world pages open the same way now. Ranged left
   inside a left hand column it read as two things pushed to one side rather than as one thing at
   the top of a page, which is what the founder said when he looked at it.

   THE CENTRING IS TWO MECHANISMS AND THIS NOTE USED TO NAME ONE OF THEM. `text-align: center` on
   the section is the line directly under this comment and it has been there all along; the auto
   margins on the heading and on the lede are the other half. Holding them apart matters, because
   they do different work and only one of them is safe everywhere. THE AUTO MARGINS CENTRE A BLOCK
   THAT ALREADY CARRIES A CAP OF ITS OWN, so the width of a line of prose still comes from
   `--column` and the heading still breaks where it wants to. `text-align` centres the LINES, which
   suits a headline and costs a reader something in a paragraph, because it moves the start of every
   line. A world's opening takes the margins for all three of its blocks and holds its description
   ranged left; the rule that does it is further down, with the reasoning. */
.opening { margin-bottom: var(--gap-xl); text-align: center; }
.opening h1 { max-width: 20ch; margin-left: auto; margin-right: auto; }
.opening .lede { margin-left: auto; margin-right: auto; }

.lede {
  font-size: clamp(1.05rem, 1rem + 0.45vw, 1.2rem);
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 0 0 var(--gap-m);
  max-width: 32rem;
}

h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.35rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 var(--gap-s);
}

h3 {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: var(--gap-m) 0 var(--gap-s);
}

p { margin: 0 0 1em; }

/* LINKS ARE INK WITH AN INK UNDERLINE. The green is not a link colour and the note beside the token
   says why at length: at 1.21:1 on this paper an underline in it is a smudge, and a person has to
   be able to see the thing that tells them a word is clickable. */
a {
  color: var(--ink);
  text-decoration-color: var(--rule-firm);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
a:hover { text-decoration-color: var(--ink); text-decoration-thickness: 2px; }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}

strong { font-weight: 500; }

/* --- a section, and the rail beside it -----------------------------------------------------------
   `.band` is the shape of every prose section on this site: a small typewriter label in a column of
   its own, and the reading beside it. Below the breakpoint the rail is not there and the label sits
   above the prose, which is the only sensible thing on a phone.

   THE BREAKPOINT IS SET IN `rem`, NOT `px`, so it moves with the reader's own text size: somebody
   reading at 24px gets the stacked layout at a window width where 16px would still have room for
   two columns, which is correct, because their column of prose is wider too. */
section { margin: 0 0 var(--gap-xl); }

/* NO ROW GAP, ON PURPOSE. Stacked on a phone the spacing between a label and what it labels is the
   label's own bottom margin, in one place; a grid row gap on top of it would be the same distance
   declared twice and adjusted in one. Only the COLUMN gap is set, and only where there is a second
   column. */
.band { display: grid; }
.band > * { min-width: 0; }

@media (min-width: 58rem) {
  .band { grid-template-columns: var(--rail) minmax(0, 1fr); column-gap: var(--gap-l); }
  /* `align-self: start` IS LOAD-BEARING AND IT IS THE KIND OF BUG THAT LOOKS LIKE A DESIGN CHOICE. A
     grid item stretches to the height of its row by default, so the label box became as tall as the
     whole section and its own `align-items: center` then parked the word in the vertical middle of
     it. The label belongs at the top of what it labels. */
  .band > .label { margin-bottom: 0; align-self: start; }
}

/* A SECTION LABEL, IN THE TYPEWRITER FACE, WITH A SHORT GREEN RULE UNDER IT and a small drawn mark
   beside it. The rule is the second sanctioned use of the green: it is a rule, and nothing is read
   out of it. */
.label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 var(--gap-m);
  max-width: none;
}
.label::after {
  content: "";
  flex: 0 0 auto;
  width: 1.4rem;
  height: 2px;
  background: var(--green);
}
@media (min-width: 58rem) {
  .label { position: sticky; top: var(--gap-m); }
}

/* THE LABEL'S OWN GLYPH. One tier, one size, one colour, one stroke weight, one per section and
   never two. It is there so that a reader scanning the rail can tell the sections apart without
   reading them, which is the only job a glyph at this size can actually do. */
.label .glyph { flex: 0 0 auto; width: 0.95rem; height: 0.95rem; color: var(--ink-faint); }

.rule { border: 0; border-top: 1px solid var(--rule); margin: var(--gap-l) 0; }

/* --- the worlds ----------------------------------------------------------------------------------
   TWO ABREAST, AND THEY STACK ONLY ON A PHONE. Stacked they read as two blog posts; side by side
   they read as two things to choose between, which is what they are. This section does NOT use the
   rail: it is the widest thing on the page and its label sits above it.

   A THIRD WORLD IS A THIRD <li> COPIED FROM EITHER OF THESE, with its own capsule. `auto-fit` means
   nothing here counts them: two fill the row, three wrap to a second row, and no sentence anywhere
   says how many there are. */

.worlds {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* `min(19rem, 100%)` RATHER THAN `19rem`, AND THE 100% IS LOAD BEARING ON A SMALL PHONE.
     A bare `minmax(19rem, …)` track is never allowed to be narrower than 19rem, which is 304
     pixels, and the field inside this page's padding is 280 at a 320 pixel viewport. The track
     stayed 304, the two cards ran 4 pixels past the edge, and THE WHOLE FRONT PAGE SCROLLED
     SIDEWAYS on any phone 344 pixels or narrower. It was found by reading `scrollWidth` against
     `clientWidth` on all four pages at 320, 375, 414, 768 and 1280, which is the check to repeat:
     a sideways scroll is invisible in a screenshot, and `DEPLOYING.md` already carries a note about
     believing a cropped screenshot on this exact question. `min()` lets the track fall to the
     width there actually is. Nothing at 375 or above moves by a pixel.

     AND THE OTHER WORD FOR READING TWO NUMBERS OFF A DOCUMENT IS REFUSED ON THIS SITE, which is how
     this comment came to be written twice. The wordlist bans it outright, in copy and in comments,
     because the founder's rule is that nothing here says anything about anybody is weighed in that
     way, and a rule with a carve-out for the places we happened to want it would not be that rule.
     This stylesheet has now cost the same word three times. */
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
  gap: var(--gap-l) var(--gap-l);
}
.world { max-width: none; display: flex; flex-direction: column; }

/* A WORLD IS SHOWN BEFORE IT IS DESCRIBED. The capsule is a real frame from the world itself, and
   the whole capsule is a link into it. */
.capsule {
  display: block;
  border-radius: 10px;
  overflow: hidden;
  background: var(--rule);
  border: 1px solid var(--rule-firm);
  text-decoration: none;
  aspect-ratio: 16 / 9;
}
.capsule img,
.capsule video { display: block; width: 100%; height: 100%; object-fit: cover; }
.capsule:hover { border-color: var(--ink); }

/* THE CLIP INSIDE A CAPSULE. It is a few seconds of the world being played, silent, looping, and
   playing on its own, with the still that used to sit here as its poster so nothing is blank while
   it loads. `background` matters: while the poster is still arriving the box is the same paper as
   everything else rather than the black a video element paints by default.

   REDUCED MOTION IS HANDLED IN THE MARKUP AND NOT HERE, AND THAT IS WORTH KNOWING BEFORE SOMEBODY
   ADDS A RULE FOR IT. There is no CSS that pauses a video. A rule under `prefers-reduced-motion`
   could hide the moving thing, and the file would still be fetched and the video would still be
   playing behind the rule. `<source media="(prefers-reduced-motion: no-preference)">` makes the
   browser select no source at all: the poster stays, nothing plays, and nothing is asked for. */
.capsule video { background: var(--rule); }

.world h2 { margin: var(--gap-m) 0 var(--gap-s); }

/* The two lines. They do the only job the front page has after the picture: say what you do in this
   world. `flex: 1` on the description pushes the way in to the bottom of both cards, so the two
   launch blocks line up whatever length the copy is. */
.world .says { color: var(--ink-soft); margin: 0 0 var(--gap-m); max-width: none; flex: 1 1 auto; }

/* --- the way in ----------------------------------------------------------------------------------
   ==================================================================================================
   THE MOST IMPORTANT CONTROL ON THE SITE, AND IT IS NOW DRAWN IN OUTLINE
   ==================================================================================================

   IT WAS A SOLID BLOCK OF THE COMPANY'S GREEN, THE FULL WIDTH OF ITS CARD, and the founder's verdict
   was that the block is far too loud. So it is the same control at its natural size, centred under
   the card it belongs to, with a rule around the words instead of a field of colour behind them.

   THE GREEN ARRIVES ON HOVER AND ON FOCUS. That is the same sanctioned use as before, ink on the
   brand green at 13.96 : 1, and it is better contrast than the body text on this page. At rest the
   control is ink on paper. What changed is which state carries the colour.

   `:focus-visible` GETS THE FILL AS WELL AS THE RING, AND THAT IS DELIBERATE. A keyboard reader
   should see the same thing a mouse reader sees, and an outline control whose only focus signal is
   an outline is a control whose focus signal looks like its resting state.

   IT IS STILL AN <a> WITH A REAL href, AND THAT IS NOT NEGOTIABLE: there is no script on this site,
   the policy in `_headers` carries `script-src 'none'`, and a control that needed one would be a
   control that does nothing. Everything below is paint on a link. */
.launch {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: -0.005em;
  padding: 0.6rem 1.1rem;
  border-radius: 8px;
  border: 1px solid var(--ink);
  line-height: 1.2;
}
.launch-text { flex: 0 1 auto; }
/* THE PLAY MARK. Solid, larger than every other glyph on the site, and the only one that is filled
   rather than drawn in outline. That is the hierarchy: one glyph says GO and the rest say WHERE. */
.launch .launch-mark { flex: 0 0 auto; width: 1.15rem; height: 1.15rem; fill: currentColor; stroke: none; }
.launch .launch-go   { flex: 0 0 auto; width: 1rem; height: 1rem; }
.launch:hover,
.launch:focus-visible { background: var(--green); color: var(--ink); border-color: var(--ink); }

/* The quiet second route out of a card. It is a link and it is meant to look like one.
   INSIDE A WORLD CARD THE TWO STACK AND BOTH ARE CENTRED, which is what "centred in its own column"
   actually means: a row of two centres the PAIR, and the control itself then sits off to one side of
   the card it belongs to. Stacked, the control is on the axis of the picture above it and the quiet
   link sits under it. Everywhere else the row stays a row. */
.world .actions { flex-direction: column; gap: 0.9rem; }
.actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
           gap: 0.7rem 1.2rem; margin: var(--gap-m) 0 0; max-width: none; }
.quiet { color: var(--ink-soft); font-size: 0.9rem; }
a.quiet { text-decoration-color: var(--rule-firm); }
a.quiet .glyph { width: 0.85em; height: 0.85em; }

/* On a world's own page and on the 404 the way in is one control under the opening rather than one
   per card, and there it sits where the prose starts rather than in the middle of the column. The
   class is on the control itself, so the row it lives in is selected through it. */
.way-in { margin: 0 0 var(--gap-l); }
.actions:has(> .way-in) { justify-content: flex-start; }

/* A world's page opens with the capsule and then names itself. The heading has no top margin of its
   own, by design, so the gap is put here rather than on every h1 on the site.

   AND THE GAP BETWEEN THE PICTURE AND THE NAME IS `--gap-l` RATHER THAN `--gap-m`, WHICH IS THE
   SAME CORRECTION AS THE ONE UNDER A HEADLINE AND FOR THE SAME REASON. A world's name sitting a
   thumb's width under a moving picture reads as that picture's caption. It is the title of the
   page, so it is given the room a title has. */
/* AND THE CAPSULE THAT OPENS A WORLD'S PAGE IS CAPPED AT THE WIDTH OF ITS OWN CLIP.
   ==================================================================================================
   THE PICTURE IS NEVER DRAWN LARGER THAN IT WAS CAPTURED, AND THAT IS THE WHOLE RULE.

   These two pages used to open with the capsule at the full width of the field, about 950 pixels,
   with a 512 pixel clip inside it. The founder read that as poor quality and it is: the poster is
   1440 wide and crisp, so the drop is visible at the instant the clip starts. `DEPLOYING.md` §19
   left it open with three ways out and §21 records which one was taken and what the others cost.

   32rem IS 512 PIXELS AND IT IS THE CLIP'S OWN WIDTH. It is also a number this stylesheet already
   speaks: `.lede`, `.plain` and `.join` all stop at 32rem. So the opening picture now sits in the
   same column as the writing under it, which reads as a decision rather than as a smaller picture.
   On a phone it is unchanged, because a phone was always narrower than this.

   THE POSTER IS UNAFFECTED AND GETS BETTER: 1440 pixels drawn into 512 is far under its own size,
   so the still a reduced-motion reader sees is sharper here than it was. */

/* ==================================================================================================
   AND THE WHOLE OPENING IS CENTRED IN THE FIELD, THE WAY THE FRONT PAGE'S HERO IS CENTRED
   ==================================================================================================

   THIS RULE USED TO SAY THE REVERSE, AND THE CHANGE IS THE FOUNDER'S. The case for holding a
   world's opening against the left was that a centred heading under a picture the full width of the
   field reads as that picture's caption. The picture stopped being the full width of the field the
   day the capsule was capped at 32rem, and the case went with it. What was left was a 512 pixel
   column of picture and prose against the left edge of a 64rem page, with the front page centred,
   and he read the two as different sites.

   IT IS DONE THE WAY THE HERO ABOVE IS DONE: auto margins on blocks that already carry a cap of
   their own. The capsule keeps its 32rem, the lede keeps its 32rem, the heading keeps its 20ch, and
   the centring is a margin on each of them. Every width on this page is the width it already was.

   THE SENTENCES INSIDE THE DESCRIPTION STAY RANGED LEFT, AND THAT IS THE HALF WORTH KEEPING.
   Centring a block is a layout decision. Centring the lines inside it moves the start of every
   line, so a reader hunts for the beginning of each one in a new place, and this site is read by
   people for whom that costs more than usual. THE HEADING IS CENTRED, because a world's name is one
   or two words: ranged left inside a 20ch box it sits visibly off the axis of the picture over it,
   and a heading has no line for anybody to lose. So the column is centred, the picture and the
   prose share its left edge, and the name sits on the middle of it.

   THE WAY IN TRAVELS WITH THEM AND KEEPS THE PLACE IT WAS GIVEN. `.actions` runs the full width of
   the field, and the rule above ranges this one at the start of the row, which used to put the
   control on the left edge of the page. It gets the same 32rem column as everything else in this
   opening, so it still sits where the prose starts, and the prose has moved. */
.capsule + .opening { margin-top: var(--gap-l); }
.masthead + .capsule { max-width: 32rem; margin-left: auto; margin-right: auto; }
.capsule + .opening .lede { text-align: left; }
.capsule + .opening .actions { max-width: 32rem; margin-left: auto; margin-right: auto; }

/* --- the small drawn glyphs ----------------------------------------------------------------------
   EVERY MARK ON THIS SITE IS INLINE SVG DRAWN IN THE MARKUP IN `currentColor`. No icon font, no
   sprite, no file: there is nothing to fetch and nothing to keep in step.

   AND THERE ARE THREE TIERS, WHICH IS THE WHOLE OF WHY THEY HELP RATHER THAN CLUTTER. A page with
   fourteen glyphs of equal weight is a worse page than one with none.

     1 · `.launch-mark` — one per way in. Solid, 1.5rem, and it is the only filled glyph.
     2 · `.label .glyph` — one per section, in the rail. Drawn, 0.95rem, `--ink-faint`.
     3 · list glyphs inside `.route` and `.note` — one per step. Drawn, `--ink`, and they exist
         because two install routes can then be read at a glance instead of read as a paragraph. */
.glyph { display: inline-block; width: 1.05em; height: 1.05em; vertical-align: -0.16em; fill: none;
         stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.glyph-solid { fill: currentColor; stroke: none; }

/* --- putting it on a phone -----------------------------------------------------------------------
   BOTH ROUTES ARE VISIBLE AT ONCE AND NOBODY IS ASKED TO CHOOSE FROM A MENU. Two short rows, three
   glyphs each, six words each. A person who already knows how to do this scrolls past it; a person
   who does not can follow it without reading a paragraph first. It sits BELOW the way in, because
   reading this is not a precondition for playing. */
.install { display: flex; flex-wrap: wrap; gap: var(--gap-m) 2.5rem; margin: var(--gap-m) 0 0; }
.route { flex: 1 1 15rem; min-width: 0; }
.route-name { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.13em;
              text-transform: uppercase; color: var(--ink-faint); margin: 0 0 0.7rem; }
.route ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.route li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.92rem; color: var(--ink-soft); max-width: none; }
.route li .glyph { flex: 0 0 auto; width: 1.2rem; height: 1.2rem; color: var(--ink); }
.install + .quiet, .install + .note { margin-top: var(--gap-m); }

/* --- a note --------------------------------------------------------------------------------------
   A green rule down the left, which is the same sanctioned use as the mark under a label. */
.note {
  border-left: 3px solid var(--green);
  padding-left: 1rem;
  color: var(--ink-soft);
  font-size: 0.92rem;
  max-width: var(--column);
  margin: var(--gap-m) 0 0;
}
.note p { margin-bottom: 0.6em; }
.note p:last-child { margin-bottom: 0; }

/* --- the questions -------------------------------------------------------------------------------
   ==================================================================================================
   SEVEN QUESTIONS, COLLAPSED, AND NOT ONE LINE OF SCRIPT
   ==================================================================================================

   Expanded, seven questions are a wall of text that pushes everything under them off the page.
   Collapsed, they are seven lines and a reader can see the whole shape of what gets asked. So they
   fold, and `<details>` and `<summary>` do it with nothing else: no script, no checkbox pretending
   to be one, and it still opens for a reader whose browser never runs a script, because the policy
   in `_headers` carries `script-src 'none'` and would refuse one anyway.

   ONE OPEN AT A TIME, ALSO WITH NO SCRIPT. Every `<details>` here carries the same `name`, which is
   what makes a browser treat them as one exclusive group and close the open one when another is
   opened. In a browser too old for it, all seven simply open independently, which is the behaviour
   this page had before and is a shabby moment rather than a broken one. That is the right way round
   and it is why the attribute was worth using rather than contorting for.

   EVERY ANSWER IS IN THE MARKUP WHETHER THE FOLD IS OPEN OR SHUT, so a text extractor, a search
   engine and a reader with no script all get the whole page. */
.qa { border-top: 1px solid var(--rule); }
.q { border-bottom: 1px solid var(--rule); }

.q > summary {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  cursor: pointer;
  list-style: none;
  padding: 0.95rem 0;
  font-weight: 500;
  color: var(--ink);
}
.q > summary::-webkit-details-marker { display: none; }
.q > summary:hover { color: var(--ink); }
.q > summary:hover .q-mark { border-color: var(--ink); }

/* THE MARKER IS DRAWN IN CSS RATHER THAN TYPED, so no plus sign and no minus sign has to live in
   the markup of every question. A minus sign typed into ten summaries would be ten characters a
   dash check has to know the difference between. */
.q-mark {
  flex: 0 0 auto;
  position: relative;
  width: 1.05rem;
  height: 1.05rem;
  border: 1px solid var(--rule-firm);
  border-radius: 3px;
  align-self: center;
}
.q-mark::before, .q-mark::after {
  content: "";
  position: absolute;
  background: currentColor;
  top: 50%;
  left: 50%;
}
.q-mark::before { width: 0.45rem; height: 1px; transform: translate(-50%, -50%); }
.q-mark::after  { width: 1px; height: 0.45rem; transform: translate(-50%, -50%); }
.q[open] > summary .q-mark::after { height: 0; }

.q-text { flex: 1 1 auto; }
.q .a { padding: 0 0 1.15rem 1.9rem; color: var(--ink-soft); max-width: none; }
.q .a p { margin: 0 0 0.7em; }
.q .a p:last-child { margin-bottom: 0; }

/* --- the log ---------------------------------------------------------------------------------------
   Dated entries, newest first, in the manner of a project's news list. THERE IS ONE PER WORLD AND IT
   LIVES ON THAT WORLD'S OWN PAGE. A single mixed log had to name the world on every line, and a
   reader who came for one world read half a list about the other.

   Five are open and the rest are behind a `<details>`, which opens with no script at all: the whole
   log is in the markup either way. The date sits on one small typewriter line above the entry, so
   the shape is the same on a phone as on a desk and no column has to collapse. */
.log { list-style: none; margin: 0; padding: 0; }
.log li {
  padding: 1.1rem 0;
  border-top: 1px solid var(--rule);
  max-width: none;
}
.log li:last-child { border-bottom: 1px solid var(--rule); }
.log .when {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.35rem;
  max-width: none;
}
/* A SOLID GREEN DOT BEFORE THE DATE. Third sanctioned use: a bullet, and nothing is read out of it.
   It is drawn rather than typed so that no separator character has to live in every entry. */
.log .when::before {
  content: "";
  flex: 0 0 auto;
  width: 0.3rem;
  height: 0.3rem;
  border-radius: 50%;
  background: var(--green);
}
.log .what { color: var(--ink-soft); max-width: var(--column); }

/* THE FOLD. `details` with no script, and the marker is replaced by a drawn one so the control reads
   as a quiet button rather than as a browser default.

   WHILE THE FOLD IS EMPTY IT HIDES ITSELF. No script, no second class to remember to remove: move an
   entry into the list and the control appears. `:empty` counts whitespace, which is why the list in
   the markup has nothing between its tags. A browser without `:has` shows a fold that opens onto
   nothing, which is shabby rather than broken. */
.log-more:has(> .log:empty) { display: none; }
.log-more { margin-top: var(--gap-m); }
.log-more > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0.5rem 0.85rem 0.5rem 0.7rem;
  border: 1px solid var(--rule-firm);
  border-radius: 6px;
}
.log-more > summary::-webkit-details-marker { display: none; }
.log-more > summary::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.15em) rotate(45deg);
}
.log-more[open] > summary::after { transform: translateY(0.1em) rotate(225deg); }
.log-more > summary:hover { border-color: var(--ink); color: var(--ink); }
.log-more[open] > summary { margin-bottom: var(--gap-m); }

/* --- telling us ------------------------------------------------------------------------------------
   THE SPACE FOR THIS IS DESIGNED HERE AND IT SITS UNDER A WORLD. Today it holds one address and
   nothing else. What it is BUILT to hold, a place where a person can leave what they thought where
   other people can read it, is the first thing on this site that would keep anything about anybody,
   which is a different kind of job with a legal shape, and it is deliberately not built. The rules
   below are the room it will go in: `.say-space` is styled and unused, and the markup that would
   fill it is described in a comment on each world's page.

   IT IS PER WORLD BY CONSTRUCTION. Every rule here is scoped to a section that lives on a world's
   page, so one world can have this and the other need not. */
.say .channel {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: var(--gap-m);
}
.say .what { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.13em;
             text-transform: uppercase; color: var(--ink-faint); }

.say-space {
  margin-top: var(--gap-l);
  border: 1px dashed var(--rule-firm);
  border-radius: 10px;
  padding: var(--gap-m);
  background: var(--paper-lift);
}
.say-space .entry {
  border-bottom: 1px solid var(--rule);
  padding-bottom: var(--gap-m);
  margin-bottom: var(--gap-m);
}
.say-space .entry:last-child { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }
.say-space .who { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.08em;
                  text-transform: uppercase; color: var(--ink-faint); }
.say-space .tally { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-faint); }

/* --- who we are, as three points with a mark each ------------------------------------------------
   THE DRAFT THAT USED TO LIVE HERE IS GONE. `.proposal` was a dashed box holding four paragraphs and
   three open questions written by a lane and flagged on the page as a draft for the founder to write
   over. He deleted it rather than writing over it, so the rules that drew it went with it, along
   with the NOTE the control printed on every run while the class was still in the published set.

   WHAT IS THERE INSTEAD IS THREE POINTS IN AN ORDER THAT IS AN ARGUMENT: who we are, what we think a
   world can be, and why the subject is worth the attention. Each carries ONE drawn mark, at the size
   and weight the marks in a world's install routes use, which is the third tier described above:
   one per line, ink, outline, never two. */
.points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--gap-m); }
.points li { display: flex; gap: 0.85rem; max-width: none; }
.points li > .glyph { flex: 0 0 auto; width: 1.2rem; height: 1.2rem; color: var(--ink); margin-top: 0.2em; }
.points .point { margin: 0; }

/* --- the two sections the founder rewrote ------------------------------------------------------------
   A POINT IS A LEAD AND A SENTENCE, AND THE LEAD IS A <strong> RATHER THAN A HEADING. Seven points
   across two sections would be seven more entries in the outline of a page that already has seven
   sections, for one line of copy each. What a heading would have bought is weight, and weight is
   what `font-weight: 500` in the reading face already gives. `.point` is the paragraph; the lead is
   the bold run at the front of it.

   THEY ARE SPACED FURTHER APART THAN ORDINARY PARAGRAPHS. Each point is a separate claim rather than
   a step in an argument, and run at paragraph spacing they read as one long paragraph with bold bits
   in it. */
.point { margin: 0 0 var(--gap-m); max-width: var(--column); }
/* The one line under a section's own heading, where that heading is a statement rather than a
   label. `Take part` is the only section built that way, and it borrows `.lede` from the opening
   for it: same job, one step down the page. */
.band .lede { margin-bottom: var(--gap-l); }
.point:last-child { margin-bottom: 0; }
.point strong { font-weight: 500; color: var(--ink); }

/* --- THE SPACE WHERE AN EMAIL ADDRESS WILL GO, AND EVERY RULE HERE DRAWS A ROOM RATHER THAN A FIELD
   ------------------------------------------------------------------------------------------------
   THERE IS NO FORM ON THIS SITE AND THIS IS NOT ONE. An address is the first thing this site would
   keep about a person, which brings a lawful basis, a retention period and a route to deletion with
   it, and that is a decision the founder has not made. A field that posts nowhere is worse than no
   field, because somebody types an address into it and the site has taken something and lost it.

   SO THE SLOT IS DRAWN AS A DRAWING. It is dashed, like `.say-space` on a world's page, because a
   dashed edge is how this site says *a working state* everywhere else it says it. It carries no
   focus ring, no hover, no caret and no pointer, and nothing in it responds to a click, so nothing
   about it invites one. The markup carries `aria-hidden` on the slot for the same reason: a screen
   reader announcing a text field that is not there is the cruellest version of this mistake.

   AND AN ASSERTION IN THE CONTROL REFUSES A FIELD ANYWHERE IN THE PUBLISHED SET, with a planted
   fault against this block. The posting tag was already refused as an embedding tag; a field on its
   own was not, and a field on its own is the likelier fault: the box gets drawn, the wiring is left
   for later, and later never has a date. */
.join {
  margin-top: var(--gap-l);
  border: 1px dashed var(--rule-firm);
  border-radius: 10px;
  padding: var(--gap-m);
  background: var(--paper-lift);
  max-width: 32rem;
}
/* THE INVITATION, AT BODY SIZE, ABOVE EVERYTHING ELSE IN THE BOX. It is a sentence rather than a
   label, so it is not the mono flag it sits above. */
.join-invite { margin: 0 0 var(--gap-m); max-width: none; }

/* --- THE TWO PROMISES, NUMBERED ------------------------------------------------------------------
   THEY ARE THE ENTIRE REASON SOMEBODY LEAVES AN ADDRESS, and run together as prose they are a
   clause and a half in the middle of a paragraph. That much was already agreed and the first fix
   went half way: each line got a two pixel rule over it and nothing else. THE FOUNDER READ THAT AS
   A TABLE THAT HAD LOST ITS EDGES and he is right. A rule with a line under it, repeated, is the
   shape of rows of data, and the reader is left to work out that the rules are the point.

   SO THEY ARE NUMBERED, WHICH IS WHAT HE ASKED FOR, and the numbering does the counting the two
   rules were being asked to do. One two pixel rule across the top of the pair rather than one over
   each, a hairline between them, and each line led by its own figure in the mono face. The block
   reads as one considered thing containing two, which is what it is.

   THE FIGURES ARE TYPED IN THE MARKUP AND NOT DRAWN BY A COUNTER HERE. Same ruling as the site's
   own name: text drawn by CSS is absent from the document, and the DASHES scan reads `content:`
   strings precisely because they paint onto the page. A number that is part of the copy belongs in
   the copy.

   THEY STACK, AND THAT IS NOW THE ONLY THING THEY DO. The box around them is 32rem at its widest
   and the longer line draws 230 pixels, so a two-column version of this put a break before the last
   word of the second promise, orphaning the one word both lines are built on. Rows have no such
   failure and they let the numbers form a column.

   AND TWO IS THE POINT RATHER THAN THE CURRENT NUMBER. A third entry turns a pair into a list of
   things somebody is being offered. Anything else that has to be promised is a point in the body
   above this box, where the points live. */
.promises {
  list-style: none;
  margin: 0 0 var(--gap-l);
  padding: 0;
  border-top: 2px solid var(--ink);
}
.promise {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  max-width: none;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
.promise:last-child { border-bottom: 0; padding-bottom: 0; }
/* The figure. A fixed floor under its width so both lines start at the same place, which is the
   difference between a numbered pair and two lines that happen to have digits in front of them. */
.promise-n {
  flex: 0 0 auto;
  min-width: 1rem;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  color: var(--ink-faint);
}
.promise-line {
  margin: 0;
  max-width: none;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* THE MONO FLAG OVER THE SLOT IS GONE, AND ITS RULE WITH IT. It read `A SPACE HELD FOR AN EMAIL
   FIELD` and the founder cut it: the field should read as a field. A label announcing that a
   drawing is a drawing is a page explaining itself, and the slot, its placeholder and the line
   under it already say the whole of what that box is. */
/* The slot. A line of the reading face, at the height a field would be, inside a dashed edge that
   is one shade lighter than the box around it, so it reads as a space rather than as a control. */
.join-slot {
  margin: 0 0 var(--gap-m);
  border: 1px dashed var(--rule);
  border-radius: 8px;
  padding: 0.75rem 0.9rem;
  background: var(--paper);
  color: var(--ink-faint);
  max-width: none;
}
.join-slot span { font-size: 0.95rem; }

/* HIS WORDS, BESIDE THE FIELD, PLAINLY. It sits directly under the slot with almost no air between
   them, because the thing it is about is the slot. No full stop: it is a label on a control rather
   than a sentence in the prose, and it is the one line in this box that will still be true and still
   be needed on the day the field is real.

   IT IS THE LAST LINE IN THE BOX NOW. A paragraph used to follow it explaining lawful basis,
   retention and deletion. That is an engineering note and the founder cut it; the reasoning lives in
   the comment above the block in `index.html`, where reasoning belongs. */
.join-quiet {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-faint);
  max-width: none;
}

/* --- what funds this -------------------------------------------------------------------------------
   THE LOCKUP IS A PICTURE OF A LEGAL REQUIREMENT AND IT IS SIZED SO THAT IT CAN BE READ. It is very
   wide, 6.5 : 1, and the small line under each emblem is the part the rules are about, so it is
   given the full width of the reading column and a floor under which it does not shrink. Below that
   floor it scrolls inside its own box rather than becoming a picture of unreadable text.

   THE FILE IS SERVED AT TWICE THE SIZE IT DRAWS AT, so it is sharp on a phone, and it is the
   company's own file downscaled rather than anything redrawn here. */
/* IT IS SHOWN WHOLE AT EVERY WIDTH, AND THAT WAS A CHOICE BETWEEN TWO IMPERFECT THINGS. The lockup
   is 6.5 : 1, so on a phone it is a 50 pixel strip and the small line under each emblem is small.
   The alternative was a floor under its width and a box that scrolls sideways, which keeps that line
   readable and puts the European Union's own emblem, the rightmost of the three, past the edge of a
   phone unless somebody thinks to drag it. AN EMBLEM NOBODY SCROLLS TO IS WORSE THAN A SMALL ONE,
   so all three are always in view, as large as the reading column allows.

   AND THE WORDING IS SET AS REAL TEXT UNDER IT rather than left inside the picture. That is the half
   of the requirement a reader actually reads, it is the same size as the rest of the prose at every
   width, it is selectable, and it is what the alt text repeats for somebody who gets no picture. */
.funding-mark {
  display: block;
  width: 100%;
  max-width: 34rem;
  height: auto;
  margin: 0 0 var(--gap-m);
}
/* FIVE LINES, IN TWO VOICES, AND THE SPLIT IS NOT A DESIGN OPINION. Two of them are sentences and
   three of them are references: a project number, two figures with a pipe between them, and a pair
   of dates. The mono face is what this site already uses for a date, a reference and the small
   print, and it is what stops somebody reading `FEPW.01.01-IP.01-0208/25` as prose.

   THERE IS NO `:last-child` RULE HERE ANY MORE AND THAT IS DELIBERATE. It used to set the last line
   in mono because the last line happened to be the money. The block gained two lines and the last
   one became the dates, so a rule keyed on POSITION would have quietly restyled a different line.
   Each line now says what it is. */
.funding-lead { color: var(--ink); font-size: 0.92rem; margin: 0 0 0.4em; }
.funding-line { color: var(--ink-soft); font-size: 0.92rem; margin: 0 0 0.4em; }
.funding-ref {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: 0 0 0.4em;
}
.funding-ref:last-child { margin-bottom: 0; }

/* --- contact ------------------------------------------------------------------------------------- */
.plain { font-size: 1.15rem; line-height: 1.5; max-width: 32rem; }

/* --- the foot ----------------------------------------------------------------------------------------
   THE BAR AGAIN, IDENTICAL, AND THEN THE SMALL PRINT. A page that ends without a way onward makes the
   reader scroll all the way back up, which is the one thing a long front page must avoid. */
footer {
  border-top: 1px solid var(--rule);
  margin-top: var(--gap-xl);
  padding-top: var(--gap-m);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
}
footer .bar { margin-bottom: var(--gap-m); }
footer p { margin: 0 0 0.5em; max-width: none; }
footer p:last-child { margin-bottom: 0; }
footer a { color: var(--ink-soft); }

/* THE COLOPHON'S RULE WENT WITH THE COLOPHON. The founder cut the line naming the three faces and
   the licence they are under. The licence files still ship beside the type, which is the half the
   SIL Open Font License actually asks for; the footer of every page carries the note saying so. */

/* --- reduced motion --------------------------------------------------------------------------------
   THE ONE THING ON THIS SITE THAT MOVES IS A CAPSULE, AND IT IS NOT SWITCHED OFF HERE. There is no
   CSS that pauses a video: a rule under this query could hide the moving thing while it went on
   playing behind the rule and the file went on being fetched. The clips carry
   `<source media="(prefers-reduced-motion: no-preference)">` instead, which makes the browser select
   no source at all, keep the poster on screen, and ask for nothing.

   THIS RULE STAYS FOR EVERYTHING ELSE. Nothing here animates or transitions today, and the day
   something does it is already covered. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
