/* ============================================================================
   explorist.io — house stylesheet
   Tokens copied from brand/visual/brand-sheet.html (Color.md, settled 2026-09-04).
   Type per brand/visual/Typography.md. Layout per brand/visual/Layout.md.
   Plain CSS: no framework, no build step, no CDN. Edit this file directly.
   ========================================================================== */

/* ---------- 1. Faces (self-hosted, Typography.md §4) -----------------------
   Variable TTFs from github.com/google/fonts, converted to woff2 with fontTools.
   The full faces are kept, not the Google CSS API build, because that build
   strips the OpenType features (onum, lnum, smcp, frac) the style rules need.  */

@font-face {
  font-family: "EB Garamond";
  src: url("fonts/eb-garamond-var.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/eb-garamond-italic-var.woff2") format("woff2");
  font-weight: 400 800;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Goudy Bookletter 1911";
  src: url("fonts/goudy-bookletter-1911.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IM Fell Great Primer SC";
  src: url("fonts/im-fell-great-primer-sc.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("fonts/ibm-plex-sans-var.woff2") format("woff2");
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- 2. Tokens -------------------------------------------------------
   Day and night hold one value each, paired by light-dark(). Which half the
   page reads is decided by color-scheme: the default follows the system, and
   the toggle writes data-mode on <html> to override it. One block, so the two
   modes cannot drift apart. No pure white, no pure black (Color.md rule 3).    */

:root {
  color-scheme: light dark; /* no choice made: follow the system, live */

  /* palette — light-dark(day, night) */
  --blue: light-dark(#20388f, #284a7c);
  --blue-deep: light-dark(#142668, #0e1c36);
  --tone: light-dark(#8f9bd0, #7d98c2);
  --tint: light-dark(#e3e4ee, #284a7c);
  --ink: light-dark(#2d2b29, #e8e1d2);
  --paper: light-dark(#f4eedc, #142848);
  --raised: light-dark(#faf6ea, #1b335c);
  --actor: light-dark(#d27f22, #e08a3a);
  --actor-deep: light-dark(#b0661a, #c9752c);
  --on-actor: #faf6ec;
  --display: light-dark(#20388f, #e8e1d2); /* blue by day, paper text by night */
  --link: light-dark(#b0661a, #e08a3a);

  /* the frame: one shade lighter than text ink by day, tone blue by night
     (decisions 19 and 20) */
  --frame: light-dark(#6a655e, #7d98c2);
  --hatch-1: light-dark(rgba(45, 43, 41, 0.16), rgba(125, 152, 194, 0.3));
  --hatch-2: light-dark(rgba(45, 43, 41, 0.09), rgba(125, 152, 194, 0.16));

  /* faces */
  --fell: "IM Fell Great Primer SC", serif;
  --goudy: "Goudy Bookletter 1911", serif;
  --garamond: "EB Garamond", Garamond, Georgia, serif;
  --plex: "IBM Plex Sans", system-ui, sans-serif;
}

/* A chosen mode spells its half out. light-dark() alone would do, but a change
   of color-scheme does not start a CSS transition in every browser, and the
   switch (section 10) glides on transitions. The values are the same as above,
   copied by hand: keep the three lists together. */
:root[data-mode="day"] {
  color-scheme: light;
  --blue: #20388f;
  --blue-deep: #142668;
  --tone: #8f9bd0;
  --tint: #e3e4ee;
  --ink: #2d2b29;
  --paper: #f4eedc;
  --raised: #faf6ea;
  --actor: #d27f22;
  --actor-deep: #b0661a;
  --display: #20388f;
  --link: #b0661a;
  --frame: #6a655e;
}
:root[data-mode="night"] {
  color-scheme: dark;
  --blue: #284a7c;
  --blue-deep: #0e1c36;
  --tone: #7d98c2;
  --tint: #284a7c;
  --ink: #e8e1d2;
  --paper: #142848;
  --raised: #1b335c;
  --actor: #e08a3a;
  --actor-deep: #c9752c;
  --display: #e8e1d2;
  --link: #e08a3a;
  --frame: #7d98c2;
}

/* Non-color tokens cannot ride light-dark(), so they carry a mode block each.
   Keep this list short; anything that is a color belongs above. */
:root { --grain-blend: multiply; --grain-opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="day"]) {
    --grain-blend: screen; --grain-opacity: 0.5;
  }
}
:root[data-mode="night"] {
  --grain-blend: screen; --grain-opacity: 0.5;
}

/* ---------- 3. Base --------------------------------------------------------- */

* { box-sizing: border-box; margin: 0; padding: 0; }

html { background: var(--paper); }

body {
  background: var(--paper);
  color: var(--ink);
  font: 17px/1.55 var(--garamond);
  font-feature-settings: "onum", "liga", "kern"; /* oldstyle figures in prose */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--goudy);
  font-weight: 400;
  line-height: 1.12;
  color: var(--display);
}
h1 { font-size: 3.2rem; letter-spacing: -0.005em; }
h2 { font-size: 2rem; }
h3 { font-size: 1.35rem; }

p { max-width: 34em; }
p + p { margin-top: 0.7em; }

a { color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.12em; }

em, i { font-style: italic; }

::selection { background: var(--actor); color: var(--on-actor); }

/* Keyboard focus is always visible, and never only a color change. */
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--actor);
  outline-offset: 3px;
}

/* ---------- 4. Apparatus (sans; Typography.md rule 2) ----------------------- */

.sans, .kicker, .btn, .list, .spoke, table, figcaption, .caption {
  font-family: var(--plex);
  font-feature-settings: "lnum", "tnum"; /* lining figures in apparatus */
}

.kicker {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tone);
}

.wordmark {
  font-family: var(--fell);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  color: var(--ink);
}

.btn {
  display: inline-block;
  background: var(--actor);
  color: var(--on-actor);
  font-size: 14px;
  font-weight: 500;
  padding: 0.55em 1.15em;
  border: 0;
  border-radius: 3px;
  text-decoration: none;
  cursor: pointer;
  transition: background 180ms ease-out;
}
.btn:hover { background: var(--actor-deep); }
.btn:active { background: var(--blue-deep); }

.quiet { color: var(--tone); }

hr.rule { border: 0; border-top: 1px solid var(--tone); }

/* ---------- 5. The mode button ---------------------------------------------
   The one place an icon is allowed (Layout.md iconography rule), flagged as a
   substitution until a house set exists. Task 8 builds the sunrise; this is the
   stub that carries the state.                                                 */

.mode-toggle {
  position: fixed;
  top: 50px;
  right: 50px;
  z-index: 20;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: var(--raised);
  color: var(--ink);
  border: 1px solid var(--frame);
  border-radius: 50%;
  cursor: pointer;
  font: inherit;
  transition: border-color 180ms ease-out, color 180ms ease-out, background 180ms ease-out;
}
.mode-toggle:hover { border-color: var(--actor); color: var(--actor-deep); }
.mode-toggle:active { background: var(--paper); }
.mode-toggle svg { width: 20px; height: 20px; display: block; pointer-events: none; }
/* The icon shows the lighting you would switch to: a moon by day, a sun by night. */
.mode-toggle .icon-sun { display: none; }
:root[data-mode="night"] .mode-toggle .icon-sun { display: block; }
:root[data-mode="night"] .mode-toggle .icon-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="day"]) .mode-toggle .icon-sun { display: block; }
  :root:not([data-mode="day"]) .mode-toggle .icon-moon { display: none; }
}

/* ---------- 6. The drawn frame (task 2) -------------------------------------
   frame.svg is a nine-slice drawing: corners and edges keep their line weight
   at any poster size, so the band never stretches. It paints in currentColor,
   which the tile sets to --frame.                                              */

.framed { position: relative; }
.framed > .frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 4;
}
/* The outer rule again, in orange, waiting. Hover, keyboard focus and tap all
   bring it up; the rule is the signal, never the only one. */
.framed > .frame-hot {
  opacity: 0;
  transition: opacity 200ms ease-out;
}
.framed:hover > .frame-hot,
.framed:focus-visible > .frame-hot,
.framed:active > .frame-hot { opacity: 1; }

/* The drawing itself is markup, not a picture: it carries no size and no colour
   of its own. The ink is set here, once, and the whole frame reads currentColor.
   Pattern content takes its colour from where the pattern sits, so the hot set
   gets its own line. */
.frame-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  color: #6a655e; /* the day frame, literal: this set never changes colour */
}
.frame-defs .night { color: #7d98c2; }
.frame-defs .hot { color: var(--actor); }
/* Each poster carries both frames; the lighting decides which one shows, and
   the switch (section 10) cross-fades them. */
.framed > .frame-night { opacity: 0; }
:root[data-mode="night"] .framed > .frame-day { opacity: 0; }
:root[data-mode="night"] .framed > .frame-night { opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="day"]) .framed > .frame-day { opacity: 0; }
  :root:not([data-mode="day"]) .framed > .frame-night { opacity: 1; }
}

/* ---------- 6b. Foil (task 7, decision 24) ---------------------------------
   Hovering a poster turns the engraving under the cursor to foil: the ink lines
   pick up a band of orange, gold, and the house blue that slides as the pointer
   moves, the way light moves on a reflective poster. Only the lines take colour.
   The layer is a colour sheet seen through two masks at once: the line work and
   a soft spot at the pointer. On the placeholder the line work is the hatch; on
   a real poster it is NAME-lines.jpg, the drawing inverted, whose white strokes
   on black make a luminance mask. hover.js moves the spot and the sheen;
   without it the layer never shows and the orange rule still does the work.   */

/* The foil layer lives inside the picture and fills it, so it is the picture's
   own box that it is masked against. It used to sit beside the picture with its
   own 37 px inset; once it moved inside, that inset applied twice and the sheen
   landed a frame's width down and in from the drawing. */
.wet {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity 220ms ease-out;
  /* The band has to be narrower than the lit spot, or the whole spot takes one
     flat colour and reads as a stain rather than a sheen. At 55% of the poster
     the pointer carries two or three bands with it. */
  /* The band has to be narrower than the lit spot, or the whole spot takes one
     flat colour and reads as a stain rather than a sheen. At 55% of the poster
     the pointer carries two or three bands with it. The cool note is the tone
     blue, not the deep blue: a dark blue on a light poster reads as a smudge. */
  background: linear-gradient(105deg,
    var(--actor-deep) 0%, var(--actor) 12%, #f0c477 26%, #e6dcc0 38%,
    var(--tone) 50%, #e6dcc0 62%, #f0c477 74%, var(--actor) 88%, var(--actor-deep) 100%);
  background-size: 55% 100%;
  background-position: var(--mx, 50%) 0;
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
.wet.placeholder-ink {
  -webkit-mask-image:
    repeating-linear-gradient(45deg, #000 0 1px, transparent 1px 6px),
    radial-gradient(circle calc(var(--d) * 0.5) at var(--mx, 50%) var(--my, 50%), #000 0%, rgba(0,0,0,0.55) 45%, transparent 100%);
  mask-image:
    repeating-linear-gradient(45deg, #000 0 1px, transparent 1px 6px),
    radial-gradient(circle calc(var(--d) * 0.5) at var(--mx, 50%) var(--my, 50%), #000 0%, rgba(0,0,0,0.55) 45%, transparent 100%);
}
/* task 6: <div class="wet" style="--lines:url(posters/berkshire-night.png)"> */
.wet.drawing-ink {
  -webkit-mask-image:
    var(--lines),
    radial-gradient(circle calc(var(--d) * 0.5) at var(--mx, 50%) var(--my, 50%), #000 0%, rgba(0,0,0,0.55) 45%, transparent 100%);
  mask-image:
    var(--lines),
    radial-gradient(circle calc(var(--d) * 0.5) at var(--mx, 50%) var(--my, 50%), #000 0%, rgba(0,0,0,0.55) 45%, transparent 100%);
  -webkit-mask-size: cover, auto;
  mask-size: cover, auto;
  /* The strokes have to land on the drawing exactly. object-fit: cover centres
     and sits on the floor; a mask defaults to the top left corner, which is
     what threw the sheen off the lines. Same box, same anchor, same fit. */
  -webkit-mask-position: center bottom, center;
  mask-position: center bottom, center;
  mask-mode: luminance, alpha;
  z-index: 3;
}
.poster.lit .wet { opacity: 1; }

/* ---------- 7. Page grain ---------------------------------------------------
   Paper tooth. Flat ink on paper; no emboss, bevel or shadow anywhere
   (decision 15).                                                               */

.grain {
  position: absolute;
  inset: 0;
  /* Above the drawing (1), under the foil (3) and the frame (4). The tooth is
     the poster's paper, so it has to fall on the drawing too: with the drawing
     above it, the drawing was the one ungrained rectangle on the tile and read
     as a lighter panel against its own ground. */
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: var(--grain-blend);
  opacity: var(--grain-opacity);
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .18 0 0 0 0 .17 0 0 0 0 .16 0 0 0 .05 0'/></filter><rect width='200' height='200' filter='url(%23n)'/></svg>");
}

/* ---------- 8. The main page: the field ------------------------------------
   Four posters in golden section, 8 : 5 : 3 : 2, on the whole viewport, with the
   medallion at the eye of the spiral (decisions 3, 7, 8, 11, 13). One screen,
   no scroll. The narrow layout is task 5; until then the field is the page from
   900 px up, and below that the posters simply stack in source order.            */

.home { overflow: hidden; }

.field {
  /* The medallion's diameter: 350 px on a 1440 px window, held between 220 and
     420 (decision 13). The field keeps it, because the posters have to dodge it. */
  --d: clamp(220px, 24.3vw, 420px);
  position: relative;
  height: 100svh;
  min-height: 560px;
}

.poster {
  position: absolute;
  display: block;
  text-decoration: none;
  color: var(--ink);
  background: var(--raised);
  overflow: hidden;
}
.poster:focus-visible { outline-offset: -4px; }

/* 8 : 5 : 3 : 2. The vertical cut is the golden section of the width, the
   horizontal cut the golden section of the height. */
.poster-berkshire { left: 0;     top: 0;   width: 62.5%; height: 100%; }
.poster-spacex    { left: 62.5%; top: 0;   width: 37.5%; height: 60%; }
.poster-next      { left: 62.5%; top: 60%; width: 25%;   height: 40%; }
.poster-shop      { left: 87.5%; top: 60%; width: 12.5%; height: 40%; }

/* The picture sits inside the frame's 37 px. Until a drawing lands it is the
   hatched placeholder from the prototype, with the poster's brief on it; a poster
   that has its drawing turns the hatch off. */
.picture {
  position: absolute;
  inset: 37px;
  overflow: hidden;
}
/* The hatch is a colour seen through a mask, not a gradient of colours, so it
   can glide with the rest of the page when the lighting switches. */
.picture.has-drawing::before, .picture.has-drawing::after { content: none; }
.picture::before, .picture::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-color: var(--hatch-1);
  -webkit-mask-image: repeating-linear-gradient(45deg, #000 0 1px, transparent 1px 6px);
  mask-image: repeating-linear-gradient(45deg, #000 0 1px, transparent 1px 6px);
}
.picture::after {
  background-color: var(--hatch-2);
  -webkit-mask-image: repeating-linear-gradient(-45deg, #000 0 1px, transparent 1px 9px);
  mask-image: repeating-linear-gradient(-45deg, #000 0 1px, transparent 1px 9px);
}
/* A drawing is landscape and sits on the tile's floor, not stretched to the
   square. --drawing-h leaves paper above it, so the collage ends where the
   collage ends; the drawing is wider than the tile, so a wider window reveals
   more of it rather than scaling it up. Per poster, because each one's subject
   sits at its own height. */
.picture.has-drawing { --drawing-h: 80%; }
.picture img,
.picture.has-drawing > .wet {
  position: absolute;
  left: 0;
  right: 0;
  top: auto;          /* height decides the box; bottom pins it to the floor */
  bottom: 0;
  height: 100%;
}
.picture img { z-index: 1; }
.picture.has-drawing img,
.picture.has-drawing > .wet { height: var(--drawing-h); }
.picture img {
  width: 100%;
  object-fit: cover;
  object-position: center bottom;
  display: block;
}
/* Day and night drawings are two files, switched here rather than by a
   <picture> media query: the media query cannot see the visitor's own choice. */
.picture .night { opacity: 0; }
:root[data-mode="night"] .picture .day { opacity: 0; }
:root[data-mode="night"] .picture .night { opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="day"]) .picture .day { opacity: 0; }
  :root:not([data-mode="day"]) .picture .night { opacity: 1; }
}

.placeholder {
  position: absolute;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
  max-width: 70%;
  padding: 0.4em 0.8em;
  border: 1px solid var(--ink);
  background: var(--raised);
  font-family: var(--plex);
  font-size: 11px;
  line-height: 1.35;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
}

/* The label, inside the frame and over the picture (decision 16). Each line
   carries its own paper behind it; task 6 decides whether it keeps that once a
   real drawing is underneath. */
.label {
  position: absolute;
  left: 56px;
  right: 56px;
  bottom: 54px;
  z-index: 5;
  max-width: 30em;
}
.label .kicker {
  display: block;
  width: max-content;
  max-width: 100%;
  margin-bottom: 8px;
  padding: 2px 6px;
  background: var(--raised);
  color: var(--ink);
}
/* Title and description run in together, the way a poster is captioned in a
   printed catalogue, and the paper hugs the text line by line rather than
   boxing the block. The run-in also keeps the label clear of the medallion on
   the five-unit poster, which a stacked label is too tall to do. */
.label h2, .label p {
  display: inline;
  padding: 2px 8px;
  background: var(--raised);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.label h2 { font-size: 36px; color: var(--ink); }
.label p { margin: 0; font-size: 17px; line-height: 1.62; }
.label .list {
  display: block;
  width: max-content;
  max-width: 100%;
  margin-top: 12px;
  padding: 3px 6px;
  background: var(--raised);
  color: var(--actor-deep);
  font-size: 12px;
}
/* The medallion is centred on this poster's left edge, so the label starts past
   the circle's widest point: half a diameter plus a margin. Tied to the
   medallion's own size, it clears at every window width rather than at the ones
   that happened to be measured. */
.poster-spacex .label { left: calc(var(--d) / 2 + 20px); }
.poster-spacex .label h2 { font-size: 30px; }
.poster-spacex .label p { font-size: 16px; }
.poster-next .label { left: 48px; right: 48px; bottom: 46px; }
.poster-next .label h2 { font-size: 22px; }
.poster-next .label p { font-size: 15px; }
.poster-shop .label { left: 46px; right: 42px; bottom: 44px; }
.poster-shop .label h2 { font-size: 18px; }
.poster-shop .label p { font-size: 14px; }

/* ---------- 9. The medallion ------------------------------------------------
   350 px on a 1440 px window, never under 220 or over 420 (decision 13). It sits
   at the eye of the spiral, not the centre of the page (decision 8).            */

.medallion {
  position: absolute;
  left: 62.5%;
  top: 24%;
  transform: translate(-50%, -50%);
  z-index: 6;
  width: var(--d);
  height: var(--d);
  text-align: center;
  border-radius: 50%;
  overflow: hidden; /* the word tabs at east and west would otherwise cross the rule */
  background: var(--paper);
  border: 1px solid var(--ink);
}
/* One flat rule outside, one tint ring inside (decision 15: engraved, not a
   shadow). The second outer rule that used to sit 9 px out is gone: it read as
   padding and made the doors look off centre (checkpoint 1 correction). */
.medallion::after {
  content: "";
  position: absolute;
  inset: calc(var(--d) * 0.13);
  border-radius: 50%;
  border: 1px solid var(--tint);
  pointer-events: none;
}
/* The lockup is the brand's own lockup-v drawing (Logo.md, assets/export), and
   with the one-liner under it forms one block, pinned to the circle's centre.
   Nothing else in the medallion is in flow, so nothing can push it off centre. */
.medallion .core {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  row-gap: calc(var(--d) * 0.04);
}
.medallion .lockup { display: block; width: calc(var(--d) * 0.36); }
.medallion .lockup img { display: block; width: 100%; height: auto; }
.medallion small {
  display: block;
  width: max-content;
  max-width: calc(var(--d) * 0.5);
  font-style: italic;
  font-size: calc(var(--d) * 0.046);
  line-height: 1.3;
  text-align: center;
}

/* The four doors, at the compass points. Always visible, never on hover
   (decision 10). Each door is a quarter of the ring between the outer circle
   and the inner one: the whole quadrant is the link, the word sits at its
   centre, and on hover the quadrant fills with the frame's hatching, as if that
   quarter of the dial had been engraved. */
.field-nav { position: absolute; inset: 0; }
.spoke {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  cursor: pointer;
  text-decoration: none;
  background:
    repeating-linear-gradient(45deg, var(--hatch-1) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-45deg, var(--hatch-2) 0 1px, transparent 1px 8px);
  opacity: 0;
  transition: opacity 180ms ease-out;
}
.spoke:hover, .spoke:focus-visible { opacity: 1; }
.spoke:focus-visible { outline: none; }
.spoke.n { clip-path: polygon(85.36% 14.64%, 81.17% 10.91%, 76.60% 7.66%, 71.69% 4.95%, 66.51% 2.81%, 61.13% 1.25%, 55.60% 0.31%, 50.00% 0.00%, 44.40% 0.31%, 38.87% 1.25%, 33.49% 2.81%, 28.31% 4.95%, 23.40% 7.66%, 18.83% 10.91%, 14.64% 14.64%, 23.84% 23.84%, 26.93% 21.07%, 30.31% 18.67%, 33.95% 16.66%, 37.78% 15.08%, 41.77% 13.93%, 45.86% 13.23%, 50.00% 13.00%, 54.14% 13.23%, 58.23% 13.93%, 62.22% 15.08%, 66.05% 16.66%, 69.69% 18.67%, 73.07% 21.07%, 76.16% 23.84%); }
.spoke.e { clip-path: polygon(85.36% 85.36%, 89.09% 81.17%, 92.34% 76.60%, 95.05% 71.69%, 97.19% 66.51%, 98.75% 61.13%, 99.69% 55.60%, 100.00% 50.00%, 99.69% 44.40%, 98.75% 38.87%, 97.19% 33.49%, 95.05% 28.31%, 92.34% 23.40%, 89.09% 18.83%, 85.36% 14.64%, 76.16% 23.84%, 78.93% 26.93%, 81.33% 30.31%, 83.34% 33.95%, 84.92% 37.78%, 86.07% 41.77%, 86.77% 45.86%, 87.00% 50.00%, 86.77% 54.14%, 86.07% 58.23%, 84.92% 62.22%, 83.34% 66.05%, 81.33% 69.69%, 78.93% 73.07%, 76.16% 76.16%); }
.spoke.s { clip-path: polygon(14.64% 85.36%, 18.83% 89.09%, 23.40% 92.34%, 28.31% 95.05%, 33.49% 97.19%, 38.87% 98.75%, 44.40% 99.69%, 50.00% 100.00%, 55.60% 99.69%, 61.13% 98.75%, 66.51% 97.19%, 71.69% 95.05%, 76.60% 92.34%, 81.17% 89.09%, 85.36% 85.36%, 76.16% 76.16%, 73.07% 78.93%, 69.69% 81.33%, 66.05% 83.34%, 62.22% 84.92%, 58.23% 86.07%, 54.14% 86.77%, 50.00% 87.00%, 45.86% 86.77%, 41.77% 86.07%, 37.78% 84.92%, 33.95% 83.34%, 30.31% 81.33%, 26.93% 78.93%, 23.84% 76.16%); }
.spoke.w { clip-path: polygon(14.64% 14.64%, 10.91% 18.83%, 7.66% 23.40%, 4.95% 28.31%, 2.81% 33.49%, 1.25% 38.87%, 0.31% 44.40%, 0.00% 50.00%, 0.31% 55.60%, 1.25% 61.13%, 2.81% 66.51%, 4.95% 71.69%, 7.66% 76.60%, 10.91% 81.17%, 14.64% 85.36%, 23.84% 76.16%, 21.07% 73.07%, 18.67% 69.69%, 16.66% 66.05%, 15.08% 62.22%, 13.93% 58.23%, 13.23% 54.14%, 13.00% 50.00%, 13.23% 45.86%, 13.93% 41.77%, 15.08% 37.78%, 16.66% 33.95%, 18.67% 30.31%, 21.07% 26.93%, 23.84% 23.84%); }
/* The word sits on the ring's centre line, 43.5% of the diameter from the
   middle. It is drawn by its own layer, so it stays put whatever the quadrant
   under it does. */
.field-nav .word {
  position: absolute;
  pointer-events: none;
  transform: translate(-50%, -50%);
  padding: 3px 8px;
  background: var(--paper);
  color: var(--actor-deep);
  font-family: var(--plex);
  font-feature-settings: "lnum", "tnum";
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  transition: color 180ms ease-out;
}
.field-nav .word.n { left: 50%; top: 6.5%; }
.field-nav .word.s { left: 50%; top: 93.5%; }
.field-nav .word.e { left: 93.5%; top: 50%; }
.field-nav .word.w { left: 6.5%; top: 50%; }
.spoke.n:hover ~ .word.n, .spoke.e:hover ~ .word.e,
.spoke.s:hover ~ .word.s, .spoke.w:hover ~ .word.w,
.spoke.n:focus-visible ~ .word.n, .spoke.e:focus-visible ~ .word.e,
.spoke.s:focus-visible ~ .word.s, .spoke.w:focus-visible ~ .word.w { color: var(--ink); }

/* ---------- 9b. The bar (decision 12) --------------------------------------
   The inner pages' top bar: lockup left, the four doors right, 52 px, sticky.
   The main page carries it only under 900 px, where the medallion is gone.   */

.bar {
  display: none;
  position: sticky;
  top: 0;
  z-index: 10;
  align-items: center;
  justify-content: space-between;
  height: 52px;
  padding: 0 16px;
  background: var(--paper);
  border-bottom: 1px solid var(--frame);
}
.bar .brand { display: block; height: 26px; }
.bar .brand img { display: block; height: 100%; width: auto; }
.bar .brand .night { display: none; }
:root[data-mode="night"] .bar .brand .day { display: none; }
:root[data-mode="night"] .bar .brand .night { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="day"]) .bar .brand .day { display: none; }
  :root:not([data-mode="day"]) .bar .brand .night { display: block; }
}
.bar .links { display: flex; gap: 14px; }
.bar .links a {
  padding: 8px 2px;
  color: var(--actor-deep);
  font-family: var(--plex);
  font-feature-settings: "lnum", "tnum";
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.bar .links a:hover { color: var(--ink); }

/* ---------- 9c. Narrower windows (task 5) -----------------------------------
   Between 900 and 1200 px the field holds, but the three smaller posters drop
   their paragraph so nothing overflows a frame. Under 900 px the posters stack
   in one column with their full text, the medallion goes, and the bar takes
   over (decision 21).                                                          */

@media (max-width: 1200px) {
  .poster-spacex .label p, .poster-next .label p, .poster-shop .label p { display: none; }
  .poster-spacex .label h2 { font-size: 26px; }
  .poster-next .label h2 { font-size: 20px; }
  .poster-shop .label h2 { font-size: 16px; }
}

@media (max-width: 899.98px) {
  .home { overflow: auto; }
  .bar { display: flex; }
  .bar .links { gap: 10px; }
  .bar .links a { font-size: 12px; }
  .field {
    position: static;
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: 0;
  }
  .poster { position: relative; left: auto; top: auto; width: 100%; height: auto; }
  .poster-berkshire { min-height: 125vw; }
  .poster-spacex    { min-height: 100vw; }
  .poster-next      { min-height: 72vw; }
  .poster-shop      { min-height: 56vw; }
  .placeholder { top: 30%; }
  /* stacked: every label sits the same way, full text, the paragraphs back */
  .poster .label { left: 44px; right: 44px; bottom: 40px; }
  .poster .label p { display: inline; }
  .poster .label h2 { font-size: 28px; }
  .poster .label p { font-size: 15px; }
  .poster-shop .label h2, .poster-next .label h2 { font-size: 22px; }
  .medallion { display: none; }
  /* No lighting button on a phone: the page follows the system there. */
  .mode-toggle { display: none; }
}

/* ---------- 10. The switch (task 8, decision 25) ----------------------------
   Day to night is a glide, not a cut. light-dark() hands every property a new
   computed colour when the mode flips; while the root carries .dusk (mode.js,
   1.1 s) those properties are allowed to transition to it. The frame is two drawings,
   day and night, cross-faded by opacity (section 6). The medallion takes 350 ms and
   the field 800 ms starting a beat later, so the medallion brightens first, as
   the sun. 900 ms in all is a deliberate exception to Layout.md's 150 to 250 ms rule,
   flagged for the brand owner.                                                 */

:root.dusk *, :root.dusk *::before, :root.dusk *::after {
  transition:
    background-color 800ms cubic-bezier(.4,0,.2,1) 100ms,
    color 800ms cubic-bezier(.4,0,.2,1) 100ms,
    border-color 800ms cubic-bezier(.4,0,.2,1) 100ms,
    opacity 800ms cubic-bezier(.4,0,.2,1) 100ms !important;
}
:root.dusk .medallion, :root.dusk .medallion *, :root.dusk .medallion *::after {
  transition-duration: 350ms !important;
  transition-delay: 0ms !important;
}
/* Day and night pictures sit on top of each other and cross-fade rather than
   swap: the medallion's lockup here, the posters' drawings in section 8. */
.medallion .lockup { position: relative; }
.medallion .lockup img { display: block; transition: opacity 400ms; }
.medallion .lockup .night { position: absolute; inset: 0; opacity: 0; }
:root[data-mode="night"] .medallion .lockup .day { opacity: 0; }
:root[data-mode="night"] .medallion .lockup .night { opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="day"]) .medallion .lockup .day { opacity: 0; }
  :root:not([data-mode="day"]) .medallion .lockup .night { opacity: 1; }
}

/* ---------- 11. Motion ------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
  }
}
