/* ============================================================
   Kim Kenny — personal website
   Minimal layout over a maximal painted background.
   ============================================================ */

:root {
  --ink: #23262b;            /* near-black, neutral */
  --ink-soft: #23262b;       /* the same ink: captions read black too */
  --paper: rgba(252, 250, 244, 0.90);
  --accent: #3d4f3f;         /* muted Seurat green */
  --tooltip-bg: #1c1a17;
  --hairline: rgba(28, 32, 40, 0.12);
  --rail-width: 52px;

  /* Liquid glass: cool white-grey, radically transparent surfaces.
     The painting is the hero; every UI layer is frosted glass over it. */
  --cream: rgba(252, 253, 255, 0.5);        /* main glass surface */
  --cream-solid: #f7f9fb;                    /* opaque white for labels */
  --pencil: #5b6169;                         /* neutral grey lettering */
  --warm-edge: rgba(255, 255, 255, 0.55);    /* bright glass edges */
  --kraft: rgba(252, 253, 255, 0.6);         /* the fold band's glass */
  --tape: rgba(255, 255, 255, 0.35);         /* (unused ornament tint) */
  --shadow-warm: rgba(22, 28, 38, 0.2);      /* cool neutral shadows */
  /* Interactive marks — arrows, rules, footnote numbers — are the
     ink itself, turned down: quiet on the glass, still legible */
  --mark: rgba(35, 38, 43, 0.68);
  --mark-soft: rgba(35, 38, 43, 0.42);
  --grain-fine: none;                        /* glass has no grain */
}

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

html {
  scroll-behavior: smooth;
}

body {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.95;
  letter-spacing: 0.012em;
  color: var(--ink);
  min-height: 100vh;
  background: #eef0f3;
}

/* The maximal part: the painting, full bleed, fully alive —
   no blur, no veil. Legibility comes from the paper card. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  /* The wallpaper painting. --painting is set by the picker in the
     loupe panel (and remembered across pages); this is the default. */
  background-image: var(--painting, url("../painting/triumph-of-venus.jpg"));
  background-size: cover;
  /* Each painting sets its own focus (--painting-pos comes from its
     pos in js/loupe.js): portraits sit higher so faces stay in view,
     and the fresco holds its left edge so the two hands meet near the
     middle of the screen. The fallback is the fresco's, since that is
     the wall a first visitor meets. */
  background-position: var(--painting-pos, center);
  z-index: -1;
}

/* Where the glass sheet rests: the band + pillar start mid-screen.
   Scrolling slides the sheet up with the text like a piece of paper
   until it pins to the top of the screen (js/main.js drives
   --pillar-top from the scroll position). ∨ lowers it out of view. */
body.theme-painting {
  --pillar-top: 58vh; /* must match rest() in js/main.js */
}

/* Button moves (open/close) animate; scroll moves stay instant */
body.pillar-anim::after {
  transition: top 0.45s ease, bottom 0.45s ease;
}

body.pillar-anim .pillar-shade {
  transition: top 0.45s ease;
}

/* The text pillar: pure liquid glass — radically transparent, no
   texture. The painting glows straight through; a deep backdrop blur
   is what keeps the type readable. */
body::after {
  content: "";
  position: fixed;
  top: var(--pillar-top, 0px); /* the glass starts where the paper does */
  bottom: 0;
  left: 132px;
  width: 500px;
  pointer-events: none;
  z-index: 0;
  background-color: rgba(252, 253, 255, 0.52);
  -webkit-backdrop-filter: blur(18px) saturate(1.35);
  backdrop-filter: blur(18px) saturate(1.35);
  box-shadow:
    inset 1px 0 0 rgba(255, 255, 255, 0.5),
    inset -1px 0 0 rgba(255, 255, 255, 0.5),
    6px 0 28px var(--shadow-warm),
    -6px 0 28px var(--shadow-warm);
}

/* The band: a brighter strip of glass along the sheet's top edge,
   holding two controls — ∨ lowers the sheet away, ∧ raises it. */
/* The sheet's top edge, poured in early-2000s glass: a thin Aqua
   bar, translucent so the paper's own glass reads through, with the
   gloss lying along its upper half */
.pillar-shade {
  position: fixed;
  top: var(--band-top, 0px); /* rides the paper up and off the screen */
  left: 132px;
  width: 500px;
  height: 20px;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 26px; /* the title sits just clear of the close */
  /* brushed metal: a cool grey rolled from light to shadow, with a
     lit top edge and a dark seam where it meets the paper */
  border-bottom: 1px solid rgba(80, 88, 98, 0.5);
  background: linear-gradient(
    180deg,
    #f2f4f6 0%,
    #e2e6ea 42%,
    #d3d8de 58%,
    #c6ccd3 100%
  );
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(255, 255, 255, 0.35);
}

.pillar-shade button {
  width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

/* Every band icon — raise, lower, fold — same size, same weight,
   quiet until the cursor comes near: the band is tooling, not
   decoration, so it keeps the rail's icon language */
.pillar-shade svg {
  width: 13px;
  height: 13px;
  stroke: var(--ink-soft);
  stroke-width: 1.6;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.35;
  transition: opacity 0.25s ease, stroke 0.2s ease;
}

.pillar-shade:hover svg {
  opacity: 0.75;
}

.pillar-shade button:hover svg {
  opacity: 1;
  stroke: var(--ink);
}

/* A small × on the band's right edge folds the sheet completely,
   from any state; it hides while the sheet is already folded */
/* The close is simply the mark itself, resting on the glass */
.pillar-shade .shade-close {
  position: absolute;
  right: 2px;
  top: 0;
  bottom: 0;
  transform: none;
  width: 24px;
  height: auto;
  z-index: 1;
  border: none;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.pillar-shade .shade-close svg {
  width: 8px;
  height: 8px;
  opacity: 0.55;
  stroke: #5a626c;
  transition: opacity 0.15s ease;
}

.pillar-shade .shade-close:hover svg {
  opacity: 0.95;
}

/* Two A's for how large the letter is set, in the same key as the
   languages beside them */
.shade-sizes {
  position: absolute;
  left: 170px;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 2px;
}

.pillar-shade .size-pick {
  width: auto;
  height: 18px;
  padding: 0 6px;
  border-radius: 5px;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  color: var(--ink-soft);
  opacity: 0.45;
  transition: opacity 0.25s ease, color 0.2s ease, background 0.2s ease;
}

.pillar-shade .size-pick[data-size="small"] {
  font-size: 10px;
}

.pillar-shade .size-pick[data-size="large"] {
  font-size: 14px;
}

.pillar-shade:hover .size-pick {
  opacity: 0.8;
}

.pillar-shade .size-pick:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.5);
}

.pillar-shade .size-pick.active {
  opacity: 1;
  color: var(--ink);
  font-weight: 500;
  background: rgba(255, 255, 255, 0.75);
  box-shadow: 0 1px 4px rgba(22, 28, 38, 0.1);
}

/* The larger setting: the letter alone grows, the labels and lists
   around it keep their measure */
body.text-large .letter p {
  font-size: 18px;
  line-height: 1.85;
}

/* The build number sits where a machine would put it: right of the
   fold control, in the mono voice, quiet until you come looking */
/* The title, centred on the glass */
.shade-build {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  padding: 0 8px;
  background: none;
  font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 7.5px;
  letter-spacing: 0.8px;
  color: #3a5a82;
  opacity: 0.75;
  transition: opacity 0.25s ease;
}

.pillar-shade:hover .shade-build {
  opacity: 1;
}

/* The letter's four languages ride the band's left edge, as quiet
   as the icons beside them until you come looking */
.shade-langs {
  position: absolute;
  left: 33px; /* the key's padding lands its letter on the text line */
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}

.pillar-shade .lang-pick {
  width: auto;
  height: 18px;
  padding: 0 7px;
  border-radius: 5px;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.4px;
  color: var(--ink-soft);
  opacity: 0.45;
  transition: opacity 0.25s ease, color 0.2s ease, background 0.2s ease;
}

.pillar-shade:hover .lang-pick {
  opacity: 0.8;
}

.pillar-shade .lang-pick:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.5);
}

/* The language in use wears the pressed key, like the rail's
   current page and the tool bar's open tool */
.pillar-shade .lang-pick.active {
  opacity: 1;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.75);
  box-shadow: 0 1px 4px rgba(22, 28, 38, 0.1);
}


/* the button stays when the sheet folds: it is the way back */
body.pillar-closed .shade-close svg {
  opacity: 0;
}

/* The band belongs to the sheet: it rides up with the paper and
   slips off the top of the screen along with it */
.pillar-shade {
  overflow: hidden;
}

/* The text starts just below the resting band, then scrolls
   normally — the sheet follows it up via --pillar-top */
body.theme-painting .page {
  padding-top: calc(64vh + 30px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}

/* Closed: the sheet slides down flush with the bottom edge, like a
   letter dropping back into its envelope — its top line matching
   the toolbar's top line */
body.pillar-closed::after {
  top: calc(100vh - 49px);
}

body.pillar-closed .pillar-shade {
  top: calc(100vh - 64px);
  border-bottom: none;
  border-top: 1px solid rgba(255, 255, 255, 0.5);
}

body.pillar-closed .page {
  opacity: 0;
  transform: translateY(6vh);
  pointer-events: none;
}

/* ============================================================
   Hero layout (Home): the painting is the entrance hall.
   First screen: full-bleed painting and the name. Scrolling
   slides a full-width cream reading page up over it.
   ============================================================ */

/* No fixed glass pillar here — the reading page itself scrolls */
body.theme-hero::after {
  display: none;
}

.hero {
  position: relative;
  height: 100svh;
  padding-left: var(--rail-width);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
}

.hero-name {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: clamp(46px, 7vw, 88px);
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1.1;
  color: #fffdf6;
  text-shadow:
    0 2px 30px rgba(28, 24, 16, 0.55),
    0 1px 3px rgba(28, 24, 16, 0.4);
}

.hero-tag {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 1px 14px rgba(28, 24, 16, 0.6);
}

/* Gentle bobbing chevron: "there's more below" */
.hero-cue {
  position: absolute;
  bottom: 30px;
  left: calc(50% + var(--rail-width) / 2);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: cue-bob 2.4s ease-in-out infinite;
}

.hero-cue svg {
  width: 22px;
  height: 22px;
  stroke: rgba(255, 255, 255, 0.9);
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 1px 6px rgba(28, 24, 16, 0.6));
}

@keyframes cue-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(8px); }
}

/* The reading page: a full-width sheet of cream paper that rides
   up and covers the painting as you scroll */
body.theme-hero .page {
  margin-left: var(--rail-width);
  padding: 12vh 40px 24vh;
  background-color: var(--cream-solid);
  background-image: var(--grain-fine);
  background-size: 320px 320px;
  background-blend-mode: multiply;
  box-shadow: 0 -18px 44px rgba(22, 28, 38, 0.35);
}

body.theme-hero .paper {
  max-width: 600px;
  margin: 0 auto;
}

/* Past the hero, the painting tools bow out quietly */
body.past-hero .loupe-panel,
body.past-hero .loupe-bar {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

body.past-hero .loupe-box {
  display: none;
}

/* ============================================================
   Left icon rail
   ============================================================ */

.rail {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--rail-width);
  z-index: 10;

  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px 0 0;
  /* the nav, then the links, then the settings */

  /* The application's own chrome: flat system grey, a lit edge on
     the left and a shadowed one on the right, the way a toolbox
     was moulded into the window frame */
  background: rgba(207, 207, 203, 0.42);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
  border-right: 1px solid rgba(85, 86, 90, 0.5);
  box-shadow: inset 1px 0 0 rgba(251, 251, 249, 0.75),
    inset -2px 0 0 rgba(85, 86, 90, 0.18);
}

/* No profile at the top: the column opens straight onto Home */
.rail-avatar {
  display: none;
}

.rail-nav {
  margin-bottom: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 30px;
}

/* The outside lines, kept as marks alone: three small tool buttons
   at the foot of the box, moulded like every other tool above */
.rail-bottom {
  order: 2; /* the links close the column, just clear of the floor */
  margin-top: auto;
  margin-bottom: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: 44px;
  padding: 20px 0 0;
  border: none;
  border-top: 1px solid rgba(85, 86, 90, 0.28);
  background: transparent;
  box-shadow: none;
}

/* No moulding here: the marks simply sit in the well, spaced like
   the tools above but without a button around each */
.rail-bottom .rail-link {
  position: relative; /* the tooltip anchors here, not on the box */
  width: 100%;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--ink);
  transform: none;
  transition: opacity 0.12s ease;
  opacity: 1;
}

.rail-bottom .rail-link svg {
  width: 16px;
  height: 16px;
  flex: none;
  stroke-width: 1.9; /* the marks read solid, not sketched */
}

/* their names retire to the tooltip, which stays hidden until asked */
.rail-bottom .rail-link::after {
  content: none;
}

.rail-bottom .rail-link .tooltip {
  display: none;
}

.rail-bottom .rail-link:hover .tooltip {
  display: block;
  opacity: 1;
}

/* The résumé folder is the one coloured thing in the box: a little
   blue file, drawn full rather than in outline */
/* The résumé leads the links, as a plain folder emoji. It sits in
   the same box the drawn marks do, so all four share one rhythm. */
.rail-bottom .rail-resume .rail-emoji {
  font-size: 15px;
  line-height: 1;
  display: block;
}

.rail-bottom .rail-resume:active .rail-emoji {
  transform: translate(1px, 1px);
}

.rail-bottom .rail-link:hover {
  background: transparent;
  color: var(--ink);
  opacity: 1;
  transform: none;
}

/* pressed, like any tool in the box */
.rail-bottom .rail-link:active svg {
  transform: translate(1px, 1px);
}

.rail-bottom .rail-link:active svg {
  transform: translate(1px, 1px);
}

.rail-link {
  width: 100%;
  height: 16px; /* the rows breathe, like the menus above */
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  padding: 0 0 0 6px;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--ink);
  transform: none;
  transition: background 0.12s ease;
}

.rail-bottom .rail-link::after {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 7.2px;
  font-weight: 500;
  letter-spacing: 0.2px;
  color: var(--ink);
}

.rail-bottom .rail-link:hover {
  background: #ececea;
  color: var(--ink);
  transform: none;
}

.rail-link {
  width: 26px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(35, 38, 43, 0.55);
  border-radius: 4px;
  background: #fff;
  box-shadow: inset 0 1px 2px rgba(35, 38, 43, 0.25),
    0 1px 0 rgba(255, 255, 255, 0.65);
  color: rgba(86, 92, 102, 0.85);
  transform: none;
  transition: color 0.15s ease, background 0.15s ease;
}

.rail-bottom .rail-link:hover {
  background: #fff;
  color: var(--ink);
  transform: none;
}



.rail-link {
  position: relative;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  color: rgba(86, 92, 102, 0.8);
  text-decoration: none;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.rail-link svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rail-link .rail-emoji {
  font-size: 18px;
  line-height: 1;
}

.rail-link:hover {
  background: rgba(255, 255, 255, 0.55);
  color: var(--ink);
  transform: translateY(-2px); /* a little dock-style hop */
}

.rail-link.active {
  background: rgba(255, 255, 255, 0.75);
  color: var(--ink);
  box-shadow: 0 2px 8px rgba(22, 28, 38, 0.12);
}

/* Each main tab is one chunky block: icon on top, its section dots
   tucked inside underneath */
/* The toolbox: tools set two to a row in a sunken well, each one a
   little raised button. The tool in use is pressed in. */
.rail-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 44px;
  padding: 3px;
  border: none;
  border-radius: 0;
  margin-bottom: 11px;
  /* the well the buttons sit in, poured now in glass */
  background: rgba(190, 190, 186, 0.3);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.4),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
  transform: none;
  overflow: visible;
}

.rail-group.active {
  background: rgba(190, 190, 186, 0.3);
}

/* The page's own button, spanning the box's full width */
.rail-nav .rail-link {
  position: relative;
  width: 100%;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 0;
  margin-bottom: 3px;
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
  transition: background 0.12s ease;
}

.rail-nav .rail-link::before {
  content: none;
}

/* The page keys wear the signs they always had: the wave and the
   palette, printed on the button face */
.rail-nav .rail-link .rail-emoji {
  display: block;
  font-size: 18px;
  line-height: 1;
  filter: saturate(0.92);
}

.rail-nav .rail-link::after {
  content: none;
}

.rail-nav .rail-link:hover {
  background: rgba(255, 255, 255, 0.62);
}

/* Pressed: the button sinks, its bevel inverted */
.rail-group.active .rail-link,
.rail-nav .rail-link.pressed {
  background: rgba(160, 160, 156, 0.42);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

.rail-group.active .rail-link .rail-emoji,
.rail-nav .rail-link.pressed .rail-emoji {
  transform: translate(1px, 1px); /* the sign rides the press */
}

/* ...but Home's wave stands bare on the rail, no button under it */
.rail-group:nth-child(1) .rail-link,
.rail-group:nth-child(1) .rail-link:hover,
.rail-group:nth-child(1).active .rail-link,
.rail-group:nth-child(1) .rail-link.pressed {
  height: 34px;
  margin-bottom: 5px;
  background: transparent;
  box-shadow: none;
}

.rail-group:nth-child(1) .rail-link:hover {
  transform: translateY(-1px);
}

.rail-group:nth-child(1) .rail-link .rail-emoji {
  font-size: 23px;
}

/* Home is a house; Design is a brush */
.rail-group:nth-child(1) .rail-link {
  --page-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 10.5 12 3l9 7.5'/%3E%3Cpath d='M5.5 9.6V20h13V9.6'/%3E%3Cpath d='M9.8 20v-5.6h4.4V20'/%3E%3C/svg%3E");
}

.rail-group:nth-child(2) .rail-link {
  --page-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.5 3.2c-4.2 1-7.9 3.3-10.4 6.6l3.6 3.6c3.3-2.5 5.6-6.1 6.8-10.2z'/%3E%3Cpath d='M8.6 11.6c-2.4.6-3.9 2.7-4 5.9 0 1-.5 1.8-1.3 2.3 1.9.8 4.3.6 6-.7 1.6-1.2 2.5-2.9 2.8-4.2z'/%3E%3C/svg%3E");
}

/* The tools themselves: two to a row */
.rail-nav .rail-subs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2px;
  margin-top: 0;
  padding: 0;
  width: 100%;
}

.rail-nav .rail-sub {
  position: relative;
  width: 100%;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 0;
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
  transition: background 0.12s ease;
  opacity: 1;
}

.rail-nav .rail-sub::after {
  content: none;
}

.rail-nav .rail-sub::before {
  content: "";
  width: 15px;
  height: 15px;
  border: none;
  border-radius: 0;
  box-shadow: none;
  background: #4a4d54;
  opacity: 0.62;
  -webkit-mask: var(--sub-icon) no-repeat center / contain;
  mask: var(--sub-icon) no-repeat center / contain;
}

.rail-nav .rail-sub:hover {
  background: rgba(255, 255, 255, 0.62);
  transform: none;
}

/* The tool in use, held down */
.rail-nav .rail-sub.active {
  background: rgba(160, 160, 156, 0.42);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
  transform: none;
}

.rail-nav .rail-sub.active::before {
  opacity: 0.85;
  transform: translate(1px, 1px);
}

.rail-sub .sig {
  display: none;
}

/* The reading settings, keyed like everything else in the rail:
   the languages in a 2x2 block, the two A's beneath */
.rail-tools {
  order: 1; /* the settings sit straight under the toolboxes */
  margin-top: 0;
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px; /* two boards, clearly apart */
  padding: 10px 0;
}

/* A little control panel from an older machine: the raised grey
   plate, a stamped group label, and radio rows below it — the way
   settings looked before anyone called them preferences */
/* The reading settings are menus like everything else: Lang and
   Size panels, and the running choice wears the menu checkmark */
.rail-langs,
.rail-sizes {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 44px;
  position: relative;
  padding: 13px 3px 4px;
  border: none;
  /* the same well the tools and links sit in, so all three read as
     one machine no matter what the painting behind them is doing */
  background: rgba(190, 190, 186, 0.3);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.4),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

.rail-sizes {
  margin-top: 8px;
}

/* their headers, bold like the menus above */
.rail-langs::before,
.rail-sizes::before {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-bottom: 1px solid rgba(85, 86, 90, 0.3);
  background: none;
  box-shadow: none;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 6px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #55565a;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6);
}

.rail-langs::before {
  content: "Lang";
}

.rail-sizes::before {
  content: "Size";
}

.rail-tools button {
  position: relative;
  width: 100%;
  height: 14px;
  padding: 0 4px 0 15px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.2px;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.12s ease;
}

.rail-tools button:hover {
  background: rgba(255, 255, 255, 0.62);
}

/* the running value sits pressed, exactly as a tool does */
.rail-tools button.active {
  background: rgba(160, 160, 156, 0.42);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

/* the checkmark beside the running choice */
.rail-tools button.active::before {
  content: "\2713";
  position: absolute;
  left: 5px;
  font-size: 6.5px;
  line-height: 1;
  color: #6a6b6f;
}

/* The size rows say their value by size, small a and big A */
.rail-tools .size-pick[data-size="small"] {
  font-size: 8px;
}

.rail-tools .size-pick[data-size="large"] {
  font-size: 10.5px;
}

/* Branch signals: one small dot per section, inside the tab block */
.rail-subs {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  margin-top: 5px;
}

/* A long run of marks sits closer together than a handful of dots */
.rail-subs:has(.sig-bars) {
  gap: 3px;
  margin-top: 7px;
}

.rail-sub {
  position: relative;
  width: 24px;
  height: 17px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: inherit;
}

/* Home: tiny solid dots */
.sig-dots::before {
  content: "";
  width: 4.5px;
  height: 4.5px;
  border-radius: 50%;
  background: rgba(35, 38, 43, 0.32);
  transition: transform 0.18s ease, background 0.18s ease;
}

.sig-dots:hover::before {
  background: rgba(35, 38, 43, 0.6);
}

.sig-dots.active::before {
  background: var(--ink);
  transform: scale(1.5);
}

/* Home: small rules, one per stop, in the same language as the design
   page's scroll marks. The whole run reads as a measure of how far
   down the page you are; the one you're in draws itself out full. */
.sig-bars {
  height: 9px;
}

.sig-bars::before {
  content: "";
  width: 11px;
  height: 1.5px;
  border-radius: 1px;
  background: rgba(35, 38, 43, 0.3);
  transition: width 0.18s ease, background 0.18s ease;
}

.sig-bars:hover::before {
  width: 18px;
  background: rgba(35, 38, 43, 0.6);
}

.sig-bars.active::before {
  width: 18px;
  background: var(--ink);
}

/* Design: roman numerals, set in the book serif */
.sig-roman .sig {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 13px;
  line-height: 1;
  color: rgba(35, 38, 43, 0.4);
  transition: color 0.18s ease;
}

.sig-roman:hover .sig {
  color: rgba(35, 38, 43, 0.7);
}

.sig-roman.active .sig {
  color: var(--ink);
  font-weight: 600;
}

/* Inspirations: each section's tiny emoji, lit only when active */
.sig-emoji .sig {
  font-size: 12px;
  line-height: 1;
  filter: grayscale(1);
  opacity: 0.45;
  transition: filter 0.18s ease, opacity 0.18s ease, transform 0.18s ease;
}

.sig-emoji:hover .sig {
  opacity: 0.8;
}

.sig-emoji.active .sig {
  filter: none;
  opacity: 1;
  transform: scale(1.25);
}

/* Pencil label on a paper slip, appears to the right of the icon */
.rail-link .tooltip,
.rail-sub .tooltip {
  position: absolute;
  left: calc(100% + 14px);
  top: 50%;
  transform: translateY(-50%) translateX(-4px);

  background: var(--cream-solid);
  color: var(--pencil);
  border: 1px solid var(--warm-edge);
  box-shadow: 0 2px 8px var(--shadow-warm);
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11.5px;
  line-height: 1;
  white-space: nowrap;
  padding: 7px 10px;
  border-radius: 6px;

  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.rail-link:hover .tooltip,
.rail-sub:hover .tooltip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Plain pages (Design / Inspirations): no painting, no pillar —
   just the reading column on the ivory ground. */
body.theme-plain::before,
body.theme-plain::after {
  display: none;
}

/* ============================================================
   Dark theme (Design page): black screen, light ink.
   The CSS variables carry most components across.
   ============================================================ */

body.theme-dark {
  --ink: #ece7db;
  --ink-soft: #a49b8c;
  --hairline: rgba(236, 231, 219, 0.16);
  /* True black, but the easy kind: a near-black with the faintest
     lift so it never feels like a void */
  background: #101113;
  color: var(--ink);
}

/* The Design room: the SAME letter sheet and the SAME wallpaper
   as Home — only here the painting steps behind frosted glass, so
   the story's screens stand out against it */
body.design-dark {
  background: #3a3d42; /* peeks only past the blur's soft edge */
}

body.design-dark::before {
  display: block; /* theme-plain hides it; this page shows it */
  z-index: -2; /* under the pane of frost below */
}

/* The frost is a pane of glass over the painting, and it only
   frosts while a project visual is on stage beside the sheet: the
   opening of the page, with nothing floating there, reads through
   clear glass. The pane clips clean at its own edge, so the
   painting keeps Home's exact size and crop. */
:root:has(body.design-dark)::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  backdrop-filter: blur(0px) saturate(1) brightness(1);
  transition: backdrop-filter 0.9s ease;
}

:root:has(body.design-dark .stage.visible)::after {
  backdrop-filter: blur(12px) saturate(1.1) brightness(0.97);
}

@keyframes frost {
  from {
    filter: blur(0px) saturate(1) brightness(1);
  }
  to {
    filter: blur(20px) saturate(1.15) brightness(0.94);
  }
}

/* No dividers here: the letter flows, titles sit closer to the
   words above them */
body.design-dark .paper h2 {
  margin-top: 64px;
  margin-bottom: 28px;
}

/* One clip alone on the stage, quiet and full width, resting on
   the middle of the screen like the text beside it (the stage box
   itself sits 6vh low, so the solo slides up to compensate) */
.stage-media.stage-solo {
  border: none;
  background: none;
  align-items: center;
  top: -6vh;
  bottom: 6vh;
}

/* Sized to hug the picture itself (not a letterboxed box), so the
   rounded corners always sit on the visible edges */
.stage-solo video,
.stage-solo img {
  display: block;
  width: auto;
  max-width: 92%;
  margin: 0 auto;
  max-height: 76vh;
  object-fit: contain;
  border-radius: 10px;
  box-shadow:
    0 10px 30px rgba(22, 28, 38, 0.35),
    0 2px 8px rgba(22, 28, 38, 0.18);
}

/* Photographs sit square, like film prints; screens keep their
   rounded corners */
.stage-solo img {
  border-radius: 0;
}

/* Before and after on the stage: stacked tall, each clip as big as
   the dark room allows, labelled centred beneath */
.stage-media.stage-ba {
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  border: none;
  background: none;
}

.stage-ba figure {
  margin: 0;
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* The label sits centred beneath its clip */
.stage-ba figcaption {
  order: 2;
  text-align: center;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 1.6px;
  margin-top: 6px;
}

/* A quiet pointer to the shipped page, arrow and all */
.see-live {
  margin-top: 40px;
  font-size: 16px;
}

/* A full pause of empty room before the next project begins, so
   the last words of the one before have left the screen */
#tech-equity {
  margin-top: 75vh;
}

/* One label for a whole set of pieces from the same era */
.stage-ba .set-cap {
  text-align: center;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 1.6px;
}

/* Every piece in a set shares one width and a modest height, so
   the pair reads as one tidy stack */
.stage-ba video,
.stage-ba img {
  display: block;
  width: min(100%, calc(37vh * 1.86));
  height: auto;
  max-height: 37vh;
  object-fit: cover;
  object-position: top;
  border-radius: 6px;
}

/* The Redesign pair reads as one tall page. It borrows room beyond
   the stage box (6vh to 96vh of the screen) and centres there, so
   it can grow to the neighbouring solo assets' size. */
/* Doubled class beats .stage-media's later inset: 0 */
.stage-media.stage-page {
  top: -15vh;
  bottom: -3vh;
  justify-content: flex-start;
  gap: 24px;
}

.stage-page video,
.stage-page img {
  width: min(100%, 84vh);
  max-height: none;
  transition: opacity 0.25s ease; /* the era peek fades softly */
  order: 0; /* no captions here, so nothing sinks below its partner */
}

/* The top piece keeps its natural height; the bottom piece takes
   whatever room is left and crops its own lower edge to fit, so
   every era shares the same gap and never spills off the stage */
.stage-page figure:first-child {
  flex: 0 0 auto;
}

.stage-page figure:last-child {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.stage-page figure:last-child img {
  height: 100%;
  object-fit: cover;
  object-position: top;
}

/* While a peeked version is on show, the usual occupant of the
   stage waits in the wings */
.stage-media.era-stood-down {
  opacity: 0;
  visibility: hidden;
}

/* Little time machines woven into the story: a highlighter tint
   invites the cursor, and while it rests there the stage shows
   that version of the page */
.paper .u-wavy[data-era],
.paper .u-wavy[data-peek] {
  padding: 1px 4px 3px;
  margin: 0 -2px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 20' preserveAspectRatio='none'%3E%3Cpath d='M0.6 6.2 C10 1.9 26 4.4 44 2.6 C62 0.8 80 4.8 98 2.4 C107 1.2 114 3.8 119.4 2.2 L118.6 15.4 C108 19.2 92 15.4 74 17.6 C56 19.8 36 15.6 19 18.4 C11 19.7 4 17.2 0.9 18.6 Z' fill='rgba(90,130,210,0.22)'/%3E%3C/svg%3E") no-repeat center / 100% 88%;
  border-radius: 3px;
  box-decoration-break: clone; /* the tint wraps line breaks whole */
  -webkit-box-decoration-break: clone;
  cursor: default;
  transition: background 0.2s ease;
}

.paper .u-wavy[data-era]:hover,
.paper .u-wavy[data-era]:focus-visible,
.paper .u-wavy[data-peek]:hover,
.paper .u-wavy[data-peek]:focus-visible {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 20' preserveAspectRatio='none'%3E%3Cpath d='M0.6 6.2 C10 1.9 26 4.4 44 2.6 C62 0.8 80 4.8 98 2.4 C107 1.2 114 3.8 119.4 2.2 L118.6 15.4 C108 19.2 92 15.4 74 17.6 C56 19.8 36 15.6 19 18.4 C11 19.7 4 17.2 0.9 18.6 Z' fill='rgba(90,130,210,0.34)'/%3E%3C/svg%3E") no-repeat center / 100% 88%;
  outline: none;
}


body.design-dark::after {
  display: block; /* theme-plain hides it; this page keeps it */
  top: 0;
}

body.theme-dark .rail {
  background: rgba(20, 18, 16, 0.55);
  border-right-color: rgba(255, 255, 255, 0.14);
  box-shadow: none;
}

/* Cream paper slips would glare here — back to dark labels */
body.theme-dark .rail-link .tooltip,
body.theme-dark .rail-sub .tooltip {
  background: #262219;
  color: #ece7db;
  border-color: rgba(236, 231, 219, 0.2);
}

body.theme-dark .rail-link {
  color: rgba(236, 231, 219, 0.65);
}

body.theme-dark .rail-link:hover {
  background: rgba(236, 231, 219, 0.1);
  color: var(--ink);
}

body.theme-dark .rail-link.active {
  background: rgba(236, 231, 219, 0.14);
  color: var(--ink);
}

body.theme-dark .rail-group.active {
  background: rgba(236, 231, 219, 0.07);
}

body.theme-dark .sig-dots::before {
  background: rgba(236, 231, 219, 0.35);
}

body.theme-dark .sig-dots:hover::before {
  background: rgba(236, 231, 219, 0.65);
}

body.theme-dark .sig-dots.active::before {
  background: var(--ink);
}

body.theme-dark .sig-bars::before {
  background: rgba(236, 231, 219, 0.35);
}

body.theme-dark .sig-bars:hover::before {
  background: rgba(236, 231, 219, 0.65);
}

body.theme-dark .sig-bars.active::before {
  background: rgba(236, 231, 219, 0.95);
}

body.theme-dark .sig-roman .sig {
  color: rgba(236, 231, 219, 0.45);
}

body.theme-dark .sig-roman:hover .sig {
  color: rgba(236, 231, 219, 0.75);
}

body.theme-dark .sig-roman.active .sig {
  color: var(--ink);
}

body.theme-dark .paper a {
  color: var(--ink);
}

body.theme-dark .img-placeholder {
  background: rgba(236, 231, 219, 0.06);
  border-color: rgba(236, 231, 219, 0.3);
}

/* ============================================================
   Scroll marks — one small bar per section, right edge, centred.
   Injected by js/main.js on pages whose NAV group has `panel`.
   ============================================================ */

.scroll-marks {
  position: fixed;
  right: 22px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.scroll-marks a {
  position: relative;
  width: 28px;
  height: 10px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

/* Thin rules, white over the painting: the stop you're in draws
   itself out full and bright */
.scroll-marks a::before {
  content: "";
  width: 18px;
  height: 1.5px;
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: 0 0 3px rgba(35, 38, 43, 0.28);
  transition: width 0.18s ease, background 0.18s ease;
}

.scroll-marks a:hover::before {
  background: rgba(255, 255, 255, 0.85);
}

.scroll-marks a.active::before {
  width: 28px;
  height: 2px;
  background: #fff;
}

/* On the dark project page they warm to the paper's own cream */
body.theme-dark .scroll-marks a::before,
body.design-dark .scroll-marks a::before {
  background: rgba(236, 231, 219, 0.3);
  box-shadow: none;
}

body.theme-dark .scroll-marks a:hover::before,
body.design-dark .scroll-marks a:hover::before {
  background: rgba(236, 231, 219, 0.7);
}

body.theme-dark .scroll-marks a.active::before,
body.design-dark .scroll-marks a.active::before {
  background: #ece7db;
}

/* A long run (the home page's sixteen) packs closer than a short one */
.scroll-marks.long {
  gap: 7px;
}

/* Section name floats in from the left of the bar on hover */
.scroll-marks .tooltip {
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%) translateX(4px);

  background: var(--tooltip-bg);
  color: #f5f2e8;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11.5px;
  line-height: 1;
  white-space: nowrap;
  padding: 7px 10px;
  border-radius: 7px;
  border: 1px solid rgba(236, 231, 219, 0.2);

  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.scroll-marks a:hover .tooltip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

@media (max-width: 1100px) {
  .scroll-marks {
    display: none;
  }
}

/* ============================================================
   The paper card — the "book page"
   ============================================================ */

/* No box: the text floats directly on the painting, in a narrow
   column that starts right beside the navigation rail and simply
   keeps flowing as you scroll. */
.page {
  position: relative;
  z-index: 1;
  margin-left: calc(var(--rail-width) + 72px);
  min-height: 100vh;
  padding: 14vh 40px 24vh;
}

.paper {
  width: 100%;
  /* the glass sheet is 500px wide with the text 40px from its left
     edge; 420 leaves the same 40px on the right */
  max-width: 420px;
  line-height: 1.78;

  animation: rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .paper {
    animation: none;
  }
}

/* ============================================================
   Editorial typography
   ============================================================ */

/* Anchored sections land with breathing room, not glued to the top */
.paper section {
  scroll-margin-top: 90px;
}

/* Headings sit in the text at body size, only a little heavier,
   the way a newspaper marks its sections */
.paper h1 {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.2px;
  margin-bottom: 44px;
}

.paper h2 {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.2px;
  margin-top: 96px;
  margin-bottom: 40px;
}

/* A quiet note that sits on the same line as a section heading */
.h2-note {
  margin-left: 10px;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-soft);
}

.paper p {
  margin-bottom: 32px;
}

.paper p:last-child {
  margin-bottom: 0;
}

/* Links: ink text, white underline, white arrow at the end */
.paper a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 0.5px;
  text-decoration-color: var(--mark-soft);
  /* an unbroken rule: descenders don't cut gaps into it */
  text-decoration-skip-ink: none;
  white-space: nowrap; /* the arrow never wraps away from its word */
  transition: text-decoration-color 0.18s ease;
}

.paper a:hover {
  text-decoration-color: var(--mark);
}

.paper a::after {
  content: "";
  display: inline-block;
  width: 0.52em;
  height: 0.52em;
  margin-left: 0.14em;
  vertical-align: 0.28em; /* rides above the baseline, like a mark */
  background: var(--mark);
  opacity: 1;
  /* hairline arrow, the same weight as the underline */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.paper a:hover::after {
  opacity: 1;
  transform: translate(1px, -1px); /* it leans out of the page */
}

/* The card is a row, not a word: the rule and arrow belong to its
   title instead (see .post-title below) */
.paper .post-card,
.paper .footnote-ref {
  text-decoration: none;
}

.paper .post-card::after,
.paper .footnote-ref::after {
  content: none;
}

/* A footnote marker: a raised number in full ink — small, but
   dark enough to register as a mark */
.footnote-ref,
.footnote-num {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px; /* fixed, so both marks match across type sizes */
  font-weight: 600;
  vertical-align: 0.72em;
  color: var(--ink);
}

.footnote-ref {
  margin-left: 0.12em;
  transition: opacity 0.18s ease;
}

.footnote-ref:hover {
  opacity: 0.6;
}

/* Drop cap for the opening paragraph of an editorial page — cut
   newspaper style: two lines tall, flush with the column's grid */
.dropcap::first-letter {
  float: left;
  font-size: 56px;
  line-height: 0.74;
  padding: 9px 9px 0 0;
  font-weight: 400;
}

/* Browsers with real drop-cap support size and align it exactly:
   cap top on the first line, baseline on the second */
@supports (initial-letter: 2) or (-webkit-initial-letter: 2) {
  .dropcap::first-letter {
    float: none;
    font-size: unset;
    line-height: unset;
    padding: 0;
    margin-right: 9px;
    -webkit-initial-letter: 2;
    initial-letter: 2;
  }
}

/* Small quiet note, like a caption in a book margin — upright and
   a step darker, so it reads effortlessly over the painting */
.aside-note {
  color: var(--ink);
  font-size: 16.5px;
  opacity: 0.85;
}

/* Scrollytelling: the text reads on like a book in its column,
   while the visual stage on the right carries the pictures — the
   hero of the page — swapping as each chapter scrolls past */
.chapter-step {
  margin-top: 120px; /* breathing room, without forcing one/screen */
}

/* One sheet at a time: on the Design page the story reads like
   slides, not a letter. Nearly a full screen between chapters, so
   only one paragraph shares the screen with its asset. */
body.design-dark .chapter-step {
  margin-top: 90vh;
}

/* Enough floor below the last chapter that it too can rest in the
   middle of the screen before the page hands over to Inspirations */
body.design-dark .page {
  padding-bottom: 55vh;
}

/* Each scroll settles a chapter in the middle of the screen: a
   longer block simply starts higher, so the whole page of text
   reads centred beside its visual */
:root:has(body.design-dark) {
  scroll-snap-type: y proximity;
}

/* Only the paragraph paired with the visual on stage is in ink;
   the rest wait as ghosts (js/main.js sets .step-active) */
body.design-dark .paper [data-visual] {
  opacity: 0.12;
  transition: opacity 0.5s ease;
  scroll-snap-align: center;
}

body.design-dark .paper [data-visual].step-active {
  opacity: 1;
}

/* A wordless beat in the story: a sliver of height keeps its
   margins from collapsing into the next step's, so the stage gets
   a full turn with no new text */
.step-mark {
  height: 1px;
}

/* A second shelf inside a section ("Next on the list."): the same
   voice as the note above it, only closer, so the two lists read
   as one section rather than two */
.next-note {
  margin-top: 28px;
}

/* The tools shelf follows a whole list of its own, so it needs the
   air a new subject deserves */
.tools-note {
  margin-top: 64px;
}

/* End credits: the last thing on the last page, centred and small,
   the way a film signs off over its final frame */
.credits {
  margin-top: 140px;
  padding-bottom: 20vh;
  text-align: center;
}

.credit-name {
  font-size: 17px;
  color: var(--ink);
  margin-bottom: 18px;
}

/* The credits speak in the site's own label voice: small Inter
   capitals in quiet grey, the same as every note in the margins */
.credit-line {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-top: 10px;
}

/* The build's own line, spoken in the machine's typeface */
.credit-published .mono {
  font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.92em;
  letter-spacing: 0.4px;
  text-transform: none;
}

.chapter-step b {
  font-weight: 600;
}

.chapter-num {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11px;
  color: var(--ink-soft);
  margin-right: 10px;
}

.closing {
  margin-top: 120px;
  padding-top: 26px;
  border-top: 1px solid var(--hairline);
  font-size: 16.5px;
  color: var(--ink-soft);
}

/* The stage: pinned in the open space to the right of the column */
.stage {
  position: fixed;
  top: 18vh; /* the shared start line: chapters snap here too */
  left: 640px; /* clear of the 440px text column and its margins */
  right: 3vw;
  max-width: 920px;
  margin: 0 auto; /* centred in whatever space remains */
  height: 76vh;
  z-index: 1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}

.stage.visible {
  opacity: 1;
}

/* Each visual, crossfading in as its chapter arrives */
.stage-media {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed rgba(236, 231, 219, 0.25);
  border-radius: 14px;
  background: rgba(236, 231, 219, 0.05);
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-soft);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.stage-media.active {
  opacity: 1;
  transform: none;
}

/* The open space disappears on narrow windows, and the stage with it */
@media (max-width: 1100px) {
  .stage {
    display: none;
  }
}

/* "(git says: updated 2 days ago)" — a machine's aside inside
   the sentence */
.updated {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Model names: the serif line continues, only the voice shifts —
   a shade lighter and slightly spaced, like a proper noun said
   a little more precisely */
.mono {
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* A hand-drawn wavy underline in turned-down ink, sister of the
   section divider */
.u-wavy {
  padding-bottom: 6px;
  /* the wave starts and ends at the same height, so tiles join
     into one continuous line instead of breaking every repeat */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 6' preserveAspectRatio='none'%3E%3Cpath d='M0 3 Q6 0.9 12 3 T24 3' stroke='%2323262b' stroke-opacity='0.6' stroke-width='0.8' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x left bottom / 24px 6px;
}

/* TechEquity Ai as one quiet section row: small photo, name, and
   the numbers said plainly — the wallpaper picker's language. */
.post-note-title {
  margin-top: 40px;
}

.post-card {
  display: flex;
  align-items: center;
  gap: 14px;
  /* as wide as the site rows' hover glow, so their edges agree */
  width: calc(100% + 20px);
  margin: 14px -10px 0;
  padding: 10px 14px 10px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.16);
  text-decoration: none;
  transition: background 0.2s ease;
}

.post-card:hover {
  background: rgba(255, 255, 255, 0.3);
}

.post-card img {
  width: 92px;
  height: 62px;
  object-fit: cover;
  border-radius: 6px;
  flex-shrink: 0;
}

.post-card .post-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1; /* reaches the card's inner right edge... */
  position: relative; /* ...where the title's arrow lines up */
}

/* The title carries the site's link marks: hairline rule, small
   arrow — so the row reads as a link like any other */
.post-card .post-title {
  align-self: flex-start;
  /* the site rows' serif voice, so the card reads as their kin */
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 17px;
  font-weight: 400;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 0.5px;
  text-decoration-color: var(--mark-soft);
  text-decoration-skip-ink: none;
  transition: text-decoration-color 0.18s ease;
}

.post-card:hover .post-title {
  text-decoration-color: var(--mark);
}

.post-card .post-title::after {
  content: "";
  display: inline-block;
  width: 0.75em;
  height: 0.75em;
  /* on the arrows' shared vertical rule, level with the title */
  position: absolute;
  right: 10px;
  top: 8px;
  background: var(--ink);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: transform 0.18s ease;
}

.post-card:hover .post-title::after {
  transform: translate(1px, -1px);
}

.post-card .post-sub {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* Places I worked: names link out, the place stays quiet beside them */
.site-list-note {
  margin-top: 40px;
  scroll-margin-top: 90px; /* the fold band doesn't cover it on jump */
}

/* The note's own number, matching the marker up in the text */
.footnote-num {
  margin-right: 0.5em;
}

.site-list {
  list-style: none;
  margin-top: 10px;
}

.site-list li {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 0;
}

/* Each site's own favicon, like a tab strip in miniature */
.site-icon {
  width: 15px;
  height: 15px;
  border-radius: 3px;
  flex-shrink: 0;
}

.site-list a {
  font-size: 16px;
  /* the one-line rule: a title that cannot fit trails off with an
     ellipsis instead of folding, and the label keeps its column */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Every row's arrow leaves its word and lines up on one quiet
   vertical rule, just inside the sheet's right padding, riding
   the same line as its text. The whole row is the link, and it
   lights up like the post card so each line reads as one unit. */
.site-list li {
  position: relative;
  padding: 9px 44px 9px 10px; /* the right side belongs to the arrow */
  margin: 0 -10px;
  border-radius: 10px;
  transition: background 0.2s ease;
}

.site-list li:hover {
  background: rgba(255, 255, 255, 0.3);
}

.site-list a::before {
  content: "";
  position: absolute;
  inset: 0; /* the click reaches every corner of the row */
}

.site-list a::after {
  position: absolute;
  right: 24px;
  top: 50%;
  width: 0.66em;
  height: 0.66em;
  margin-left: 0;
  background: var(--ink); /* full ink, like the words it serves */
  transform: translateY(-50%);
}

.site-list li:hover a::after {
  transform: translate(1px, calc(-50% - 1px)); /* the same lean */
}

.site-list li:hover a {
  text-decoration-color: var(--mark);
}

/* The label keeps to its own right-hand column, just shy of the
   arrows, so every row aligns on the same two quiet edges */
.site-list span {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-left: auto;
  padding-left: 12px; /* never quite touches the title */
  text-align: right;
  white-space: nowrap;
}

/* Songs read as one phrase: the title and who made it share the same
   voice, with only a hairline of ink between them. The grey column
   turns into the year, and the record it came on rides beside it. */
/* The title is what the reader came for, so it keeps its words to the
   last; when the line runs out it is the name that trails off. */
.song-list a {
  display: flex;
  align-items: baseline;
  white-space: nowrap;
  text-decoration: none; /* the title span draws its own rule */
}

/* Only the title is the link's face: the credit that follows it
   carries no rule, so the eye lands on the name alone */
.song-list a em {
  font-style: normal;
  font-size: 0.85em; /* a step down from the title it follows */
  color: var(--ink-soft);
  /* the name yields first: it shrinks far more readily than the title */
  flex: 0 100 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: none;
}

/* The title keeps every letter while there is room; only when it alone
   outruns the line does it trail off too, rather than spill past. */
.song-list a > span.t {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  /* the same hairline every other row wears (.paper a, below) */
  text-decoration: underline;
  text-decoration-color: var(--mark-soft);
  text-decoration-thickness: 0.5px;
  text-underline-offset: 3px;
}

.song-list li:hover a > span.t {
  text-decoration-color: var(--mark);
}

/* the title span is part of the sentence, not one of the grey labels
   the sibling rule styles, so it takes the link's own voice back */
.song-list a > span.t {
  font-family: inherit;
  font-size: inherit;
  text-transform: none;
  color: inherit;
  letter-spacing: normal;
  margin-left: 0;
  padding: 0;
  text-align: left;
}

/* flex eats the space between the words, so the dash carries its
   own air on both sides */
.song-list a em::before {
  /* the hyphen, not a dash: EB Garamond keeps the pen's tilt in
     this one mark, its right end lifting the way it would on
     paper. It is a short stroke, so it carries wider air. */
  content: "-";
  margin: 0 0.52em 0 0.56em;
  color: var(--ink-soft);
}

.song-list li {
  padding-right: 92px; /* the year, the sleeve, then the arrow */
}

/* A song-list with no sleeves gives that column back to the words */
.song-list.no-cover li {
  padding-right: 44px;
}

/* The year keeps a narrow fixed column so it never crowds the sleeve
   and never steals width from the words */
.song-list span {
  padding-left: 14px;
  padding-right: 4px;
}

/* A row with no year (the podcasts) still needs its cover pushed to
   the same rule, so the artwork column never wanders */
.song-list li > a:not(:has(~ span)) {
  margin-right: auto;
}

.song-cover {
  position: absolute;
  right: 48px;
  top: 50%;
  width: 26px;
  height: 26px;
  transform: translateY(-50%);
  border-radius: 3px;
  object-fit: cover;
  box-shadow: 0 1px 3px rgba(35, 38, 43, 0.18);
}

/* The shortest shelf of all: names set as one sentence, wrapping like
   prose. Each keeps the site's underline, but no row, no arrow. */
.name-line {
  margin-top: 12px;
  font-size: 16px;
  line-height: 2;
  color: var(--ink);
}

/* no arrows here: seven of them would turn a sentence into a list */
.name-line a::after {
  content: none;
}

.name-line a {
  text-decoration-color: var(--mark-soft);
}

.name-line a:hover {
  text-decoration-color: var(--mark);
}

/* A minor shelf: places that only need a mark and a name, three to a
   row so the list reads as a small block rather than a long column */
.hq-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px 8px;
  margin: 12px -8px 0;
}

.hq-cell {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 8px;
  border-radius: 8px;
  min-width: 0;
  transition: background 0.2s ease;
}

.hq-cell:hover {
  background: rgba(255, 255, 255, 0.3);
}

.hq-cell img {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  flex: none;
}

.hq-cell span {
  font-size: 16px; /* the same voice as every other row */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The arrow leaves the name and rides the cell's own right edge, the
   same size and weight it has on every list row */
.hq-cell {
  position: relative;
  padding-right: 26px;
}

.paper .hq-cell::after {
  position: absolute;
  right: 8px;
  top: 50%;
  /* 0.75em of the list's 16px, held in place so the smaller name
     here doesn't shrink the mark below the rows' */
  width: 12px;
  height: 12px;
  margin-left: 0;
  background: var(--ink);
  transform: translateY(-50%);
}

.paper .hq-cell:hover::after {
  transform: translate(1px, calc(-50% - 1px)); /* the same lean */
}

/* Sections part with quiet air instead of a drawn rule */
.paper section + section {
  margin-top: 96px;
}

/* A shelf too short for a list: two columns of quiet cells, the
   site rows' hover glow and arrow language kept intact */
.shelf-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 4px 16px;
  margin: 14px -10px 0;
}

.paper .shelf-cell {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 10px; /* the label rides beside the name, not beneath it */
  padding: 9px 44px 9px 10px; /* the right side belongs to the arrow */
  border-radius: 10px;
  text-decoration: none;
  transition: background 0.2s ease;
}

.paper .shelf-cell:hover {
  background: rgba(255, 255, 255, 0.3);
}

.shelf-name {
  display: flex;
  align-items: center;
  gap: 8px; /* room for a favicon riding along */
  font-size: 16px;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 0.5px;
  text-decoration-color: var(--mark-soft);
  text-decoration-skip-ink: none;
  transition: text-decoration-color 0.18s ease;
}

.paper .shelf-cell:hover .shelf-name {
  text-decoration-color: var(--mark);
}

/* The label follows the name it belongs to, a step behind it, rather
   than drifting off to a column of its own */
.shelf-note {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* The same ink arrow the rows use, on the same rule: 24px in from
   the cell's right edge, exactly as .site-list a::after sits */
.paper .shelf-cell::after {
  content: "";
  position: absolute;
  right: 24px;
  top: 50%;
  margin-top: -0.38em;
  width: 0.75em;
  height: 0.75em;
  background: var(--ink);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: transform 0.18s ease;
}

.paper .shelf-cell:hover::after {
  transform: translate(1px, -1px); /* the same lean */
}

/* The name holds its words; if a cell runs short the label yields */
.shelf-name {
  flex: none;
}

/* ============================================================
   Lists of things: projects, books, movies, painters
   ============================================================ */

.entry {
  margin-bottom: 72px;
}

.entry:last-child {
  margin-bottom: 0;
}

.entry h3 {
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.5px;
  margin-bottom: 8px;
}

/* The small caps date line under any title, on every page */
.paper .meta {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 16px;
}

/* Grey placeholder block where a project image will go */
.img-placeholder {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: rgba(35, 38, 43, 0.08);
  border: 1px dashed rgba(35, 38, 43, 0.25);
  border-radius: 3px;
  margin-top: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ============================================================
   Quotes page — epigraph style
   ============================================================ */

/* Quotes read exactly like the body text above — same size, same
   rhythm — until the cursor rests on one and a highlighter runs
   through it, the way you would mark a line in a borrowed book */
.quote {
  margin-bottom: 32px;
}

.quote:last-child {
  margin-bottom: 0;
}

.quote blockquote {
  margin-bottom: 6px;
}

.quote blockquote span {
  /* the pen rests at zero width on the left, then draws across. The
     mark is a drawn shape rather than a block, so its edges wander
     the way a hand does and the ends are not quite square. */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 20' preserveAspectRatio='none'%3E%3Cpath d='M0.6 6.2 C10 1.9 26 4.4 44 2.6 C62 0.8 80 4.8 98 2.4 C107 1.2 114 3.8 119.4 2.2 L118.6 15.4 C108 19.2 92 15.4 74 17.6 C56 19.8 36 15.6 19 18.4 C11 19.7 4 17.2 0.9 18.6 Z' fill='rgba(90,130,210,0.3)'/%3E%3C/svg%3E")
    no-repeat left center / 0% 82%;
  padding: 1px 3px;
  margin: 0 -3px;
  border-radius: 2px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  transition: background-size 0.55s cubic-bezier(0.22, 0.9, 0.3, 1);
}

.quote:hover blockquote span {
  background-size: 100% 82%;
}

.quote cite {
  font-style: normal;
  color: var(--ink-soft);
  transition: color 0.3s ease;
}

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

/* ============================================================
   Right loupe panel — magnify the pointillism
   ============================================================ */

/* The placard: a museum wall label in glass, resting in the
   bottom-right corner. The label (title, artist, icon row) is its
   constant face; choosing a tool grows the card upward. */
.loupe-panel {
  position: fixed;
  right: 16px;
  bottom: 16px;
  width: max(282px, 19vw);
  max-height: calc(100vh - 32px);
  z-index: 10;

  display: flex;
  flex-direction: column;
  overflow: hidden; /* clips children to the rounded corners */

  /* Cut from the same glass as the letter, and squared off like it:
     one ink hairline round the edge, the way the menus are drawn */
  background: rgba(252, 253, 255, 0.52);
  -webkit-backdrop-filter: blur(18px) saturate(1.35);
  backdrop-filter: blur(18px) saturate(1.35);
  border: 1px solid rgba(35, 38, 43, 0.32);
  border-radius: 0;
  box-shadow:
    0 14px 34px rgba(22, 28, 38, 0.2),
    inset 1px 0 0 rgba(255, 255, 255, 0.5),
    inset -1px 0 0 rgba(255, 255, 255, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  transition: box-shadow 0.3s ease;
}

.loupe-panel:hover {
  box-shadow:
    inset 1px 1px 0 rgba(255, 255, 255, 0.6),
    inset -1px -1px 0 rgba(255, 255, 255, 0.35),
    0 18px 44px rgba(22, 28, 38, 0.3);
}

/* The drawer above the label: collapsed to nothing until a tool is
   chosen, then it grows to fit that tool's controls */
.tool-drawer {
  display: grid;
  grid-template-rows: 0fr;
  min-height: 0;
  transition: grid-template-rows 0.45s cubic-bezier(0.22, 0.9, 0.3, 1);
}

.loupe-panel.open .tool-drawer {
  grid-template-rows: 1fr;
  border-bottom: 1px solid rgba(85, 86, 90, 0.16);
  box-shadow: 0 1px 0 rgba(251, 251, 249, 0.22);
}

.tool-drawer-inner {
  min-height: 0;
  overflow: hidden;
}

.loupe-panel.open .tool-drawer-inner {
  overflow-y: auto;
}

/* One tool at a time inside the popover */
.tool-section {
  display: none;
}

.tool-section.active {
  display: block;
}

/* ----- The icon row at the placard's foot: the nav rail's square
   buttons and hover language, laid sideways inside the card ----- */
.loupe-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 5px 8px;
  border-top: none;
  flex-shrink: 0;
}

/* The rail's menu language, laid sideways: square cells, a plain
   fill on hover, and the tool in use held in a thin ink rule */
.bar-tool {
  width: 33px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  color: rgba(86, 92, 102, 0.85);
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease,
    box-shadow 0.15s ease;
}

.bar-tool svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 1.3;
  fill: none;
  stroke-linecap: butt;   /* square ends, the old plotter look */
  stroke-linejoin: miter;
}

.bar-tool:hover {
  background: rgba(255, 255, 255, 0.5);
  color: var(--ink);
  transform: none;
}

/* the pressed state is said once, at the foot of this file, in the
   rail's own bevel */

/* The label itself: artwork title and artist on a brighter pane of
   glass, with the icon row beneath */
/* The placard reads like the menus on the rail: an opaque white
   card in a hard ink rule, the painting's name set in it */
.loupe-intro {
  position: relative;
  margin: 0;
  padding: 10px 15px 11px;
  background: #fff;
  border: none;
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
}

.loupe-artwork {
  font-size: 13px;
  font-style: italic;
  line-height: 1.35;
  color: var(--ink);
}

.loupe-artist {
  margin-top: 3px;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 7.8px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Title bar, a slightly denser strip of the glass */
.loupe-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 15px;
  /* the very glass the letter's title bar is poured from */
  background: linear-gradient(
    180deg,
    rgba(226, 238, 251, 0.85) 0%,
    rgba(183, 210, 240, 0.55) 46%,
    rgba(158, 193, 231, 0.35) 52%,
    rgba(198, 221, 245, 0.55) 100%
  );
  border-top: 1px solid rgba(70, 105, 150, 0.45);
  border-bottom: 1px solid rgba(70, 105, 150, 0.45);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
  transition: background 0.2s ease;
}

/* The section under the cursor lights up like touched glass */
.tool-section:hover > .loupe-header {
  background: rgba(255, 255, 255, 0.5);
}

.loupe-header svg {
  width: 11px;
  height: 11px;
  stroke: #3a5a82;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: round;
  flex-shrink: 0;
}

.loupe-title {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: #3a5a82;
}

.loupe-zoom-label {
  margin-left: auto;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--ink-soft);
}

.loupe-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 14px;
}

/* The magnified view */
.loupe-view {
  width: 100%;
  aspect-ratio: 1 / 1; /* a big square lens, no controls around it */
  background-repeat: no-repeat;
  background-color: #e9edf1;
  border: 1px solid var(--warm-edge);
  border-radius: 6px;
  box-shadow: 0 6px 18px var(--shadow-warm);
}

/* One quiet line instead of a zoom slider */
.loupe-hint {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9.5px;
  letter-spacing: 0.4px;
  color: var(--ink-soft);
  text-align: center;
}

/* Minimal control row: "LABEL 4.0" on top, full-width slider below */
.loupe-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 6px;
}

.loupe-row[hidden] {
  display: none; /* flex above would otherwise defeat hidden */
}

.loupe-row-label {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Minimal slider: hairline track, one small dot as the knob */
.loupe-slider {
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  height: 1px;
  background: rgba(35, 38, 43, 0.2);
  outline: none;
}

.loupe-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #6f6a60;
  border: none;
  cursor: pointer;
}

.loupe-slider::-moz-range-thumb {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #6f6a60;
  border: none;
  cursor: pointer;
}

/* The value, quietly beside the label */
.loupe-val {
  margin-left: 5px;
  color: var(--ink);
  letter-spacing: 0.5px;
  font-variant-numeric: tabular-nums;
}

/* Effects section: live preview tiles, like a filter gallery */
.fx-previews {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px 8px;
}

.fx-tile {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 4px 4px 6px;
  background: none;
  border: none;
  border-radius: 9px;
  cursor: pointer;
  transition: background 0.18s ease;
}

/* Selection speaks the same white-chip language as the gallery
   rows and the toolbar buttons */
.fx-tile:hover {
  background: rgba(255, 255, 255, 0.4);
}

.fx-tile.active {
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 2px 8px rgba(22, 28, 38, 0.1);
}

.fx-tile canvas {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid rgba(35, 38, 43, 0.12);
  border-radius: 5px;
  transition: transform 0.15s ease;
}

.fx-tile:hover canvas {
  transform: translateY(-1px);
}

/* Wallpaper picker: one clear row per painting — thumbnail, artist,
   title and year, oldest first. The current one sits highlighted. */
.gallery-choices {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.gallery-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: none;
  text-align: left;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease;
}

.gallery-row.active {
  background: rgba(255, 255, 255, 0.5);
  border-color: transparent;
  box-shadow: none;
}

.gallery-row img {
  width: 56px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid rgba(35, 38, 43, 0.12);
  border-radius: 5px;
  flex-shrink: 0;
}

.gallery-row .g-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0; /* lets the title line ellipsize */
}

.gallery-row .g-artist {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink);
}

.gallery-row .g-title {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9.5px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


.gallery-row .g-check {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  stroke: var(--ink);
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transition: opacity 0.18s ease;
}

.gallery-row.active .g-check {
  opacity: 1;
}

.fx-tile span {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 8.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

.fx-tile.active span {
  color: var(--ink);
  font-weight: 500;
}

/* Palette section: a display, not a picker. The band shows the
   painting's composition at a glance — each colour as wide as its
   share — and the list beneath reads like a spec sheet. */
/* A bento of squares: the three most-used colours large (2×2),
   the other four small (1×1) — 4×4 grid, perfectly packed. Size
   alone says what the painting is made of. */
.palette-bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  margin-bottom: 8px;
}

.palette-bento span {
  display: block;
  aspect-ratio: 1;
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 9px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
  cursor: pointer;
  transition: transform 0.15s ease;
}

.palette-bento span.big {
  grid-column: span 2;
  grid-row: span 2;
  border-radius: 12px;
}

.palette-bento span:hover {
  transform: translateY(-1px);
}

.palette-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.palette-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 5px;
  border: none;
  border-radius: 6px;
  background: none;
  cursor: pointer;
  text-align: left;
}

.palette-row:hover {
  background: rgba(255, 255, 255, 0.35);
}

.row-swatch {
  width: 13px;
  height: 13px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 4px;
  flex-shrink: 0;
}

.row-hex {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.row-share {
  margin-left: auto;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 9.5px;
  color: var(--ink);
}

/* Full-screen canvas that re-paints the painting as dots.
   Sits on the same visual layer as the painting; fades in only
   when the Dots slider is above 0. */
.dots-canvas {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.dots-canvas.visible {
  opacity: 1;
}

/* Composition guides: white golden-ratio lines that sweep
   themselves over the painting (built by js/loupe.js) */
.grid-overlay {
  position: fixed;
  inset: 0;
  z-index: -1; /* under the reading sheet, over the painting */
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
}

.grid-overlay.visible {
  opacity: 1;
}

.grid-overlay path {
  stroke: rgba(255, 255, 255, 0.92);
  stroke-width: 1;
  fill: none;
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.4));
  transition: stroke-dashoffset 1.4s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.grid-overlay path.spiral {
  stroke-width: 1.5; /* the spiral leads, slightly heavier */
  transition-duration: 2s;
}

/* The viewfinder frame that follows the mouse over the painting */
.loupe-box {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 11;
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 0 0.5px rgba(35, 38, 43, 0.3);
  pointer-events: none;
}

/* On narrower screens the loupe would crowd the reading column */
@media (max-width: 1100px) {
  .loupe-panel,
  .loupe-box,
  .loupe-bar,
  .dots-canvas,
  .grid-overlay {
    display: none;
  }
}

/* ============================================================
   Small screens — rail becomes a bottom bar
   ============================================================ */

@media (max-width: 720px) {
  /* Text spans the whole screen on mobile, so the pillar does too */
  body::after {
    top: 0;
    left: 0;
    width: auto;
    right: 0;
    background: rgba(252, 253, 255, 0.72);
    box-shadow: none;
  }

  .pillar-shade {
    display: none;
  }

  .rail {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 52px;
    flex-direction: row;
    justify-content: center;
    gap: 4px;
    padding: 0 12px;
  }

  .rail-avatar {
    width: 28px;
    height: 28px;
    font-size: 12px;
  }

  .rail-nav,
  .rail-bottom {
    flex-direction: row;
    align-items: center;
    margin: 0;
    gap: 4px;
  }

  .rail-group {
    flex-direction: row;
    align-items: center;
    padding: 4px 8px;
    margin: 0;
  }

  .rail-subs {
    flex-direction: row;
    gap: 5px;
    margin: 0 0 0 6px;
  }

  .rail-nav {
    margin-left: 10px;
  }

  .rail-bottom {
    margin-left: 10px;
  }

  .rail-link .tooltip,
  .rail-sub .tooltip {
    display: none;
  }

  .page,
  body.theme-painting .page {
    margin-left: 0;
    padding: 12vh 28px 120px;
  }

  /* The rail is a bottom bar here, so the hero centres on the screen */
  .hero {
    padding-left: 0;
  }

  .hero-cue {
    left: 50%;
    bottom: 76px; /* clear the bottom bar */
  }

  .paper h1 {
    margin-bottom: 56px;
  }

}

/* ============================================================
   Poster wall — small movie posters gathered in the open space
   to the right of the shelves, beside the letter
   ============================================================ */

/* Each section's wall holds the open air beside the sheet, fixed
   like the Design page's stage, and only while its section is on
   screen (js/main.js raises .on); the letter scrolls on as one. */
.poster-wall {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  /* centred in the air right of the sheet's 592px edge */
  left: calc(50vw + 106px);
  width: 380px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}

.poster-wall.on {
  opacity: 1;
}

.poster-wall img {
  display: block;
  width: 100%;
  border-radius: 3px;
  box-shadow:
    0 2px 10px rgba(22, 28, 38, 0.24),
    0 1px 3px rgba(22, 28, 38, 0.14);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

/* The cover whose row is under the cursor leans forward a little */
.poster-wall img.lit {
  position: relative;
  z-index: 1;
  transform: scale(1.12);
  box-shadow:
    0 10px 26px rgba(22, 28, 38, 0.34),
    0 2px 6px rgba(22, 28, 38, 0.18);
}

/* Logo walls: transparent marks each rest on a small pane of the
   site's glass instead of standing raw on the painting */
.logo-wall span {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  padding: 22px;
  border-radius: 10px;
  background: rgba(252, 253, 255, 0.6);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
  box-shadow:
    0 2px 10px rgba(22, 28, 38, 0.24),
    0 1px 3px rgba(22, 28, 38, 0.14);
}

.logo-wall img {
  width: auto;
  max-width: 100%;
  max-height: 100%;
  border-radius: 0;
  box-shadow: none;
}

.logo-wall img.lit {
  box-shadow: none; /* the mark alone leans, its pane stays still */
}

/* The open space disappears on narrow windows, so the wall does too */
@media (max-width: 1100px) {
  .poster-wall {
    display: none;
  }
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(1) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='3.6'/%3E%3Cpath d='M4.8 20c.8-4 3.7-5.6 7.2-5.6s6.4 1.6 7.2 5.6'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(2) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 16.5V13c0-3.6 1.8-6.1 5-7.3'/%3E%3Cpath d='M4.5 16.5h3.6V12H4.5z'/%3E%3Cpath d='M13.5 16.5V13c0-3.6 1.8-6.1 5-7.3'/%3E%3Cpath d='M13.5 16.5h3.6V12h-3.6z'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(3) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20l1.6-4.8 3.2 3.2z'/%3E%3Cpath d='M6.6 13.6 16.2 4l3.2 3.2-9.6 9.6z'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(4) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.4 5.4c2.8-1.2 5.6-1.2 8.6.4v12.8c-3-1.6-5.8-1.6-8.6-.4z'/%3E%3Cpath d='M20.6 5.4c-2.8-1.2-5.6-1.2-8.6.4v12.8c3-1.6 5.8-1.6 8.6-.4z'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(5) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3 21 8H3z'/%3E%3Cpath d='M6 10v7M12 10v7M18 10v7'/%3E%3Cpath d='M3.5 20.5h17'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(6) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s6.6-6.2 6.6-11A6.6 6.6 0 0 0 5.4 10c0 4.8 6.6 11 6.6 11z'/%3E%3Ccircle cx='12' cy='9.8' r='2.4'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(7) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.4 8.6h17.2V20H3.4z'/%3E%3Cpath d='m3.6 8.6 1.2-4 16 1.6-.4 2.4'/%3E%3Cpath d='m8.4 4.9-1 3.7M13.6 5.4l-1 3.6'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(8) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18V5.6l9-1.8v12.4'/%3E%3Ccircle cx='6.8' cy='18' r='2.4'/%3E%3Ccircle cx='15.8' cy='16.2' r='2.4'/%3E%3C/svg%3E");
}

.rail-group:nth-child(1) .rail-sub:nth-of-type(9) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 8.5h8a5 5 0 0 1 4.6 6.9 2.6 2.6 0 0 1-4.5.7l-1.3-1.6H9.2l-1.3 1.6a2.6 2.6 0 0 1-4.5-.7A5 5 0 0 1 8 8.5z'/%3E%3Cpath d='M7.4 11.4v2.2M6.3 12.5h2.2'/%3E%3Ccircle cx='16' cy='12' r='.9'/%3E%3C/svg%3E");
}

.rail-group:nth-child(2) .rail-sub:nth-of-type(1) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='7' y='2.8' width='10' height='18.4' rx='2'/%3E%3Cpath d='M10.6 5.6h2.8'/%3E%3Cpath d='M10.6 18.6h2.8'/%3E%3C/svg%3E");
}

.rail-group:nth-child(2) .rail-sub:nth-of-type(2) {
  --sub-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.2l2 5.6 5.6 2-5.6 2-2 5.6-2-5.6-5.6-2 5.6-2z'/%3E%3Cpath d='M18.6 16.4l.8 2.2 2.2.8-2.2.8-.8 2.2-.8-2.2-2.2-.8 2.2-.8z'/%3E%3C/svg%3E");
}

/* The two projects are numbered, not pictured: roman figures set
   in the same button the tools wear */
.rail-group:nth-child(2) .rail-sub::before {
  -webkit-mask: none;
  mask: none;
  background: none;
  width: auto;
  height: auto;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11px;
  line-height: 1;
  color: #4a4d54;
  opacity: 0.75;
}

.rail-group:nth-child(2) .rail-sub:nth-of-type(1)::before {
  content: "I";
}

.rail-group:nth-child(2) .rail-sub:nth-of-type(2)::before {
  content: "II";
}

.rail-group:nth-child(2) .rail-sub.active::before {
  opacity: 1;
  color: #23262b;
}

.rail-group:nth-child(2) .rail-sub:nth-of-type(3)::before {
  content: "III";
}

.rail-group:nth-child(2) .rail-sub:nth-of-type(4)::before {
  content: "IV";
}

/* The letter's own update stamp: it simply reads as part of the
   sentence it ends */
.letter-stamp {
  white-space: nowrap;
}

/* The letter alone speaks in Garamond: the old-style face Apple's
   own Garamond descended from, a shade rounder and warmer than the
   Newsreader that runs the rest of the site. It sits small for its
   point size, so it takes a nudge up to match the measure. */
.letter p {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 16.5px;
  line-height: 1.74;
  letter-spacing: 0.1px;
}

body.text-large .letter p {
  /* +2 on the letter's 16.5: a 12% step, enough to feel pressed.
     (+1.5 lands under the ~10% a reader reliably notices, and a
     toggle that barely changes reads as broken.) The line-height
     eases so the line box grows with the letterforms, not faster. */
  font-size: 18.5px;
  line-height: 1.78;
}

/* Form controls and canvases do not inherit type by default, so the
   one face is handed to them explicitly */
button,
input,
select,
textarea,
canvas {
  font-family: inherit;
}

/* Books and films are printed tall, so their covers keep that shape;
   the square ones (records, podcasts, games) stay as they are */
#books .song-cover,
#movies .song-cover {
  width: 23px;
  height: 31px;
  right: 46px;
}

#books .song-list li,
#movies .song-list li {
  padding-right: 90px;
}



/* the icons' own tooltips stand down: the flyout says the names */
.rail-group:nth-child(1) .rail-sub .tooltip {
  display: none;
}

/* The Design group loses its well: the keys stand on the rail
   by themselves, with nothing drawn behind them. */
.rail-group:nth-child(1),
.rail-group:nth-child(2) {
  background: none;
  box-shadow: none;
}

/* Both signs keep the moulded key they always had: the same grey
   face as the numerals below them, nothing brighter. */
.rail-group:nth-child(1) .rail-link,
.rail-group:nth-child(2) .rail-link {
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.rail-group:nth-child(1).active .rail-link,
.rail-group:nth-child(2).active .rail-link,
.rail-group:nth-child(1) .rail-link.pressed,
.rail-group:nth-child(2) .rail-link.pressed {
  background: rgba(160, 160, 156, 0.42);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

/* ============================================================
   The tool panel, redrawn in the rail menu's language: an opaque
   white sheet, type at a size that can actually be read, and the
   row you have chosen carried on the same blue bar.
   ============================================================ */
.loupe-panel {
  /* the letter's own glass, poured at the same strength */
  background: rgba(252, 253, 255, 0.62);
  -webkit-backdrop-filter: blur(18px) saturate(1.35);
  backdrop-filter: blur(18px) saturate(1.35);
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 6px;
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.6),
    inset -1px -1px 0 rgba(255, 255, 255, 0.35),
    0 10px 30px rgba(22, 28, 38, 0.26);
}

/* the title strip keeps its blue glass but says its name plainly */
.loupe-title {
  font-size: 12px;
  letter-spacing: 0.6px;
  text-transform: none;
  color: #2c4a6e;
}

.loupe-header {
  padding: 8px 14px;
}

.loupe-header svg {
  width: 13px;
  height: 13px;
}

/* the rows: roomier, and named at the menu's size */
.gallery-row {
  gap: 11px;
  padding: 6px 9px;
  border-radius: 4px;
}

.gallery-row .g-artist {
  font-size: 13.5px;
  font-weight: 400;
  line-height: 1.35;
}

.gallery-row .g-title {
  font-size: 11.5px;
  color: #4a4d54;
  line-height: 1.35;
}

/* the painting in use takes the selection blue, as the menu does */
.gallery-row.active {
  background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
  box-shadow: none;
}

.gallery-row.active .g-artist,
.gallery-row.active .g-title {
  color: #fff;
}

.gallery-row.active .g-check {
  stroke: #fff;
}

/* The placard is set exactly as a shelf row is: the work's name at
   the row's own size, upright, and the painter after it a little
   smaller. No italic, no small capitals — the same two voices the
   films and books are listed in. */
.loupe-artwork {
  font-size: 16px;
  font-style: normal;
  line-height: 1.4;
  color: var(--ink);
}

.loupe-artist {
  margin-top: 1px;
  font-size: 13.6px;
  letter-spacing: 0.19px;
  line-height: 1.4;
  text-transform: none;
  color: var(--ink);
}

/* the rest of the panel's small print, brought up to a size that
   reads: the effect names, the slider labels, the hints */
.fx-tile span {
  font-size: 10.5px;
  letter-spacing: 0.5px;
  text-transform: none;
  color: #23262b;
}

.loupe-row-label,
.loupe-val,
.loupe-zoom-label {
  font-size: 11.5px;
  letter-spacing: 0.2px;
}

.loupe-hint {
  font-size: 11.5px;
  line-height: 1.5;
}

/* Lang and Size speak the same way: the running value on the blue,
   so the three panels answer each other down the rail. */
.rail-tools button.active {
  background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
  box-shadow: none;
  color: #fff;
}

.rail-tools button.active::before {
  color: #fff;
}

.rail-tools button:hover {
  background: rgba(90, 130, 210, 0.16);
}

.rail-tools button.active:hover {
  background: linear-gradient(180deg, #7ba0e5 0%, #5580d6 100%);
}

/* The panels take more of the rail's width: 48px inside the same
   52px column, so all four blocks stand on one pair of edges. */
.rail-group,
.rail-langs,
.rail-sizes,
.rail-bottom {
  width: 48px;
}

/* ============================================================
   The right edge carries the names now: each mark says its own
   section in white beside the rule, so the rail can stay quiet.
   The one you are reading brightens with its mark.
   ============================================================ */
.scroll-marks .tooltip {
  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  opacity: 1;
  color: rgba(255, 255, 255, 0.62);
  font-size: 11px;
  letter-spacing: 0.1px;
  text-shadow: 0 1px 3px rgba(20, 24, 30, 0.85);
  transition: color 0.18s ease;
}

.scroll-marks a:hover .tooltip {
  color: #fff;
}

.scroll-marks a.active .tooltip {
  color: #fff;
  font-style: italic;
}

/* the rows sit further apart, so the names have air */
.scroll-marks {
  gap: 14px;
}

/* The lit lower-right edge stays, but faint: enough to give the
   panel an edge, not so much that it draws the eye to the corner. */
.rail-group,
.rail-langs,
.rail-sizes {
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.32),
    inset -1px -1px 0 rgba(251, 251, 249, 0.26);
}

/* ============================================================
   Home's sections are three small signs in a column, nothing
   drawn round them: a figure, a thought, a pair of headphones.
   The one you are reading stands full; the others sit back.
   ============================================================ */
.rail-group:nth-child(1) .rail-subs {
  grid-template-columns: 1fr;
  gap: 5px;
  /* the signs stand clear of the portrait and below a hairline, the
     way a system menu rules off one group of items from the next */
  margin-top: 12px;
  padding-top: 12px;
  position: relative;
}

.rail-group:nth-child(1) .rail-sub {
  box-sizing: border-box;
  width: 100%;
  height: 21px;
  border: 0;
  border-radius: 4px;
  background: none;
  box-shadow: none;
  opacity: 0.55;
  transition: opacity 0.16s ease;
}

/* the drawn mark steps aside: the sign says it */
.rail-group:nth-child(1) .rail-sub::before {
  display: none;
}

.rail-group:nth-child(1) .rail-sub .sig {
  display: block;
  font-size: 15px;
  line-height: 1;
  filter: saturate(0.9);
}

.rail-group:nth-child(1) .rail-sub:hover {
  opacity: 0.85;
  background: none;
}

/* the section you are reading comes up whole */
.rail-group:nth-child(1) .rail-sub.active {
  opacity: 1;
  background: none;
  box-shadow: none;
}

/* The house stands bare like the signs beneath it, and the rail
   starts at the top rather than a third of the way down. */
.rail-group:nth-child(1) .rail-link,
.rail-group:nth-child(1) .rail-link:hover,
.rail-group:nth-child(1).active .rail-link,
.rail-group:nth-child(1) .rail-link.pressed {
  background: none;
  box-shadow: none;
}

.rail-nav {
  margin-top: 10px;
}

/* Home is her own face rather than a sign: a painted portrait in
   grey, cut to the rounded square a system icon is drawn in. No
   edge round it; it comes up whole on the page it opens. */
.rail-portrait {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  object-fit: cover;
  opacity: 0.78;
  transition: opacity 0.16s ease;
}

.rail-group:nth-child(1) .rail-link:hover .rail-portrait {
  opacity: 1;
}

.rail-group:nth-child(1).active .rail-portrait {
  opacity: 1;
}

/* Only two rules are drawn: one inside Home, parting the face from
   its signs, and one above the outside links at the foot. Both are
   inset from the panel's edge so they read as a menu's divider
   rather than a border. Design and Lang need none: the gap between
   the blocks already says where one ends. */
.rail-bottom {
  position: relative;
}

.rail-bottom::before {
  content: "";
  position: absolute;
  top: 0;
  left: 9px;
  right: 9px;
  height: 1px;
  background: rgba(85, 86, 90, 0.16);
  box-shadow: 0 1px 0 rgba(251, 251, 249, 0.22);
  pointer-events: none;
}

/* ---- one measure between blocks, top to bottom ---- */
.rail-nav {
  margin-top: 10px;
  margin-bottom: 0;
  gap: 14px;
}

.rail-group {
  margin-bottom: 0;
}

/* The settings are not part of the reading. They fall to the foot
   of the rail and sit just above the outside links, so the pages
   keep the top and the machinery keeps the bottom. */
.rail-tools {
  order: 2;
  margin-top: auto;
  gap: 14px;
  padding: 0 0 12px;
}

.rail-bottom {
  order: 3;
  margin-top: 0;
}

.rail-sizes {
  margin-top: 0;
}

.rail-bottom {
  padding-top: 12px;
}

/* Home's own divider, inset to the same measure as the one below */
.rail-group:nth-child(1) .rail-subs::before {
  content: "";
  position: absolute;
  top: 0;
  left: 9px;
  right: 9px;
  height: 1px;
  background: rgba(85, 86, 90, 0.16);
  box-shadow: 0 1px 0 rgba(251, 251, 249, 0.22);
  pointer-events: none;
}

/* Lang and Size keep their rows off the panel's edge, the way the
   keys in Design stand clear of theirs, so the selection bar has a
   margin to sit in rather than running to the wall. */
/* the rows take the whole of the panel they sit in, and the value
   is centred with its tick beside it rather than pushed right by a
   fixed indent */
.rail-tools button {
  margin: 0;
  width: 100%;
  padding: 0;
  justify-content: center;
  border-radius: 2px;
}

.rail-tools button.active::before {
  position: static;
  margin-right: 3px;
}

/* the settings stand in from both sides, narrower than the pages
   above them, so the machinery reads as a lesser thing */
.rail-langs,
.rail-sizes {
  align-self: center;
  margin-left: 0;
  width: 40px;
}

/* the portrait's box hugs the picture, so the rule below it sits
   the same twelve pixels clear as the one at the foot */
.rail-group:nth-child(1) .rail-link,
.rail-group:nth-child(1) .rail-link:hover,
.rail-group:nth-child(1).active .rail-link,
.rail-group:nth-child(1) .rail-link.pressed {
  height: 30px;
  margin-bottom: 0;
}

/* The header word is set larger so it can be read, and the panel
   opens further down so its rule never meets the selection bar. */
.rail-langs::before,
.rail-sizes::before {
  height: 15px;
  font-size: 8px;
  letter-spacing: 0.8px;
  color: #4a4b4f;
}

.rail-langs,
.rail-sizes {
  padding-top: 19px;
}

/* ============================================================
   The close is the traffic light as the Mac draws it now: a small
   flat disc of red held in a hairline, no dome, no shine. The ×
   arrives only under the cursor. It folds the sheet away and folds
   it back out.
   ============================================================ */
.pillar-shade .shade-close {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 11px;
  height: 11px;
  bottom: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  /* the Mac's red, poured as glass: light falls across the upper
     half and pools at the top edge, a hairline holds the rim, and
     the disc rests on the bar with the smallest of shadows */
  background: linear-gradient(180deg,
      rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.12) 38%,
      rgba(255, 255, 255, 0) 52%),
    linear-gradient(180deg, #ff746b 0%, #f95a50 50%, #e83e33 100%);
  box-shadow: inset 0 0.5px 0.5px rgba(255, 255, 255, 0.7),
    inset 0 -1px 1.5px rgba(140, 20, 12, 0.35),
    inset 0 0 0 0.5px rgba(130, 20, 12, 0.3),
    0 0.5px 1px rgba(70, 15, 10, 0.3);
}

.pillar-shade .shade-close::before {
  content: none;
}

.pillar-shade .shade-close svg {
  position: relative;
  z-index: 1;
  width: 6.5px;
  height: 6.5px;
  stroke: #5a0803;
  stroke-width: 2.6;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.pillar-shade .shade-close:hover svg {
  opacity: 1;
}

/* The placard is the one lit surface in the panel: a pale sheet of
   the same glass rather than solid paper, so the painting behind it
   still shows through. It is parted from what sits above and below
   by the rail's own engraved rule, held in from the edges the way a
   menu's divider is, and lit from underneath. */
.loupe-intro {
  background: rgba(255, 255, 255, 0.5);
  border-top: none;
  border-bottom: none;
}

/* only the rule above it is drawn: the tools below sit close enough
   that a second line just crowded them */
.loupe-intro::before {
  content: "";
  position: absolute;
  top: 0;
  left: 9px;
  right: 9px;
  height: 1px;
  background: rgba(85, 86, 90, 0.16);
  box-shadow: 0 1px 0 rgba(251, 251, 249, 0.22);
  pointer-events: none;
}

/* the rows take the rail's own hover tint, the same wash the
   settings rows use, rather than a white one of their own */
.gallery-row:hover {
  background: rgba(90, 130, 210, 0.16);
}

/* and the painting in use answers the cursor, as the running value
   does in Lang and Size */
.gallery-row.active:hover {
  background: linear-gradient(180deg, #7ba0e5 0%, #5580d6 100%);
}

/* the header strip keeps its Aqua blue, thinned so the glass reads
   through it */
.loupe-header {
  background: linear-gradient(180deg,
    rgba(226, 238, 251, 0.62) 0%,
    rgba(183, 210, 240, 0.4) 46%,
    rgba(158, 193, 231, 0.26) 52%,
    rgba(198, 221, 245, 0.4) 100%);
}

/* ============================================================
   The panel's controls answer the way the rail's keys do: resting
   on one raises it, choosing it presses it in and the sign rides
   the press. Every hard ink rule is gone; there are none in the
   rail either. The alphas are lighter than the rail's own, because
   this sits on blurred glass over a painting rather than on flat
   chrome, where the same value would read half again as heavy.
   ============================================================ */
.loupe-bar {
  background: rgba(255, 255, 255, 0.32);
}

.bar-tool {
  border-radius: 2px;
  transition: background 0.12s ease, color 0.12s ease,
    box-shadow 0.12s ease;
}

.bar-tool svg {
  transition: transform 0.12s ease;
}

.bar-tool:hover {
  background: rgba(90, 130, 210, 0.16);
  color: var(--ink);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.32);
}

.bar-tool.active {
  background: rgba(160, 160, 156, 0.28);
  color: var(--ink);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

.bar-tool.active svg {
  transform: translate(1px, 1px);
}

/* the effect tiles are toggles too, so they press rather than
   float: the panel had three ways of saying "chosen", now one */
.fx-tile {
  transition: background 0.12s ease, box-shadow 0.12s ease;
}

.fx-tile:hover {
  background: rgba(90, 130, 210, 0.16);
}

.fx-tile.active {
  background: rgba(160, 160, 156, 0.28);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

.gallery-row {
  transition: background 0.12s ease, border-color 0.12s ease;
}

/* the header lifts under the cursor instead of losing its blue */
.tool-section:hover > .loupe-header {
  background: linear-gradient(180deg,
    rgba(236, 244, 253, 0.72) 0%, rgba(196, 219, 245, 0.5) 46%,
    rgba(172, 203, 236, 0.34) 52%, rgba(210, 230, 248, 0.5) 100%);
}

/* the slider had no answer at all, and no ring for the keyboard */
.loupe-slider::-webkit-slider-thumb {
  transition: background 0.12s ease, box-shadow 0.12s ease;
}

.loupe-slider:hover::-webkit-slider-thumb,
.loupe-slider:active::-webkit-slider-thumb {
  background: #4f4a42;
}

.loupe-slider:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 2px rgba(90, 130, 210, 0.55);
}

.loupe-slider:hover::-moz-range-thumb,
.loupe-slider:active::-moz-range-thumb {
  background: #4f4a42;
}

.loupe-slider:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 2px rgba(90, 130, 210, 0.55);
}

/* ============================================================
   Three seams the last pass left behind.
   ============================================================ */

/* The header keeps its Aqua glass but loses the two blue rules that
   boxed it in: the drawer above and the body below already say
   where it ends, and its own lit top edge does the rest. */
.loupe-header {
  border-top: none;
  border-bottom: none;
}

/* The tools each take a share of the row rather than being pushed
   to its ends: the outer margins were 8px against 26px between,
   which only showed once a key carried a fill. */
.loupe-bar {
  justify-content: space-around;
  padding: 5px 6px;
}

/* The rows reserve a transparent border so nothing shifts when the
   colour comes in, but the fill was painting under it and leaving a
   pale fringe along the top of the blue. Hold it to the padding.
   The `background` shorthand resets the clip, so it is restated
   after every rule that sets one. */
.gallery-row,
.gallery-row:hover,
.gallery-row.active,
.gallery-row.active:hover {
  background-clip: padding-box;
}

/* The press moved the whole glyph down and right, which left it
   sitting off-centre in its key. Nudge the key's own padding back
   by the same pixel so the sign presses without drifting. */
.bar-tool.active svg {
  transform: translate(0.5px, 0.5px);
}

/* The rail's 1px right rule sits inside its 52px, so its interior
   is 51 and centred blocks land a pixel left of true middle. The
   box grows by that pixel instead, which puts the rule back on the
   outside where it belongs and the blocks in the centre. */
.rail {
  width: calc(var(--rail-width) + 1px);
}

/* ============================================================
   One hover colour for the whole site: the blue wash the settings
   rows have always used. Every white hover is replaced by it, so
   resting on anything anywhere says the same thing.
   ============================================================ */
.rail-link:hover,
.rail-nav .rail-link:hover,
.rail-nav .rail-sub:hover,
.rail-tools button:hover,
.bar-tool:hover,
.fx-tile:hover,
.gallery-row:hover,
.post-card:hover,
.site-list li:hover,
.hq-cell:hover,
.paper .shelf-cell:hover,
.pillar-shade .size-pick:hover,
.pillar-shade .lang-pick:hover {
  background: rgba(90, 130, 210, 0.16);
}

/* ============================================================
   The sheet is centred on its text. The glass was pinned at a
   fixed 132px, set when the rail was a different width; the text
   has since moved and the two fell out of step, leaving 32px of
   margin on the left and 48px on the right. Both are measured
   from the rail now, so the paper always sits square in its
   glass: the text starts one rail plus 72 plus 40 from the edge,
   so the glass starts 40 short of that and runs 500 wide.
   ============================================================ */
body::after,
.pillar-shade {
  left: calc(var(--rail-width) + 72px);
}

/* The arrows stood 14px short of the paper's right edge while the
   text began flush on the left, which tipped every row. The rows
   bleed 10px past the paper so their hover can breathe, so the
   arrow sits at that same 10px and the column reads square. */
.site-list a::after,
.paper .shelf-cell::after {
  right: 10px;
}

/* Every arrow is cut the way a system draws one: the shaft square
   at both ends, the corner mitred rather than rounded, and the mark
   a touch smaller and lighter than the words it serves. */
.paper a::after,
.paper .shelf-cell::after,
.post-card .post-title::after {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E");
  width: 0.58em;
  height: 0.58em;
  opacity: 0.6;
}

.site-list li:hover a::after,
.paper .shelf-cell:hover::after,
.post-card:hover .post-title::after {
  opacity: 1;
}

/* The apple waits under a rule of its own, drawn like the one at
   the rail's foot: nothing is behind it yet, so it sits quiet and
   says "Soon" when you rest on it. */
.rail-group.waiting {
  position: relative;
  /* the panel starts below the rule rather than under it, and drops
     its lit lower-right edge — only the shaded side is drawn, so
     the face keeps its silk and nothing outlines it */
  margin-top: 12px;
  /* the panel closes evenly on the apple: three pixels a side */
  padding: 3px;
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.32);
}

.rail-group.waiting::before {
  content: "";
  position: absolute;
  top: -12px;
  left: 9px;
  right: 9px;
  height: 1px;
  background: rgba(85, 86, 90, 0.16);
  box-shadow: 0 1px 0 rgba(251, 251, 249, 0.22);
  pointer-events: none;
}

/* The key is there, but nothing answers the cursor: it does not
   brighten or lift, because there is nothing behind it yet. Only
   the name arrives, on hover. */
.rail-group.waiting .rail-link,
.rail-group.waiting .rail-link:hover {
  cursor: default;
  opacity: 0.5;
  transform: none;
  /* the key keeps its resting face under the cursor: no blue, no
     lift, nothing to press */
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

/* it has no stops of its own, so nothing is drawn under it */
.rail-group.waiting .rail-subs {
  display: none;
}

/* the apple's key sits flush in its panel, with no margin of its
   own pushing the floor down */
.rail-group.waiting .rail-link {
  margin-bottom: 0;
}

/* The arrow moved out to the paper's edge, so everything that was
   holding a place for it follows by the same fourteen pixels: the
   covers, the years, and the room each row leaves on its right.
   Otherwise a gap opens between the picture and the mark. */
#books .song-cover,
#movies .song-cover {
  right: 32px;
}

#books .song-list li,
#movies .song-list li {
  padding-right: 76px;
}

.site-list li,
.paper .shelf-cell {
  padding-right: 30px;
}

/* every shelf follows the arrow by the same fourteen pixels */
.song-cover {
  right: 34px;
}

.song-list li {
  padding-right: 78px;
}

/* The year is pushed by the row's own right padding, so it was
   left standing where the sleeve used to be. The padding closes to
   just the sleeve and the arrow, which brings the year up against
   the artwork the way it reads on a shelf. */
.song-list li {
  padding-right: 64px;
}

#books .song-list li,
#movies .song-list li {
  padding-right: 62px;
}

/* rows with no sleeve keep only the arrow's room */
.song-list.no-cover li {
  padding-right: 30px;
}

/* The design page carries its own reading column right up to the
   marks, so the names would sit on top of it. There the marks
   speak alone, and the name arrives only under the cursor. */
body.theme-plain .scroll-marks .tooltip {
  opacity: 0;
  transition: opacity 0.15s ease;
}

body.theme-plain .scroll-marks a:hover .tooltip {
  opacity: 1;
}

/* The card's corner is cut closer, to the six the photograph inside
   it and the tool panel already use. Ten belonged to the older,
   softer language; the site has been moving toward the system's
   tighter one. Only this card for now, to see it beside the rest. */
.post-card {
  border-radius: 6px;
}

/* The card sat taller than the rows around it, and its two lines
   were nearly twice apart: the title at seventeen, the note at
   nine. The card closes up, the title meets the shelf rows at
   sixteen, and the note rises to a size that can be read. The
   picture keeps its size but takes the card's own corner. */
.post-card {
  padding: 8px 12px 8px 8px;
}

.post-card img {
  border-radius: 4px;
}

.post-card .post-title {
  font-size: 16px;
}

.post-card .post-sub {
  font-size: 12.5px;
}

/* ============================================================
   The design page speaks in one voice: every line set at the same
   size, in the same ink, upright and unshouted. The date under a
   project name, the numeral before a chapter, and the closing note
   all come to meet the prose they sit beside.
   ============================================================ */
body.theme-plain .paper .meta {
  font-size: 16px;
  letter-spacing: 0.192px;
  text-transform: none;
  color: var(--ink);
}

body.theme-plain .paper .chapter-num {
  font-size: 16px;
  color: var(--ink);
}

body.theme-plain .paper .closing {
  font-size: 16px;
}

/* ============================================================
   A compact project: the steps sit close enough to read as one
   passage rather than one screen apiece. Each opens with a short
   rule instead of a numeral, and the rule fills with ink as its
   own step comes up, so the eye can see where it is without
   scrolling a page to find out.
   ============================================================ */
body.design-dark .chapter-step.compact {
  position: relative;
  /* close enough to read as one passage, far enough that each step
     holds the stage long enough to be seen */
  margin-top: 120px;
  margin-bottom: 0;
  padding-left: 26px;
}

.chapter-step.compact::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 20px;
  height: 2px;
  border-radius: 1px;
  background: var(--ink);
  /* only the step being read carries a bar; the others show none,
     so the mark says one thing and never competes with itself */
  opacity: 0;
  transition: opacity 0.28s ease;
}

/* the step being read is the only one marked */
.chapter-step.compact.step-active::before {
  opacity: 1;
}

/* Inside a compact project the step the stage is answering reads
   in full ink, and its neighbours wait beside it in a half-voice:
   present enough to read on, quiet enough that the eye knows where
   it is. Once you leave, the whole section fades with the rest, so
   the next project still arrives on a clear page. */
body.design-dark #clawtin.section-live [data-visual],
body.design-dark #tech-equity.section-live [data-visual],
body.design-dark #minigloss.section-live [data-visual],
body.design-dark #jeep.section-live [data-visual] {
  opacity: 0.38;
}

body.design-dark #clawtin.section-live [data-visual].step-active,
body.design-dark #tech-equity.section-live [data-visual].step-active,
body.design-dark #minigloss.section-live [data-visual].step-active,
body.design-dark #jeep.section-live [data-visual].step-active {
  opacity: 1;
}

/* The Clawtin shot is a photograph, so it keeps a photograph's
   square corners like every other picture on the stage. */
.stage-media[data-visual="v1"] img {
  border-radius: 0;
}

/* The design page opens on its one belief, held at the middle of
   the screen: nothing above it, and the first project waiting a
   scroll below. */
body.theme-plain .paper > h1 {
  margin-top: 26vh;
}

body.theme-plain .philosophy {
  margin-bottom: 26px;
}

/* the question, then the three answers, counted plainly and set in
   the same hand as everything else on the page */
body.theme-plain .philosophy-sub {
  margin-bottom: 10px;
}

body.theme-plain .craft {
  margin: 0 0 12px;
  padding-left: 20px;
  list-style: decimal;
}

/* only the opening list holds the page open before the first
   project arrives */
body.theme-plain .paper > .craft {
  margin-bottom: 30vh;
}

body.theme-plain .craft li {
  margin-bottom: 4px;
  font-size: 16px;
  line-height: 1.74;
  color: var(--ink);
}

/* The end credits speak the way the letter does: one size, one
   ink, no small capitals. The name leads and the rest follows in
   the same voice. */
.credits {
  text-align: left;
}

.credit-name {
  font-size: 16px;
  font-weight: 400;
}

.credit-line {
  font-size: 16px;
  font-weight: 400;
  letter-spacing: 0.192px;
  text-transform: none;
  color: var(--ink);
}

/* ============================================================
   The panel's toolbar is moulded from the rail itself: the same
   grey well, and every tool a raised keycap with the same 1px
   two-tone bevel the palette and the numerals sit on. Choosing
   one presses it in, exactly as a rail key presses.
   ============================================================ */
.loupe-bar {
  /* the rail's own glass, poured identically: the painting reads
     through a 16px blur under the same grey, so the two surfaces
     are one material rather than one colour */
  background: rgba(207, 207, 203, 0.42);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.32),
    inset -1px -1px 0 rgba(251, 251, 249, 0.26);
}

.bar-tool {
  border-radius: 0;
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.bar-tool:hover {
  background: rgba(255, 255, 255, 0.62);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.bar-tool.active {
  background: rgba(160, 160, 156, 0.42);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

/* The panel's white sheet steps back to its two upper rooms — the
   drawer and the placard — so behind the toolbar nothing but the
   blurred painting remains, and the rail's grey lands on the same
   ground it lands on in the rail. One material, twice. */
.loupe-panel {
  background: rgba(252, 253, 255, 0.1);
}

.tool-drawer-inner {
  background: rgba(252, 253, 255, 0.58);
}

.loupe-intro {
  background: rgba(255, 255, 255, 0.72);
}

/* ============================================================
   The tool row sits back at the placard's foot, square-cornered
   like the sheet above it. The signs are the rail's own emoji,
   plain and a touch desaturated, coming to full colour and riding
   the press when their tool is out.
   ============================================================ */
.loupe-panel {
  border-radius: 0;
}

.bar-sign {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  line-height: 1;
  filter: saturate(0.92);
  opacity: 0.85;
}

.bar-tool.active .bar-sign {
  filter: none;
  opacity: 1;
  transform: translate(1px, 1px); /* the sign rides the press */
}

/* ============================================================
   Choosing a painting reads like the rail's own menu: one line of
   text per painting on breathing glass, no pictures, no marks.
   The blue wash on hover and the blue bar on the chosen one are
   kept exactly as they were — they already said it well.
   ============================================================ */
.tool-drawer-inner:has(.tool-section[data-tool="gallery"].active) {
  /* thinner milk over the panel's blur, so the wallpaper reads
     through the list the way it reads through the rail */
  background: rgba(252, 253, 255, 0.3);
}

.gallery-choices {
  gap: 2px;
}

.gallery-row img {
  display: none;
}

.gallery-row {
  padding: 6px 12px;
}

.gallery-row .g-meta {
  flex-direction: row;
  align-items: baseline;
  gap: 8px;
}

.gallery-row .g-artist {
  flex: none;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.4;
}

.gallery-row .g-title {
  font-size: 12px;
  line-height: 1.4;
  opacity: 0.75;
}

/* The panel's header is rolled from the letter's own title bar:
   the same brushed metal, the same lit top edge and dark seam, so
   the two windows are trimmed alike. */
.loupe-header {
  height: 20px;
  padding: 0 12px;
  background: linear-gradient(
    180deg,
    #f2f4f6 0%,
    #e2e6ea 42%,
    #d3d8de 58%,
    #c6ccd3 100%
  );
  border-top: none;
  border-bottom: 1px solid rgba(80, 88, 98, 0.5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(255, 255, 255, 0.35);
}

/* resting on the section no longer washes the metal out */
.tool-section:hover > .loupe-header {
  background: linear-gradient(
    180deg,
    #f6f8fa 0%,
    #e8ecf0 42%,
    #d9dee4 58%,
    #ccd2d9 100%
  );
}

.loupe-title {
  font-size: 11px;
  letter-spacing: 0.3px;
  color: #3f4650;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
}

.loupe-header svg {
  width: 11px;
  height: 11px;
  stroke: #59616c;
}

/* ============================================================
   The panel is edged the way the rail is: no ink line round it,
   only the rail's own hairline and lit inner edges, so the two
   read as the same glass rather than a card sitting on top of it.
   The painting's name has moved into the metal title bar, so the
   white placard below is gone.
   ============================================================ */
.loupe-panel {
  border: none;
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.28),
    inset 1px 1px 0 rgba(251, 251, 249, 0.55),
    0 14px 34px rgba(22, 28, 38, 0.22);
}

.loupe-panel:hover {
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.28),
    inset 1px 1px 0 rgba(251, 251, 249, 0.55),
    0 18px 44px rgba(22, 28, 38, 0.3);
}

/* the title reads as a name, not a label: it can run long, so it
   sits at the left and trims with an ellipsis if the panel is
   narrower than the words */
.loupe-header {
  justify-content: flex-start;
  gap: 7px;
}

.loupe-title {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* the tool row closes the panel now that the placard has gone */
.loupe-bar {
  border-top: 1px solid rgba(85, 86, 90, 0.22);
}

/* ============================================================
   THE WALL LABEL

   The tools are about the painting, so they live on the painting:
   a museum's wall label, resting on the open wall to the right of
   the letter rather than floating in a window of its own. At rest
   it is only the name of the work, small and quiet, the way a
   label is. Approach it and the tools unfold beneath it.

   This is why the panel never felt placed before: it belonged to
   the painting all along, and was standing in the corner instead.
   ============================================================ */
.loupe-panel {
  /* Low on the wall and off to the right, where a label is hung:
     below the run of section marks, set in from the corner. The
     work opens upward from it, the way a drawer pulls out of a
     cabinet rather than pushing off the floor. */
  /* Out in the open air below and left of the last section mark:
     its right edge stops where the marks' own line begins, so the
     label reads as the next step down that diagonal rather than a
     thing pinned to the corner. */
  right: 148px;
  left: auto;
  top: auto;
  bottom: 22vh;
  transform: none;
  width: 260px;
  max-height: 56vh;

  /* the label is printed on the wall, not cut from glass: it holds
     only the faintest tint so the painting stays the subject */
  background: rgba(252, 253, 255, 0.16);
  -webkit-backdrop-filter: blur(3px) saturate(1.05);
  backdrop-filter: blur(3px) saturate(1.05);
  box-shadow: none;
  overflow: visible;
  transition: background 0.32s ease, backdrop-filter 0.32s ease,
    box-shadow 0.32s ease;
}

/* The label's own line, always on the wall: the work above, the
   hand that made it below, lit like the section names opposite. */
.loupe-now {
  margin: 0;
  padding: 8px 12px 7px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.35;
  transition: color 0.32s ease, text-shadow 0.32s ease;
}

.now-work {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 1px 3px rgba(15, 18, 24, 0.9);
}

.now-hand {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 0 1px 3px rgba(15, 18, 24, 0.9);
}

.loupe-panel.open .now-work {
  color: var(--ink);
  text-shadow: none;
}

.loupe-panel.open .now-hand {
  color: #4a4d54;
  text-shadow: none;
}

/* a tool's own title, once its drawer is open */
.loupe-header {
  height: auto;
  padding: 6px 12px;
  background: none;
  border: none;
  border-top: 1px solid rgba(85, 86, 90, 0.18);
  box-shadow: none;
}

.loupe-title {
  font-size: 11px;
  letter-spacing: 0.2px;
  color: #59616c;
  text-shadow: none;
}

.loupe-header svg {
  stroke: #59616c;
  filter: none;
}

/* the tools wait under the label, out of the way until wanted */
.loupe-bar {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-top: none;
  box-shadow: none;
  opacity: 0.42;
  transition: opacity 0.28s ease;
}

.loupe-panel:hover .loupe-bar,
.loupe-panel.open .loupe-bar {
  opacity: 1;
}

/* the keys stand bare on the wall until the label is approached */
.bar-tool {
  background: none;
  box-shadow: none;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.loupe-panel:hover .bar-tool,
.loupe-panel.open .bar-tool {
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

/* opening a tool turns the label into a working surface: the glass
   thickens so the controls can be read against it */
.loupe-panel.open {
  background: rgba(252, 253, 255, 0.72);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.28),
    inset 1px 1px 0 rgba(251, 251, 249, 0.55),
    0 14px 34px rgba(22, 28, 38, 0.22);
}

/* ============================================================
   THE WALL LABEL

   The tools are about the painting, so they live on the painting:
   a museum's wall label, resting on the open wall to the right of
   the letter rather than floating in a window of its own. At rest
   it is only the name of the work, small and quiet, the way a
   label is. Approach it and the tools unfold beneath it.

   This is why the panel never felt placed before: it belonged to
   the painting all along, and was standing in the corner instead.
   ============================================================ */
.loupe-panel {
  /* Low on the wall and off to the right, where a label is hung:
     below the run of section marks, set in from the corner. The
     work opens upward from it, the way a drawer pulls out of a
     cabinet rather than pushing off the floor. */
  /* Out in the open air below and left of the last section mark:
     its right edge stops where the marks' own line begins, so the
     label reads as the next step down that diagonal rather than a
     thing pinned to the corner. */
  right: 148px;
  left: auto;
  top: auto;
  bottom: 22vh;
  transform: none;
  width: 260px;
  max-height: 56vh;

  /* the label is printed on the wall, not cut from glass: it holds
     only the faintest tint so the painting stays the subject */
  background: rgba(252, 253, 255, 0.16);
  -webkit-backdrop-filter: blur(3px) saturate(1.05);
  backdrop-filter: blur(3px) saturate(1.05);
  box-shadow: none;
  overflow: visible;
  transition: background 0.32s ease, backdrop-filter 0.32s ease,
    box-shadow 0.32s ease;
}

/* The label's own line, always on the wall: the work above, the
   hand that made it below, lit like the section names opposite. */
.loupe-now {
  margin: 0;
  padding: 8px 12px 7px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.35;
  transition: color 0.32s ease, text-shadow 0.32s ease;
}

.now-work {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 1px 3px rgba(15, 18, 24, 0.9);
}

.now-hand {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 0 1px 3px rgba(15, 18, 24, 0.9);
}

.loupe-panel.open .now-work {
  color: var(--ink);
  text-shadow: none;
}

.loupe-panel.open .now-hand {
  color: #4a4d54;
  text-shadow: none;
}

/* a tool's own title, once its drawer is open */
.loupe-header {
  height: auto;
  padding: 6px 12px;
  background: none;
  border: none;
  border-top: 1px solid rgba(85, 86, 90, 0.18);
  box-shadow: none;
}

.loupe-title {
  font-size: 11px;
  letter-spacing: 0.2px;
  color: #59616c;
  text-shadow: none;
}

.loupe-header svg {
  stroke: #59616c;
  filter: none;
}

/* the tools wait under the label, out of the way until wanted */
.loupe-bar {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-top: none;
  box-shadow: none;
  opacity: 0.42;
  transition: opacity 0.28s ease;
}

.loupe-panel:hover .loupe-bar,
.loupe-panel.open .loupe-bar {
  opacity: 1;
}

/* the keys stand bare on the wall until the label is approached */
.bar-tool {
  background: none;
  box-shadow: none;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.loupe-panel:hover .bar-tool,
.loupe-panel.open .bar-tool {
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

/* opening a tool turns the label into a working surface: the glass
   thickens so the controls can be read against it */
.loupe-panel.open {
  background: rgba(252, 253, 255, 0.72);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.28),
    inset 1px 1px 0 rgba(251, 251, 249, 0.55),
    0 14px 34px rgba(22, 28, 38, 0.22);
}

/* The keys wear the face they wear on hover, and the label's line
   is put away: the painting is right there to be looked at. */
.bar-tool {
  background: rgba(255, 255, 255, 0.62);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.85),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45),
    0 1px 3px rgba(20, 24, 32, 0.28);
}

.bar-tool:hover {
  background: rgba(255, 255, 255, 0.82);
}

.bar-tool.active {
  background: rgba(160, 160, 156, 0.55);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

.bar-tool svg.bar-sign {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: #23262b;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.82;
}

.bar-tool:hover svg.bar-sign,
.bar-tool.active svg.bar-sign {
  opacity: 1;
}

.loupe-now {
  display: none;
}

/* ============================================================
   At rest the tools are a column of quiet chips standing above
   the section marks, out on the painting with nothing behind
   them. Opening one returns the panel to the card it already
   knows how to be, so nothing about its insides changes.
   ============================================================ */
.loupe-panel:not(.open) {
  right: 20px;
  left: auto;
  top: auto;
  bottom: calc(50% + var(--marks-half, 141px) + 22px);
  width: 44px;
  max-height: none;
  align-items: flex-end;
}

.loupe-panel:not(.open) .loupe-bar {
  flex-direction: column;
  align-items: center;
  gap: 7px;
  width: auto;
  padding: 0;
  margin: 0;
}

/* quiet until asked: the chip is barely there, the sign faint */
.loupe-panel:not(.open) .bar-tool {
  width: 34px;
  height: 28px;
  background: rgba(255, 255, 255, 0.3);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.5),
    inset -1px -1px 0 rgba(85, 86, 90, 0.28);
}

.loupe-panel:not(.open) .bar-tool:hover {
  background: rgba(255, 255, 255, 0.68);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.9),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45),
    0 1px 3px rgba(20, 24, 32, 0.28);
}

.loupe-panel:not(.open) .bar-tool svg.bar-sign {
  opacity: 0.6;
}

.loupe-panel:not(.open) .bar-tool:hover svg.bar-sign {
  opacity: 1;
}

/* The card opens where the tools stand: its foot rests on the line
   the marks begin at, so it rises out of the column rather than
   appearing somewhere else on the screen. */
/* The card is held at the middle of the screen, out where the
   marks run: it rises over them rather than beside them. */
.loupe-panel.open {
  right: 20px;
  left: auto;
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  max-height: 78vh;
}

/* The chips stand apart, so the column reads as five keys rather
   than one grey slab, and the run begins level with the portrait
   at the head of the left rail. */
.loupe-panel:not(.open) {
  top: 29px;
  bottom: auto;
}

.loupe-panel:not(.open) .loupe-bar {
  gap: 12px;
}

/* nothing behind the resting keys: the painting runs right up to
   their edges */
.loupe-panel:not(.open) {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* No edge is drawn round the resting column — the white line that
   appeared on approach was the panel's own hover shadow. And the
   keys wear their lit face by default, since the sign brightening
   under the cursor already answers for the hover. */
.loupe-panel:not(.open),
.loupe-panel:not(.open):hover {
  border: none;
  box-shadow: none;
}

.loupe-panel:not(.open) .bar-tool,
.loupe-panel:not(.open):hover .bar-tool {
  background: rgba(255, 255, 255, 0.34);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.55),
    inset -1px -1px 0 rgba(85, 86, 90, 0.3);
}

.loupe-panel:not(.open) .bar-tool:hover {
  background: rgba(255, 255, 255, 0.62);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.85),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.loupe-panel:not(.open) .bar-tool.active {
  background: rgba(160, 160, 156, 0.5);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.5),
    inset -1px -1px 0 rgba(251, 251, 249, 0.7);
}

/* The signs are drawn in white against the dim chip, with a soft
   shadow under them so they hold up over a pale painting too. */
.loupe-panel:not(.open) .bar-tool svg.bar-sign {
  stroke: #fff;
  opacity: 0.95;
  filter: drop-shadow(0 1px 2px rgba(15, 18, 24, 0.55));
}

.loupe-panel:not(.open) .bar-tool:hover svg.bar-sign,
.loupe-panel:not(.open) .bar-tool.active svg.bar-sign {
  stroke: #fff;
  opacity: 1;
}

/* ============================================================
   RESPONSIVE, PUT BACK IN ORDER

   The glass sheet and the tool column were pinned to the rail in
   rules written after the media queries, so on a narrow screen
   they kept their desk-sized measurements and the letter fell off
   its own paper. These take the last word back.
   ============================================================ */

/* On a wide desk the reading column grows a little, and the glass
   grows with it: the letter should not stay a postcard on a large
   screen while the painting sprawls. */
@media (min-width: 1600px) {
  .paper {
    max-width: 520px;
  }

  body::after {
    width: 600px;
  }

  .page {
    margin-left: calc(var(--rail-width) + 96px);
  }

  body::after,
  .pillar-shade {
    left: calc(var(--rail-width) + 96px);
  }

  .pillar-shade {
    width: 600px;
  }
}

@media (min-width: 2000px) {
  .paper {
    max-width: 580px;
  }

  /* the glass keeps the same forty-pixel margin either side of the
     wider column: 580 + 40 + 40 */
  body::after,
  .pillar-shade {
    width: 660px;
  }

  .page {
    margin-left: calc(var(--rail-width) + 116px);
  }

  body::after,
  .pillar-shade {
    left: calc(var(--rail-width) + 116px);
  }
}

/* On a phone the sheet is the whole screen, the rail lies along
   the foot, and the tools come in from the right edge as a row
   above it rather than a column beside the painting. */
@media (max-width: 720px) {
  body::after,
  .pillar-shade {
    left: 0;
    right: 0;
    width: auto;
  }

  body::after {
    top: 0;
    background: rgba(252, 253, 255, 0.72);
    box-shadow: none;
  }

  .page {
    margin-left: 0;
  }

  .loupe-panel:not(.open),
  .loupe-panel.open {
    right: 12px;
    left: auto;
    top: auto;
    /* clear of the rail lying along the foot */
    bottom: 64px;
    transform: none;
    max-height: 60vh;
  }

  .loupe-panel:not(.open) {
    width: auto;
  }

  .loupe-panel:not(.open) .loupe-bar {
    flex-direction: row;
    gap: 8px;
  }

  .loupe-panel.open {
    left: 12px;
    right: 12px;
    width: auto;
  }

  .scroll-marks {
    display: none;
  }
}

/* The tools were hidden from 1100px down, which took them away on
   every tablet as well. They stay: only the loupe's own machinery,
   which wants a mouse and a large picture, steps aside there. */
@media (max-width: 1100px) and (min-width: 721px) {
  .loupe-panel,
  .loupe-bar {
    display: flex;
  }
}

/* on a phone the row sits above the rail at the foot */
@media (max-width: 720px) {
  .loupe-panel,
  .loupe-bar {
    display: flex;
  }

  .loupe-box,
  .dots-canvas,
  .grid-overlay {
    display: none;
  }
}

/* Between phone and desk the section marks are gone, so the tools
   have no line to stand above: they hold the top-right corner on
   their own. */
@media (max-width: 1100px) and (min-width: 721px) {
  .loupe-panel:not(.open) {
    top: 29px;
    bottom: auto;
  }

  .loupe-panel.open {
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
  }
}

/* ============================================================
   THE THOUGHT CHAINS

   A numbered run down the letter, newest first. The short ones
   say themselves on the paper. The longer ones give only their
   first line and open on a dark sheet beside the letter, where a
   long piece can be read without the page growing forever.
   ============================================================ */
.chains {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
}

.chain {
  width: 100%;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 9px 10px 9px 0;
  margin: 0 0 0 -10px;
  padding-left: 10px;
  border: none;
  border-radius: 4px;
  background: none;
  text-align: left;
  font-family: inherit;
  color: var(--ink);
  transition: background 0.12s ease;
}

.chain-no {
  flex: none;
  width: 34px;
  font-size: 16px;
  line-height: 1.7;
  letter-spacing: 0.19px;
  color: var(--ink);
}

.chain-line {
  flex: 1;
  min-width: 0;
  font-size: 16px;
  line-height: 1.7;
  letter-spacing: 0.19px;
}

/* what a short thought says after its own first line */
.chain-more {
  display: block;
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink);
}

/* the ones that open: a mark at the end of the line, and the
   whole row answers the cursor */
.chain-long {
  cursor: pointer;
}

.chain-long .chain-line::after {
  content: "";
  display: inline-block;
  width: 0.58em;
  height: 0.58em;
  margin-left: 8px;
  vertical-align: -0.02em;
  background: var(--ink);
  opacity: 0.55;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 9 9 3M4.4 3H9v4.6' stroke='%23000' stroke-width='0.9' fill='none' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: opacity 0.12s ease;
}

.chain-long:hover,
.chain-long.reading {
  background: rgba(90, 130, 210, 0.16);
}

.chain-long:hover .chain-line::after,
.chain-long.reading .chain-line::after {
  opacity: 1;
}

/* ---------- the dark sheet ---------- */
.chain-stage {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(46vw, 620px);
  z-index: 20;
  display: flex;
  flex-direction: column;
  padding: 8vh 0 6vh;
  background: rgba(16, 17, 20, 0.94);
  -webkit-backdrop-filter: blur(20px) saturate(0.9);
  backdrop-filter: blur(20px) saturate(0.9);
  box-shadow: -18px 0 48px rgba(10, 12, 16, 0.4);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 0.42s cubic-bezier(0.22, 0.9, 0.3, 1),
    visibility 0s linear 0.42s;
}

.chain-stage.open {
  transform: none;
}

.chain-panel {
  display: none;
  padding: 0 clamp(28px, 5vw, 64px);
  max-width: 560px;
}

.chain-panel.reading {
  display: block;
}

.chain-panel header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 26px;
}

.chain-panel .chain-no {
  width: auto;
  font-size: 16px;
  color: rgba(236, 231, 219, 0.5);
}

.chain-panel h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 1.35;
  color: #f2efe8;
}

.chain-panel p,
.chain-panel li {
  font-size: 15.5px;
  line-height: 1.78;
  letter-spacing: 0.15px;
  color: rgba(236, 231, 219, 0.82);
}

.chain-panel p {
  margin: 0 0 18px;
}

.chain-panel h4 {
  margin: 30px 0 12px;
  font-size: 16px;
  font-weight: 400;
  color: #f2efe8;
}

.chain-panel ul,
.chain-panel ol {
  margin: 0 0 18px;
  padding-left: 20px;
}

.chain-panel li {
  margin-bottom: 7px;
}

.chain-panel b {
  color: #f7f4ee;
  font-weight: 500;
}

.chain-panel em {
  color: rgba(236, 231, 219, 0.62);
}

.chain-panel a {
  color: rgba(236, 231, 219, 0.82);
  text-decoration-color: rgba(236, 231, 219, 0.35);
}

.chain-panel blockquote {
  margin: 0 0 18px;
  padding-left: 16px;
  border-left: 1px solid rgba(236, 231, 219, 0.22);
}

/* the way out, held at the sheet's top corner */
.chain-close {
  position: sticky;
  top: 0;
  align-self: flex-end;
  margin: -4vh clamp(28px, 5vw, 64px) 22px 0;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(236, 231, 219, 0.1);
  color: rgba(236, 231, 219, 0.7);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}

.chain-close:hover {
  background: rgba(236, 231, 219, 0.2);
  color: #f2efe8;
}

@media (max-width: 900px) {
  .chain-stage {
    width: 100%;
    padding-top: 6vh;
  }
}

/* the sheet's own rule, said last so nothing later undoes it */
.chain-stage.open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.42s cubic-bezier(0.22, 0.9, 0.3, 1),
    visibility 0s;
}

/* The chips wear the brighter face at rest — what used to arrive
   only on approach. Resting on one now lifts it a little further
   still, so the cursor still has something to answer. */
.loupe-panel:not(.open) .bar-tool,
.loupe-panel:not(.open):hover .bar-tool {
  background: rgba(255, 255, 255, 0.4);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.7),
    inset -1px -1px 0 rgba(85, 86, 90, 0.38),
    0 1px 2px rgba(20, 24, 32, 0.2);
}

.loupe-panel:not(.open) .bar-tool:hover {
  background: rgba(255, 255, 255, 0.66);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.88),
    inset -1px -1px 0 rgba(85, 86, 90, 0.42),
    0 1px 3px rgba(20, 24, 32, 0.26);
}

/* the chip is bright now, so the sign goes back to ink against it */
.loupe-panel:not(.open) .bar-tool svg.bar-sign,
.loupe-panel:not(.open) .bar-tool:hover svg.bar-sign,
.loupe-panel:not(.open) .bar-tool.active svg.bar-sign {
  stroke: #23262b;
  filter: none;
  opacity: 0.82;
}

.loupe-panel:not(.open) .bar-tool:hover svg.bar-sign,
.loupe-panel:not(.open) .bar-tool.active svg.bar-sign {
  opacity: 1;
}

/* ============================================================
   The wallpaper rows show their pictures again: a small square-cut
   swatch of each painting before its name, framed in a hairline,
   cropped to the same focus the wallpaper itself uses.
   ============================================================ */
.gallery-row img {
  display: block;
  width: 34px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 0;
  border: 1px solid rgba(85, 86, 90, 0.4);
  box-shadow: 0 1px 2px rgba(20, 24, 32, 0.18);
  flex-shrink: 0;
}

.gallery-row.active img {
  border-color: rgba(251, 251, 249, 0.85);
}

/* ============================================================
   ONE BAR, ONE WALL

   At rest the tools are a single title bar of the letter's
   brushed metal at the painting's foot: "Tools", and the red
   disc. Click it and a wall slides in over the right edge, cut
   from the left rail's own glass: the five tools stand at its
   head as a nav, always in view, and the chosen tool's controls
   fill the rest. No floors below floors — everything the window
   has is on show. The section marks step out to the wall's left
   and say only their dashes until it closes.
   ============================================================ */
@media (min-width: 721px) {
  /* the marks stand from the first moment; only the wall sends
     them away */
  .scroll-marks {
    transition: opacity 0.4s ease, right 0.34s cubic-bezier(0.22, 0.9, 0.3, 1);
  }

  /* while the wall is up the marks step out of the room entirely:
     the wall is the only instrument on the right */
  body:has(.loupe-panel.open) .scroll-marks {
    opacity: 0;
    pointer-events: none;
  }

  /* ---- shut: one square key at the top right, cut the way the
     left rail cuts its own keycaps */
  .loupe-panel:not(.open),
  .loupe-panel:not(.open):hover {
    top: 28px;
    left: auto;
    right: 22px;
    bottom: auto;
    width: auto;
    max-height: none;
    transform: none;
    border-radius: 0;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    padding: 0;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: none;
    box-shadow: none;
  }

  .loupe-panel:not(.open) .pod-chrome {
    display: none;
  }

  .pod-key {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: none;
    border-radius: 0;
    cursor: pointer;
    font-size: 17px;
    line-height: 1;
    background: rgba(240, 240, 237, 0.5);
    box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
      inset -1px -1px 0 rgba(85, 86, 90, 0.45);
  }

  .pod-key:hover {
    background: rgba(248, 248, 245, 0.62);
  }

  .pod-key:active {
    background: rgba(160, 160, 156, 0.42);
    box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.45),
      inset -1px -1px 0 rgba(255, 255, 255, 0.8);
  }

  .pod-key:active .pod-key-sign {
    transform: translate(1px, 1px);
  }

  .pod-key-sign {
    display: block;
  }

  .loupe-panel.open .pod-key {
    display: none;
  }

  /* ---- open: the full wall, in the rail's glass, sliding in */
  .loupe-panel.open {
    top: 0;
    bottom: 0;
    right: 0;
    left: auto;
    width: 320px;
    max-height: none;
    transform: none;
    border-radius: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    padding: 0;
    background: rgba(207, 207, 203, 0.42);
    -webkit-backdrop-filter: blur(16px) saturate(1.25);
    backdrop-filter: blur(16px) saturate(1.25);
    border: none;
    border-left: 1px solid rgba(85, 86, 90, 0.5);
    box-shadow: inset -1px 0 0 rgba(251, 251, 249, 0.75),
      inset 2px 0 0 rgba(85, 86, 90, 0.18);
    animation: wall-in 0.34s cubic-bezier(0.22, 0.9, 0.3, 1);
  }

  @keyframes wall-in {
    from {
      transform: translateX(100%);
    }
    to {
      transform: none;
    }
  }

  /* the word buttons belong to the phone's sheet */
  .loupe-panel .loupe-bar {
    display: none;
  }

  /* ---- the bar: the iPod's own glossy strip, light with a hard
     shine across its middle, the way the old screens drew it */
  .loupe-panel .pod-chrome {
    display: flex;
    align-items: center;
    flex: none;
    order: -2;
    height: 24px;
    padding: 0 7px;
    background: linear-gradient(
      180deg,
      #ffffff 0%,
      #f3f5f7 44%,
      #dde1e5 50%,
      #ccd1d7 88%,
      #c3c9cf 100%
    );
    box-shadow: inset 0 1px 0 #ffffff;
  }

  .loupe-panel.open .pod-chrome {
    border-bottom: 1px solid rgba(75, 82, 90, 0.55);
  }

  /* every floor is on show now; nothing to back out of */
  .pod-back {
    display: none;
  }

  .pod-name {
    flex: 1 1 auto;
    text-align: center;
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.4px;
    color: #23262b;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
    margin: 0;
    padding-left: 24px; /* the X's width, so the name centres on the bar */
    pointer-events: none;
  }

  /* the close: a plain system-cut X, no glass, no colour */
  .pod-close {
    flex: none;
    position: relative;
    width: 18px;
    height: 18px;
    margin-left: auto;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 0;
    cursor: pointer;
    background: none;
    box-shadow: none;
  }

  .pod-close svg {
    width: 8px;
    height: 8px;
    fill: none;
    stroke: #23262b;
    stroke-width: 1.8;
    stroke-linecap: square;
    opacity: 0.55;
    transition: opacity 0.15s ease;
  }

  .loupe-panel.open .pod-close:hover svg {
    opacity: 1;
  }

  /* ---- the nav: five rows at the wall's head, always in view */
  .loupe-panel .pod-menu {
    display: none;
  }

  /* the nav is a proper list panel, the way the pocket screen drew
     it: a pale sheet on the glass, rows parted by engraved rules */
  .loupe-panel.open .pod-menu {
    display: flex;
    flex-direction: column;
    flex: none;
    order: -1;
    padding: 0;
    background: rgba(252, 253, 255, 0.62);
    border-bottom: 1px solid rgba(85, 86, 90, 0.4);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7),
      0 1px 0 rgba(251, 251, 249, 0.3);
  }

  .pod-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    height: 30px;
    padding: 0 14px;
    border: none;
    background: none;
    cursor: pointer;
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 14px;
    color: #23262b;
    text-align: left;
  }

  .pod-row + .pod-row {
    border-top: 1px solid rgba(85, 86, 90, 0.16);
    box-shadow: inset 0 1px 0 rgba(251, 251, 249, 0.22);
  }

  .pod-row.active + .pod-row,
  .pod-row:has(+ .pod-row.active) + .pod-row {
    box-shadow: none;
  }

  .pod-row-go {
    display: flex;
    align-items: center;
    color: rgba(35, 38, 43, 0.3);
    transition: color 0.15s ease;
  }

  .pod-row-go svg {
    width: 5.5px;
    height: 9px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: square;
    stroke-linejoin: miter;
    display: block;
  }

  .pod-row.active .pod-row-go {
    color: rgba(255, 255, 255, 0.7);
  }

  .pod-row:hover {
    background: rgba(90, 130, 210, 0.16);
  }

  .pod-row.active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    color: #fff;
  }

  .pod-row.active .pod-row-go {
    color: rgba(255, 255, 255, 0.85);
  }

  /* ---- the pages: the rest of the wall, scrolling inside */
  .loupe-panel.open .tool-drawer {
    flex: 1 1 auto;
    min-height: 0;
  }

  .loupe-panel.open .tool-drawer-inner,
  .loupe-panel.open .tool-drawer-inner:has(.tool-section[data-tool="gallery"].active) {
    height: 100%;
    max-height: none;
    overflow-y: auto;
    background: none;
  }

  /* the nav names the page; the old headers stay quiet */
  .loupe-panel .loupe-header {
    display: none;
  }

  /* a page pushes in from the right, quietly */
  .loupe-panel.open .tool-section.turn {
    animation: pod-turn 0.22s ease;
  }

  @keyframes pod-turn {
    from {
      opacity: 0;
      transform: translateX(14px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }
}



/* ============================================================
   The wallpaper list, set straight: no stray indent — the rows
   run the wall's full width like the nav above them, parted by
   the same engraved rules, each painting a small square-cut
   swatch. The chosen row is the same full-width blue bar the
   nav draws.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .tool-section[data-tool="gallery"] .loupe-body {
    padding: 0;
    gap: 0;
  }

  .loupe-panel.open .gallery-choices {
    gap: 0;
    padding: 0;
  }

  .loupe-panel.open .gallery-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    margin: 0;
    padding: 7px 14px;
    border-radius: 0;
  }

  .loupe-panel.open .gallery-row + .gallery-row {
    border-top: 1px solid rgba(85, 86, 90, 0.14);
    box-shadow: inset 0 1px 0 rgba(251, 251, 249, 0.18);
  }

  .loupe-panel.open .gallery-row img {
    width: 26px;
    height: 26px;
    aspect-ratio: auto;
    object-fit: cover;
    border: 1px solid rgba(85, 86, 90, 0.4);
    box-shadow: none;
    border-radius: 0;
  }

  .loupe-panel.open .gallery-row .g-artist {
    font-size: 14px;
  }

  .loupe-panel.open .gallery-row .g-title {
    font-size: 12px;
  }

  .loupe-panel.open .gallery-row.active {
    border-radius: 0;
  }
}

/* ============================================================
   The effect previews, set straight: square-cut frames on the
   glass, no cards, no lifts, no rounded corners. The one in use
   wears the selection blue as a plain ring; its name says the
   rest. The wallpaper rows lose their double rules and heavy
   frames — one hairline each, nothing else.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .fx-previews {
    gap: 12px 10px;
  }

  .loupe-panel.open .fx-tile,
  .loupe-panel.open .fx-tile:hover,
  .loupe-panel.open .fx-tile.active {
    padding: 0;
    background: none;
    border-radius: 0;
    box-shadow: none;
  }

  .loupe-panel.open .fx-tile canvas {
    border-radius: 0;
    border: 1px solid rgba(85, 86, 90, 0.35);
    transition: box-shadow 0.12s ease, border-color 0.12s ease;
  }

  .loupe-panel.open .fx-tile:hover canvas {
    transform: none;
    border-color: rgba(85, 86, 90, 0.6);
  }

  .loupe-panel.open .fx-tile.active canvas {
    border-color: #4a75cf;
    box-shadow: 0 0 0 1px #4a75cf;
  }

  .loupe-panel.open .fx-tile span {
    font-size: 12px;
    color: rgba(35, 38, 43, 0.75);
  }

  .loupe-panel.open .fx-tile.active span {
    color: #23262b;
    font-weight: 600;
  }

  /* the wallpaper rows: one rule between rows, one hairline on
     each swatch, and nothing else */
  .loupe-panel.open .gallery-row + .gallery-row {
    border-top: 1px solid rgba(85, 86, 90, 0.12);
    box-shadow: none;
  }

  .loupe-panel.open .gallery-row img,
  .loupe-panel.open .gallery-row.active img {
    border: 1px solid rgba(85, 86, 90, 0.25);
  }

  .loupe-panel.open .gallery-row:hover {
    background: rgba(90, 130, 210, 0.16);
  }
}

/* ============================================================
   Selection speaks in the letter's own voice: the same blue wash
   its links wear under the cursor, a shade deeper for the thing
   chosen, ink text throughout. The royal bars retire.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .pod-row:hover {
    background: rgba(90, 130, 210, 0.16);
  }

  /* chosen things keep the old Aqua bar; the wash is for the
     cursor only */
  .loupe-panel.open .pod-row.active,
  .loupe-panel.open .pod-row.active:hover,
  .loupe-panel.open .pod-row:active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    color: #fff;
  }

  .loupe-panel.open .pod-row.active .pod-row-go,
  .loupe-panel.open .pod-row:active .pod-row-go {
    color: rgba(255, 255, 255, 0.7);
  }

  .loupe-panel.open .gallery-row.active,
  .loupe-panel.open .gallery-row.active:hover {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
  }

  .loupe-panel.open .gallery-row.active .g-artist {
    color: #fff;
  }

  .loupe-panel.open .gallery-row.active .g-title {
    color: rgba(255, 255, 255, 0.8);
  }

  .loupe-panel.open .fx-tile.active canvas {
    border-color: #4a75cf;
    box-shadow: 0 0 0 1px #4a75cf;
  }
}

/* ============================================================
   Inset things get their corners back: previews, palette rows,
   swatches — anything floating inside the wall's padding wears a
   small radius, and selection wears the letter's wash rounded
   the same way. Full-bleed rows (nav, wallpaper list) stay
   square-cut against the edges.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile canvas {
    border-radius: 5px;
  }

  .loupe-panel.open .fx-tile.active canvas {
    border-radius: 5px;
  }

  .loupe-panel.open .palette-row {
    border-radius: 6px;
  }

  .loupe-panel.open .palette-row:hover {
    background: rgba(90, 130, 210, 0.16);
  }

  .loupe-panel.open .palette-row:active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
  }

  .loupe-panel.open .palette-row:active .row-hex,
  .loupe-panel.open .palette-row:active .row-share {
    color: #fff;
  }

  .loupe-panel.open .row-swatch {
    border-radius: 4px;
    border: 1px solid rgba(85, 86, 90, 0.3);
  }

  .loupe-panel.open .palette-bento span {
    border-radius: 5px;
  }
}

/* ============================================================
   The effect previews become little cards: a soft rounded chip
   of the site's white glass holding the picture, its name set
   at the card's foot. The one in use is the lit card, ringed in
   the Aqua blue; the cursor's wash stays the letter's.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .fx-previews {
    gap: 12px 10px;
  }

  .loupe-panel.open .fx-tile,
  .loupe-panel.open .fx-tile:hover,
  .loupe-panel.open .fx-tile.active {
    padding: 7px 7px 6px;
    border-radius: 10px;
    gap: 6px;
  }

  .loupe-panel.open .fx-tile {
    background: rgba(255, 255, 255, 0.32);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5),
      0 1px 3px rgba(20, 24, 32, 0.12);
  }

  .loupe-panel.open .fx-tile:hover {
    background: rgba(90, 130, 210, 0.16);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4),
      0 1px 3px rgba(20, 24, 32, 0.12);
  }

  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    background: rgba(255, 255, 255, 0.66);
    box-shadow: 0 0 0 1.5px #4a75cf,
      inset 0 1px 0 rgba(255, 255, 255, 0.7),
      0 1px 4px rgba(20, 24, 32, 0.14);
  }

  .loupe-panel.open .fx-tile canvas,
  .loupe-panel.open .fx-tile.active canvas {
    border-radius: 6px;
    border: 1px solid rgba(85, 86, 90, 0.25);
    box-shadow: none;
  }

  .loupe-panel.open .fx-tile span {
    text-align: left;
    padding: 0 2px;
    font-size: 12.5px;
    color: rgba(35, 38, 43, 0.8);
  }

  .loupe-panel.open .fx-tile.active span {
    color: #23262b;
    font-weight: 600;
  }
}

/* ============================================================
   The effect cards take the letter's own card voice: a faint
   blue glass at rest, and the chosen one settles into the same
   quiet lifted card the letter's post wears — underlined name,
   no loud ring. The name line grows; the picture cedes a little.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile,
  .loupe-panel.open .fx-tile:hover,
  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    padding: 7px 7px 8px;
    gap: 7px;
  }

  .loupe-panel.open .fx-tile {
    background: rgba(170, 190, 225, 0.24);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45);
  }

  .loupe-panel.open .fx-tile:hover {
    background: rgba(90, 130, 210, 0.2);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
  }

  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    background: rgba(205, 215, 240, 0.5);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65),
      0 1px 4px rgba(20, 24, 32, 0.14);
  }

  .loupe-panel.open .fx-tile span {
    font-size: 13px;
    padding: 1px 3px 2px;
    color: rgba(35, 38, 43, 0.85);
  }

  .loupe-panel.open .fx-tile.active span {
    color: #23262b;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
    text-decoration-color: rgba(35, 38, 43, 0.6);
  }
}

/* ============================================================
   The cards start white, and the chosen one wears exactly what
   the paper wears under the cursor: the letter's wash laid over
   white glass, that faint violet the two make together. No
   underline; the bolder name and the small lift say chosen.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile {
    background: rgba(255, 255, 255, 0.42);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
  }

  .loupe-panel.open .fx-tile:hover {
    background: linear-gradient(
        0deg,
        rgba(90, 130, 210, 0.16),
        rgba(90, 130, 210, 0.16)
      ),
      rgba(255, 255, 255, 0.42);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
  }

  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    background: linear-gradient(
        0deg,
        rgba(90, 130, 210, 0.16),
        rgba(90, 130, 210, 0.16)
      ),
      rgba(255, 255, 255, 0.42);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55),
      0 1px 4px rgba(20, 24, 32, 0.14);
  }

  .loupe-panel.open .fx-tile.active span {
    text-decoration: none;
  }
}

/* ============================================================
   The wallpaper rows redrawn: the painting first. A wider swatch
   you can actually read, and the words stacked beside it — the
   artist above, the work below — so nothing truncates against
   the clock. Same hairlines, same Aqua choice.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .gallery-row {
    gap: 12px;
    padding: 8px 14px;
  }

  .loupe-panel.open .gallery-row img {
    width: 54px;
    height: 40px;
    border-radius: 4px;
    border: 1px solid rgba(85, 86, 90, 0.3);
  }

  .loupe-panel.open .gallery-row .g-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }

  .loupe-panel.open .gallery-row .g-artist {
    font-size: 14px;
    line-height: 1.15;
  }

  .loupe-panel.open .gallery-row .g-title {
    font-size: 12px;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* every radius in the wall follows the letter's post card:
   6px for cards and washes, 4px for pictures inside them */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile,
  .loupe-panel.open .fx-tile:hover,
  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    border-radius: 6px;
  }

  .loupe-panel.open .fx-tile canvas,
  .loupe-panel.open .fx-tile.active canvas {
    border-radius: 4px;
  }

  .loupe-panel.open .palette-bento span {
    border-radius: 4px;
  }
}

/* ============================================================
   The wall's foot keeps the old control panels' promise: one
   small button, "Reset", that puts the room back the way it was
   found — first painting, no effects. Set as a quiet white-glass
   chip; pressing it speaks the Aqua click like everything else.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel .pod-foot {
    display: none;
  }

  .loupe-panel.open .pod-foot {
    display: flex;
    justify-content: center;
    flex: none;
    order: 99;
    padding: 9px 14px 12px;
    border-top: 1px solid rgba(85, 86, 90, 0.3);
    box-shadow: inset 0 1px 0 rgba(251, 251, 249, 0.3);
  }

  .pod-reset {
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 12.5px;
    line-height: 1;
    color: #23262b;
    padding: 5px 16px 6px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    background: rgba(255, 255, 255, 0.42);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
  }

  .pod-reset:hover {
    background: linear-gradient(
        0deg,
        rgba(90, 130, 210, 0.16),
        rgba(90, 130, 210, 0.16)
      ),
      rgba(255, 255, 255, 0.42);
  }

  .pod-reset:active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    color: #fff;
  }
}



/* the white halos come off: every frame in the wall is the same
   quiet ink hairline, nothing lit around it */
@media (min-width: 721px) {
  .loupe-panel.open .loupe-view {
    border: 1px solid rgba(85, 86, 90, 0.3);
    box-shadow: none;
    border-radius: 4px;
  }

  .loupe-panel.open .palette-bento span {
    border: 1px solid rgba(85, 86, 90, 0.3);
    box-shadow: none;
  }
}

/* ============================================================
   The wall's foot, quieted: the painting's own label at the
   left — the placard found its place — and at the right a small
   system-cut dial, the counterclockwise arrow that turns the
   room back to how it was found. No chip, no box.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .pod-foot {
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 8px 14px 10px;
    border-top: 1px solid rgba(85, 86, 90, 0.3);
    box-shadow: none;
  }

  .loupe-panel.open .pod-foot .loupe-now {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
  }

  .loupe-panel.open .pod-foot .now-work {
    font-size: 11.5px;
    line-height: 1.25;
    color: #23262b;
    font-style: italic;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .loupe-panel.open .pod-foot .now-hand {
    font-size: 10.5px;
    line-height: 1.2;
    color: rgba(35, 38, 43, 0.6);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .pod-reset,
  .pod-reset:hover,
  .pod-reset:active {
    flex: none;
    width: 22px;
    height: 22px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 0;
    background: none;
    box-shadow: none;
    cursor: pointer;
  }

  .pod-reset svg {
    width: 13px;
    height: 13px;
    fill: none;
    stroke: #23262b;
    stroke-width: 1.5;
    stroke-linecap: square;
    stroke-linejoin: miter;
    opacity: 0.55;
    transition: opacity 0.15s ease, transform 0.3s ease;
  }

  .pod-reset:hover svg {
    opacity: 1;
  }

  .pod-reset:active svg {
    transform: rotate(-70deg);
  }
}

/* ============================================================
   One type scale for the whole wall. Two sizes only: 14px for
   whatever a row is about — tool names, artists, effect names,
   hex codes — and 12.5px for whatever attends it: works and
   years, percentages, hints. Ink for the first voice, six-tenths
   ink for the second. Nothing smaller, nothing in between.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .row-hex {
    font-size: 14px;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: #23262b;
  }

  .loupe-panel.open .row-share {
    font-size: 12.5px;
    color: rgba(35, 38, 43, 0.6);
  }

  .loupe-panel.open .gallery-row .g-artist {
    font-size: 14px;
    color: #23262b;
  }

  .loupe-panel.open .gallery-row .g-title {
    font-size: 12.5px;
    color: rgba(35, 38, 43, 0.6);
  }

  .loupe-panel.open .gallery-row.active .g-artist {
    color: #fff;
  }

  .loupe-panel.open .gallery-row.active .g-title {
    color: rgba(255, 255, 255, 0.8);
  }

  .loupe-panel.open .fx-tile span {
    font-size: 14px;
    color: #23262b;
  }

  .loupe-panel.open .loupe-hint,
  .loupe-panel.open .grid-hint {
    font-size: 12.5px;
    line-height: 1.45;
    color: rgba(35, 38, 43, 0.6);
  }

  .loupe-panel.open .loupe-row-label,
  .loupe-panel.open .loupe-val {
    font-size: 12.5px;
    letter-spacing: 0.4px;
    color: rgba(35, 38, 43, 0.6);
  }

  .loupe-panel.open .pod-foot .now-work {
    font-size: 12.5px;
  }

  .loupe-panel.open .pod-foot .now-hand {
    font-size: 12.5px;
  }
}

/* ============================================================
   The foot says one thing only: Reset, dial and word together,
   a proper button you can find. The placard goes back to sleep —
   the list already names every painting. And the wall's words
   press harder into the glass: near-black for first voices,
   three-quarter ink for second ones, so nothing washes out over
   a dark painting.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .pod-foot .loupe-now {
    display: none;
  }

  .loupe-panel.open .pod-foot {
    justify-content: flex-end;
    padding: 8px 12px;
  }

  .pod-reset,
  .pod-reset:hover,
  .pod-reset:active {
    width: auto;
    height: auto;
    gap: 7px;
    padding: 5px 13px 6px 11px;
    border-radius: 6px;
  }

  .pod-reset {
    background: rgba(255, 255, 255, 0.5);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
  }

  .pod-reset:hover {
    background: linear-gradient(
        0deg,
        rgba(90, 130, 210, 0.16),
        rgba(90, 130, 210, 0.16)
      ),
      rgba(255, 255, 255, 0.5);
  }

  .pod-reset:active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
  }

  .pod-reset svg {
    opacity: 0.8;
  }

  .pod-reset span {
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 13.5px;
    line-height: 1;
    color: #16181b;
  }

  .pod-reset:active svg {
    stroke: #fff;
    opacity: 1;
  }

  .pod-reset:active span {
    color: #fff;
  }

  /* contrast: first voices near-black, second voices 3/4 ink */
  .loupe-panel.open .pod-row,
  .loupe-panel.open .gallery-row .g-artist,
  .loupe-panel.open .fx-tile span,
  .loupe-panel.open .row-hex {
    color: #16181b;
  }

  .loupe-panel.open .gallery-row .g-title,
  .loupe-panel.open .row-share,
  .loupe-panel.open .loupe-hint,
  .loupe-panel.open .grid-hint,
  .loupe-panel.open .loupe-row-label,
  .loupe-panel.open .loupe-val {
    color: rgba(22, 24, 27, 0.76);
  }

  .loupe-panel.open .gallery-row.active .g-artist {
    color: #fff;
  }

  .loupe-panel.open .gallery-row.active .g-title {
    color: rgba(255, 255, 255, 0.85);
  }
}

/* the percentages are a murmur, not a voice: smaller and fainter
   than every other second line */
@media (min-width: 721px) {
  .loupe-panel.open .row-share {
    font-size: 11.5px;
    color: rgba(22, 24, 27, 0.42);
  }
}

/* the bar back to its heavier iPod build: taller strip, bolder
   name — same silver as now */
@media (min-width: 721px) {
  .loupe-panel .pod-chrome {
    height: 29px;
    padding: 0 9px;
  }

  .pod-name {
    font-size: 13.5px;
    font-weight: 700;
    letter-spacing: 0.3px;
  }

  .pod-close {
    width: 20px;
    height: 20px;
  }

  .pod-close svg {
    width: 9px;
    height: 9px;
  }
}

/* ============================================================
   The letter's title bar takes the wall's own silver: a white
   crown, the hard shine across the middle, the quiet pool at
   the foot — one metal for every window. The red disc stays
   exactly as it was.
   ============================================================ */
.pillar-shade {
  background: linear-gradient(
    180deg,
    #ffffff 0%,
    #f3f5f7 44%,
    #dde1e5 50%,
    #ccd1d7 88%,
    #c3c9cf 100%
  );
  border-bottom: 1px solid rgba(85, 86, 90, 0.45);
  box-shadow: inset 0 1px 0 #ffffff;
}

/* ============================================================
   The palette, rewoven: no slabs. One low band across the top —
   the painting's paints laid side by side, each as wide as its
   share of the canvas — and beneath it the chips, named in hex.
   The numbers go quiet for good; the band already says them.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .palette-bento {
    display: flex;
    gap: 0;
    height: 24px;
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid rgba(85, 86, 90, 0.3);
  }

  .loupe-panel.open .palette-bento span,
  .loupe-panel.open .palette-bento span.big {
    flex-basis: 0;
    min-width: 0;
    aspect-ratio: auto;
    height: 100%;
    border: none;
    border-radius: 0;
    box-shadow: none;
    transform: none;
  }

  .loupe-panel.open .palette-bento span:hover {
    transform: none;
    filter: brightness(1.12);
  }

  .loupe-panel.open .row-share {
    display: none;
  }

  .loupe-panel.open .palette-list {
    gap: 0;
  }

  .loupe-panel.open .palette-row {
    padding: 6px 8px;
  }

  .loupe-panel.open .row-swatch {
    width: 15px;
    height: 15px;
  }
}

/* ============================================================
   Quieter still: the letter's bar loses the showy shine. A near
   matte porcelain strip — one breath of gradient, a lit top
   edge, a soft seam — system-made, saying nothing.
   ============================================================ */
.pillar-shade {
  background: linear-gradient(180deg, #f7f8f9 0%, #eef0f2 62%, #e7eaec 100%);
  border-bottom: 1px solid rgba(85, 86, 90, 0.32);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(255, 255, 255, 0.2);
}

/* hierarchy: the nav speaks at 14; everything inside a page
   speaks under it. The card names step down to the second size */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile span {
    font-size: 12.5px;
  }
}

/* ============================================================
   The bento returns — that version read better — with the wall's
   own manners: letter-card radii, one ink hairline, no lift. And
   the hex names set like specimens: even letters, even figures,
   one quiet row each.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .palette-bento {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 7px;
    height: auto;
    border: none;
    border-radius: 0;
    overflow: visible;
    margin-bottom: 10px;
  }

  .loupe-panel.open .palette-bento span,
  .loupe-panel.open .palette-bento span.big {
    display: block;
    aspect-ratio: 1;
    height: auto;
    flex-basis: auto;
    border: 1px solid rgba(85, 86, 90, 0.3);
    border-radius: 6px;
    box-shadow: none;
  }

  .loupe-panel.open .palette-bento span.big {
    grid-column: span 2;
    grid-row: span 2;
  }

  .loupe-panel.open .palette-bento span:hover {
    transform: none;
    filter: brightness(1.08);
  }

  .loupe-panel.open .row-hex {
    font-size: 13px;
    letter-spacing: 1.2px;
    font-variant-numeric: tabular-nums;
    color: #16181b;
  }

  .loupe-panel.open .palette-row {
    gap: 10px;
    padding: 6px 8px;
  }
}

/* a title is never cut off: long works wrap to a second line */
@media (min-width: 721px) {
  .loupe-panel.open .gallery-row .g-title {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
}

/* ============================================================
   The hex names settle into chips: two columns of small white
   glass cards, swatch and code together, the same card language
   as the effects. And the Tools bar goes Aqua — the same blue
   the chosen rows wear, white name on top.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .palette-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 7px;
  }

  .loupe-panel.open .palette-row {
    gap: 8px;
    padding: 7px 10px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.42);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
  }

  .loupe-panel.open .palette-row:hover {
    background: linear-gradient(
        0deg,
        rgba(90, 130, 210, 0.16),
        rgba(90, 130, 210, 0.16)
      ),
      rgba(255, 255, 255, 0.42);
  }

  .loupe-panel.open .row-hex {
    font-size: 12.5px;
    letter-spacing: 0.6px;
  }

  /* the bar wears the Aqua */
  .loupe-panel .pod-chrome {
    background: linear-gradient(180deg, #7ba0e5 0%, #5c86d8 55%, #4a75cf 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
  }

  .loupe-panel.open .pod-chrome {
    border-bottom: 1px solid rgba(40, 60, 110, 0.55);
  }

  .pod-name {
    color: #fff;
    text-shadow: 0 1px 1px rgba(25, 40, 80, 0.4);
  }

  .pod-close svg {
    stroke: #fff;
    opacity: 0.75;
  }

  .loupe-panel.open .pod-close:hover svg {
    opacity: 1;
  }
}

/* seven chips, no orphan: the most-used colour takes the full
   first row, the six behind it pair off evenly */
@media (min-width: 721px) {
  .loupe-panel.open .palette-row:first-child {
    grid-column: span 2;
  }
}

/* the chosen effect wears the same Aqua the chosen painting
   wears: the blue card, white name, a light frame on the blue */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35),
      0 1px 4px rgba(20, 24, 32, 0.18);
  }

  .loupe-panel.open .fx-tile.active span {
    color: #fff;
    font-weight: 600;
  }

  .loupe-panel.open .fx-tile.active canvas {
    border-color: rgba(255, 255, 255, 0.55);
  }
}

/* ============================================================
   Flat, everywhere. The cards drop their lifts and inner lights;
   the chosen blue lies as flat as the paint chips. The slider
   joins the system: a hairline track, a flat white-glass thumb
   in the letter's radius, Aqua while your finger is on it.
   ============================================================ */
@media (min-width: 721px) {
  .loupe-panel.open .fx-tile,
  .loupe-panel.open .fx-tile:hover,
  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover,
  .loupe-panel.open .palette-row,
  .loupe-panel.open .palette-row:hover,
  .pod-reset,
  .pod-reset:hover,
  .pod-reset:active {
    box-shadow: none;
  }

  .loupe-panel.open .loupe-slider {
    height: 2px;
    border-radius: 1px;
    background: rgba(35, 38, 43, 0.25);
  }

  .loupe-panel.open .loupe-slider::-webkit-slider-thumb {
    width: 14px;
    height: 14px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid rgba(85, 86, 90, 0.45);
    box-shadow: none;
  }

  .loupe-panel.open .loupe-slider:hover::-webkit-slider-thumb,
  .loupe-panel.open .loupe-slider:active::-webkit-slider-thumb {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    border-color: rgba(40, 60, 110, 0.6);
  }

  .loupe-panel.open .loupe-slider::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid rgba(85, 86, 90, 0.45);
    box-shadow: none;
  }

  .loupe-panel.open .loupe-slider:hover::-moz-range-thumb,
  .loupe-panel.open .loupe-slider:active::-moz-range-thumb {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    border-color: rgba(40, 60, 110, 0.6);
  }
}

/* ============================================================
   The key is the wall in miniature: a tiny window with the Aqua
   bar on top and three faint rows sleeping under glass. Click
   it and the same thing stands up at full size — the connection
   reads by itself.
   ============================================================ */
@media (min-width: 721px) {
  .pod-key,
  .pod-key:hover,
  .pod-key:active {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    width: 38px;
    height: 32px;
    padding: 0;
    overflow: hidden;
    border: 1px solid rgba(85, 86, 90, 0.55);
    border-radius: 0;
    background: rgba(252, 253, 255, 0.6);
    -webkit-backdrop-filter: blur(10px) saturate(1.15);
    backdrop-filter: blur(10px) saturate(1.15);
    box-shadow: 0 2px 8px rgba(20, 24, 32, 0.25);
  }

  .pod-key-sign {
    display: none;
  }

  /* the little Aqua bar */
  .pod-key::before {
    content: "";
    flex: none;
    height: 8px;
    background: linear-gradient(180deg, #7ba0e5 0%, #5c86d8 55%, #4a75cf 100%);
    border-bottom: 1px solid rgba(40, 60, 110, 0.5);
  }

  /* three rows asleep under the glass */
  .pod-key::after {
    content: "";
    flex: 1 1 auto;
    margin: 3px 5px;
    background: repeating-linear-gradient(
      180deg,
      transparent 0 4px,
      rgba(85, 86, 90, 0.4) 4px 5px
    );
  }

  .pod-key:hover {
    background: rgba(252, 253, 255, 0.78);
  }

  .pod-key:active .pod-key-sign {
    transform: none;
  }
}

/* ============================================================
   The marks keep quiet about their names. From arrival the
   dashes are there — the reading's ruler — but the words only
   surface when the cursor comes to ask. Approach the column and
   every name steps forward together; leave and they sink back.
   ============================================================ */
@media (min-width: 721px) {
  body .scroll-marks a .tooltip,
  body .scroll-marks a:hover .tooltip,
  body .scroll-marks a.active .tooltip {
    opacity: 0;
    transition: opacity 0.25s ease;
    pointer-events: none;
  }

  body .scroll-marks:hover a .tooltip,
  body .scroll-marks:hover a:hover .tooltip,
  body .scroll-marks:hover a.active .tooltip {
    opacity: 1;
  }
}

/* ============================================================
   The key returns to its keycap self — the rail's own raised
   face — but with one private touch: set into it, like a plate
   on a door, a small framed swatch of the very painting on the
   wall. Change the wallpaper and the key changes with it.
   ============================================================ */
@media (min-width: 721px) {
  .pod-key,
  .pod-key:hover,
  .pod-key:active {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 34px;
    padding: 0;
    overflow: visible;
    border: none;
    border-radius: 0;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
      inset -1px -1px 0 rgba(85, 86, 90, 0.45);
  }

  .pod-key {
    background: rgba(240, 240, 237, 0.5);
  }

  .pod-key:hover {
    background: rgba(248, 248, 245, 0.62);
  }

  .pod-key:active {
    background: rgba(160, 160, 156, 0.42);
    box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.45),
      inset -1px -1px 0 rgba(255, 255, 255, 0.8);
  }

  .pod-key::before,
  .pod-key::after {
    content: none;
  }

  .pod-key-sign {
    display: block;
    width: 24px;
    height: 22px;
    background-size: cover;
    border: 1px solid rgba(85, 86, 90, 0.55);
    box-shadow: inset 0 0 0 1px rgba(251, 251, 249, 0.35);
  }

  .pod-key:active .pod-key-sign {
    transform: translate(1px, 1px);
  }
}




/* the disc as it was, tidied a touch: same red, one clean rim,
   one soft light, nothing else stacked on it */
.pillar-shade .shade-close {
  background: linear-gradient(180deg, #ff746b 0%, #f2544a 55%, #e83e33 100%);
  box-shadow: inset 0 0 0 0.5px rgba(130, 20, 12, 0.35),
    inset 0 1px 0.5px rgba(255, 255, 255, 0.5),
    0 0.5px 1px rgba(70, 15, 10, 0.25);
}

/* flatter and quieter still: one muted red, one hairline, no
   light, no depth — a dot that minds its own business */
.pillar-shade .shade-close {
  background: #dd5348;
  box-shadow: inset 0 0 0 0.5px rgba(130, 20, 12, 0.3);
}

/* ============================================================
   THE PHONE GETS THE SAME MACHINE

   No more leftover chip tray: on small screens the painting key
   sits at the top right corner, and tapping it raises a sheet
   above the bottom rail wearing the very same clothes as the
   desktop wall — Aqua bar with its X, the standing nav, flat
   white cards, the reset at the foot. One design, two sizes.
   ============================================================ */
@media (max-width: 720px) {
  /* the chip tray retires here too */
  .loupe-panel .loupe-bar {
    display: none;
  }

  /* shut: the painting keycap alone, top right */
  .loupe-panel:not(.open),
  .loupe-panel:not(.open):hover {
    top: 14px;
    right: 12px;
    bottom: auto;
    left: auto;
    width: auto;
    max-height: none;
    padding: 0;
    overflow: visible;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: none;
    box-shadow: none;
  }

  .pod-key {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 36px;
    padding: 0;
    border: none;
    border-radius: 0;
    cursor: pointer;
    background: rgba(240, 240, 237, 0.5);
    box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
      inset -1px -1px 0 rgba(85, 86, 90, 0.45);
  }

  .pod-key-sign {
    display: block;
    width: 26px;
    height: 24px;
    background-size: cover;
    border: 1px solid rgba(85, 86, 90, 0.55);
    box-shadow: inset 0 0 0 1px rgba(251, 251, 249, 0.35);
  }

  /* open: a sheet above the bottom rail, in the wall's clothes */
  .loupe-panel.open {
    left: 12px;
    right: 12px;
    top: auto;
    bottom: 64px;
    width: auto;
    max-height: 72vh;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 0;
    overflow: hidden;
    border-radius: 0;
    background: rgba(252, 253, 255, 0.8);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    backdrop-filter: blur(14px) saturate(1.2);
    border: 1px solid rgba(85, 86, 90, 0.5);
    box-shadow: 0 10px 30px rgba(20, 24, 32, 0.3);
  }

  .loupe-panel.open .pod-chrome {
    display: flex;
    align-items: center;
    flex: none;
    order: -2;
    height: 30px;
    padding: 0 9px;
    background: linear-gradient(180deg, #7ba0e5 0%, #5c86d8 55%, #4a75cf 100%);
    border-bottom: 1px solid rgba(40, 60, 110, 0.55);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
  }

  .pod-back {
    display: none;
  }

  .pod-name {
    flex: 1 1 auto;
    text-align: center;
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.3px;
    color: #fff;
    text-shadow: 0 1px 1px rgba(25, 40, 80, 0.4);
    padding-left: 24px;
    pointer-events: none;
  }

  .pod-close {
    flex: none;
    width: 24px;
    height: 24px;
    margin-left: auto;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    cursor: pointer;
  }

  .pod-close svg {
    width: 10px;
    height: 10px;
    fill: none;
    stroke: #fff;
    stroke-width: 1.8;
    stroke-linecap: square;
    opacity: 0.85;
  }

  /* the standing nav, touch-height rows */
  .loupe-panel.open .pod-menu {
    display: flex;
    flex-direction: column;
    flex: none;
    order: -1;
    padding: 0;
    background: rgba(252, 253, 255, 0.62);
    border-bottom: 1px solid rgba(85, 86, 90, 0.4);
  }

  .pod-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    height: 38px;
    padding: 0 14px;
    border: none;
    background: none;
    cursor: pointer;
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 15px;
    color: #16181b;
    text-align: left;
  }

  .pod-row + .pod-row {
    border-top: 1px solid rgba(85, 86, 90, 0.16);
  }

  .pod-row.active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    color: #fff;
  }

  .pod-row-go {
    display: flex;
    align-items: center;
    color: rgba(35, 38, 43, 0.3);
  }

  .pod-row.active .pod-row-go {
    color: rgba(255, 255, 255, 0.7);
  }

  .pod-row-go svg {
    width: 5.5px;
    height: 9px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: square;
    display: block;
  }

  /* the pages scroll inside the sheet */
  .loupe-panel.open .tool-drawer {
    flex: 1 1 auto;
    min-height: 0;
  }

  .loupe-panel.open .tool-drawer-inner {
    max-height: none;
    height: 100%;
    overflow-y: auto;
    background: none;
  }

  .loupe-panel.open .loupe-header {
    display: none;
  }

  /* the same flat content clothes as the wall */
  .loupe-panel.open .gallery-row {
    gap: 12px;
    padding: 9px 14px;
    border-radius: 0;
    width: 100%;
  }

  .loupe-panel.open .gallery-row img {
    display: block;
    width: 54px;
    height: 40px;
    object-fit: cover;
    border-radius: 4px;
    border: 1px solid rgba(85, 86, 90, 0.3);
    box-shadow: none;
    flex-shrink: 0;
  }

  .loupe-panel.open .gallery-row .g-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }

  .loupe-panel.open .gallery-row .g-artist {
    font-size: 15px;
    color: #16181b;
  }

  .loupe-panel.open .gallery-row .g-title {
    font-size: 13px;
    color: rgba(22, 24, 27, 0.76);
    white-space: normal;
  }

  .loupe-panel.open .gallery-row.active {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    border-radius: 0;
  }

  .loupe-panel.open .gallery-row.active .g-artist {
    color: #fff;
  }

  .loupe-panel.open .gallery-row.active .g-title {
    color: rgba(255, 255, 255, 0.85);
  }

  .loupe-panel.open .fx-tile,
  .loupe-panel.open .fx-tile:hover {
    padding: 7px 7px 8px;
    gap: 7px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.42);
    box-shadow: none;
  }

  .loupe-panel.open .fx-tile canvas {
    border-radius: 4px;
    border: 1px solid rgba(85, 86, 90, 0.25);
  }

  .loupe-panel.open .fx-tile span {
    text-align: left;
    padding: 1px 3px 2px;
    font-size: 13px;
    color: rgba(35, 38, 43, 0.85);
  }

  .loupe-panel.open .fx-tile.active,
  .loupe-panel.open .fx-tile.active:hover {
    background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
    box-shadow: none;
  }

  .loupe-panel.open .fx-tile.active span {
    color: #fff;
    font-weight: 600;
  }

  .loupe-panel.open .fx-tile.active canvas {
    border-color: rgba(255, 255, 255, 0.55);
  }

  .loupe-panel.open .palette-bento span,
  .loupe-panel.open .palette-bento span.big {
    border: 1px solid rgba(85, 86, 90, 0.3);
    border-radius: 6px;
    box-shadow: none;
  }

  .loupe-panel.open .palette-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 7px;
  }

  .loupe-panel.open .palette-row {
    gap: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.42);
  }

  .loupe-panel.open .palette-row:first-child {
    grid-column: span 2;
  }

  .loupe-panel.open .row-hex {
    font-size: 13px;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: #16181b;
  }

  .loupe-panel.open .row-share {
    display: none;
  }

  /* the foot: reset, reachable */
  .loupe-panel.open .pod-foot {
    display: flex;
    justify-content: flex-end;
    flex: none;
    order: 99;
    padding: 8px 12px;
    border-top: 1px solid rgba(85, 86, 90, 0.3);
  }

  .loupe-panel.open .pod-foot .loupe-now {
    display: none;
  }

  .pod-reset {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px 8px 12px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    background: rgba(255, 255, 255, 0.5);
  }

  .pod-reset svg {
    width: 13px;
    height: 13px;
    fill: none;
    stroke: #23262b;
    stroke-width: 1.5;
    stroke-linecap: square;
    opacity: 0.8;
  }

  .pod-reset span {
    font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
    font-size: 13.5px;
    line-height: 1;
    color: #16181b;
  }
}

/* ============================================================
   The rail stays a rail. On phones it no longer lies down along
   the foot — it stands at the left edge exactly as on the desk,
   every keycap in its column, and the page simply starts beside
   it. The tool sheet drops to the true bottom now that the foot
   is free.
   ============================================================ */
@media (max-width: 720px) {
  .rail {
    top: 0;
    bottom: 0;
    left: 0;
    right: auto;
    width: var(--rail-width);
    height: auto;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    gap: 0;
    padding: 16px 0 0;
  }

  .rail-avatar {
    width: 34px;
    height: 34px;
    font-size: 14px;
  }

  .rail-nav,
  .rail-bottom {
    flex-direction: column;
    align-items: center;
    margin: 0;
    gap: 0;
  }

  .rail-group {
    flex-direction: column;
    align-items: center;
    padding: 0;
    margin: 0;
  }

  .rail-subs {
    flex-direction: column;
    gap: 0;
    margin: 0;
  }

  /* the paper starts beside the rail, not under it */
  body::after {
    left: var(--rail-width);
    right: 0;
    width: auto;
  }

  .page,
  body.theme-painting .page {
    margin-left: var(--rail-width);
    padding: 10vh 20px 18vh;
  }

  .hero-cue {
    left: calc(50% + var(--rail-width) / 2);
    bottom: 32px;
  }

  /* the foot is free again: the sheet sits at the true bottom */
  .loupe-panel.open {
    bottom: 12px;
    left: calc(var(--rail-width) + 8px);
    right: 8px;
  }

  .loupe-panel:not(.open),
  .loupe-panel:not(.open):hover {
    top: 12px;
    right: 10px;
  }
}

/* short phones: if the column runs long, the rail scrolls inside
   itself rather than spilling over the page */
@media (max-width: 720px) {
  .rail {
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: none;
  }

  .rail::-webkit-scrollbar {
    display: none;
  }
}

/* shut is shut, at every size: nothing of the window's innards —
   bar, nav, foot — shows until it opens. Only the key remains. */
.loupe-panel:not(.open) .pod-chrome,
.loupe-panel:not(.open) .pod-menu,
.loupe-panel:not(.open) .pod-foot {
  display: none;
}

/* ============================================================
   The sheet breathes on phones too. Arrival shows the painting
   with the paper resting low; a swipe up raises it, exactly as
   the desk does. The fold control returns — the disc at the
   sheet's top LEFT here, its X always visible for fingers — and
   folding drops the paper to a peek at the foot so the painting
   has the whole room.
   ============================================================ */
@media (max-width: 720px) {
  /* the glass follows the sheet again instead of filling the screen */
  body::after {
    top: var(--pillar-top, 0px);
    left: var(--rail-width);
    right: 0;
    width: auto;
  }

  body.pillar-closed::after {
    top: calc(100vh - 49px);
  }

  /* the band returns, riding the paper's top edge */
  .pillar-shade {
    display: flex;
    left: var(--rail-width);
    right: 0;
    width: auto;
  }

  /* the fold control sits at the top left of the paper */
  .pillar-shade .shade-close {
    left: 10px;
    right: auto;
  }

  /* fingers cannot hover: the X shows whenever the sheet is up */
  .pillar-shade .shade-close svg {
    opacity: 1;
  }

  body.pillar-closed .shade-close svg {
    opacity: 0; /* folded, the disc alone says "come back" */
  }

  /* the letter starts below the resting band, which sits lower
     here (66vh, matching rest() in js/main.js) */
  body.theme-painting .page {
    padding: calc(72vh + 30px) 20px 18vh;
  }
}

/* the phone's fold control, quieted to system: no disc, no red —
   a bare ink X cut like the wall's own, working both ways */
@media (max-width: 720px) {
  .pillar-shade .shade-close,
  .pillar-shade .shade-close:hover {
    width: 24px;
    height: 24px;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  .pillar-shade .shade-close svg {
    width: 10px;
    height: 10px;
    stroke: #23262b;
    stroke-width: 1.9;
    stroke-linecap: square;
    opacity: 0.6;
  }

  body.pillar-closed .shade-close svg {
    opacity: 0.6; /* the same mark is the way back */
  }
}

/* the fold control, in Her's voice: one warm coral circle, flat
   as paint, a cream X resting in it. Folded, the dot stays and
   the X sleeps. */
@media (max-width: 720px) {
  .pillar-shade .shade-close,
  .pillar-shade .shade-close:hover {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #e0573f;
    box-shadow: none;
  }

  .pillar-shade .shade-close svg {
    width: 8px;
    height: 8px;
    stroke: #fdf3ec;
    stroke-width: 2;
    stroke-linecap: square;
    opacity: 1;
  }

  body.pillar-closed .shade-close svg {
    opacity: 0;
  }
}

/* the red dot as the Mac actually draws it: traffic-light red,
   a breath of darker rim, the dark-red X inside — nothing more */
@media (max-width: 720px) {
  .pillar-shade .shade-close,
  .pillar-shade .shade-close:hover {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ff5f57;
    box-shadow: inset 0 0 0 0.5px rgba(160, 40, 30, 0.5);
  }

  .pillar-shade .shade-close svg {
    width: 7px;
    height: 7px;
    stroke: #7a1f16;
    stroke-width: 2.2;
    stroke-linecap: round;
    opacity: 1;
  }

  body.pillar-closed .shade-close svg {
    opacity: 0;
  }
}

/* cleaner still: the dot alone, perfectly round, no glyph at
   all — as the traffic lights rest. Tap folds, tap unfolds. */
@media (max-width: 720px) {
  .pillar-shade .shade-close,
  .pillar-shade .shade-close:hover {
    flex: none;
    width: 13px;
    height: 13px;
    min-width: 13px;
    min-height: 13px;
    padding: 0;
    border-radius: 50%;
    background: #ff5f57;
    box-shadow: inset 0 0 0 0.5px rgba(160, 40, 30, 0.45);
  }

  .pillar-shade .shade-close svg,
  body.pillar-closed .shade-close svg {
    display: none;
  }
}

/* subtler: the same quiet dot the desk wears — small, muted,
   one hairline, minding its own business */
@media (max-width: 720px) {
  .pillar-shade .shade-close,
  .pillar-shade .shade-close:hover {
    width: 11px;
    height: 11px;
    min-width: 11px;
    min-height: 11px;
    background: #dd5348;
    box-shadow: inset 0 0 0 0.5px rgba(130, 20, 12, 0.3);
  }
}

/* the key never rides inside its own window, at any size */
.loupe-panel.open .pod-key {
  display: none;
}

/* ============================================================
   The phone rail finds its rhythm: even air between every key.
   Portrait, then the sign groups at a steady beat, the settings
   held low, the exits at the very foot — nothing crowded,
   nothing adrift.
   ============================================================ */
@media (max-width: 720px) {
  .rail {
    padding: 14px 0 12px;
  }

  .rail-avatar {
    margin: 0 0 16px;
  }

  .rail-nav {
    gap: 18px;
    margin: 0;
  }

  .rail-group {
    gap: 9px;
    margin: 0;
  }

  .rail-subs {
    gap: 9px;
    margin: 0;
  }

  /* the settings sink to the lower third, exits to the foot */
  .rail-tools {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
  }

  .rail-bottom {
    margin: 14px 0 0;
    gap: 15px;
    padding-bottom: 4px;
  }
}

/* ============================================================
   The rail set true: its right-hand rule moves outside the
   width, so the column of keys centres on the visible field
   exactly — equal air left and right of every button. And the
   press quiets down: no inverted bevel plate, just a shade of
   weight under the chosen key.
   ============================================================ */
.rail {
  width: var(--rail-width);
  border-right: none;
  box-shadow: inset 1px 0 0 rgba(251, 251, 249, 0.75),
    inset -1px 0 0 rgba(85, 86, 90, 0.18),
    1px 0 0 rgba(85, 86, 90, 0.5);
}

/* the press, simplified: a quiet darker face, one hairline */
.rail-group.active .rail-link,
.rail-nav .rail-link.pressed {
  background: rgba(174, 174, 170, 0.5);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.rail-group.active .rail-link .rail-emoji,
.rail-nav .rail-link.pressed .rail-emoji {
  transform: none;
}

/* ============================================================
   The rail's name-cards line up: whichever key speaks, its card
   opens on the same line just clear of the rail — the left
   column simply reaches further. And each card gets a little
   comic tail low on its left side, pointing home to its key,
   the way a person would draw it.
   ============================================================ */
.rail-link .tooltip,
.rail-sub .tooltip {
  border-radius: 7px;
  overflow: visible;
}

/* one shared line, just right of the rail */
.rail-subs .rail-sub:nth-child(odd) .tooltip {
  left: calc(100% + 36px);
}

.rail-subs .rail-sub:nth-child(even) .tooltip {
  left: calc(100% + 14px);
}

/* the tail, set low like a speech balloon's */
.rail-link .tooltip::before,
.rail-sub .tooltip::before {
  content: "";
  position: absolute;
  left: -4.5px;
  bottom: 6px;
  width: 8px;
  height: 8px;
  background: var(--cream-solid);
  border-left: 1px solid var(--warm-edge);
  border-bottom: 1px solid var(--warm-edge);
  transform: rotate(45deg);
  border-bottom-left-radius: 2px;
}

/* subtler, and spoken from below: the card slips out to the
   lower right of its key, smaller and lighter, its little tail
   now on top, reaching up toward the key it names */
.rail-link .tooltip,
.rail-sub .tooltip {
  top: calc(100% + 7px);
  bottom: auto;
  transform: translateY(-3px);
  font-size: 11px;
  padding: 5px 9px;
  border-radius: 6px;
  box-shadow: 0 2px 6px rgba(22, 28, 38, 0.14);
}

.rail-link:hover .tooltip,
.rail-sub:hover .tooltip {
  transform: translateY(0);
}

.rail-link .tooltip::before,
.rail-sub .tooltip::before {
  left: 9px;
  bottom: auto;
  top: -4px;
  width: 7px;
  height: 7px;
  border: none;
  border-left: 1px solid var(--warm-edge);
  border-top: 1px solid var(--warm-edge);
  transform: rotate(45deg);
  border-radius: 0;
  border-top-left-radius: 2px;
}

/* the balloon floats up-right of its key; the tail hangs from
   its bottom-left corner, slanting home diagonally */
.rail-link .tooltip,
.rail-sub .tooltip {
  top: auto;
  bottom: calc(100% + 6px);
  transform: translateY(3px);
}

.rail-link:hover .tooltip,
.rail-sub:hover .tooltip {
  transform: translateY(0);
}

.rail-link .tooltip::before,
.rail-sub .tooltip::before {
  top: auto;
  bottom: -4px;
  left: 7px;
  border: none;
  border-left: 1px solid var(--warm-edge);
  border-bottom: 1px solid var(--warm-edge);
  transform: rotate(45deg);
  border-radius: 0;
  border-bottom-left-radius: 2px;
}

/* ============================================================
   The name-card, settled: it sits beside its key at the key's
   own height, like a speech balloon in the margin — the tail on
   its left edge, centred, pointing straight home. (The Slack
   sidebar manner.)
   ============================================================ */
.rail-link .tooltip,
.rail-sub .tooltip {
  top: 50%;
  bottom: auto;
  transform: translateY(-50%) translateX(-3px);
  border-radius: 8px;
  padding: 6px 11px;
  font-size: 11.5px;
}

.rail-link:hover .tooltip,
.rail-sub:hover .tooltip {
  transform: translateY(-50%) translateX(0);
}

.rail-link .tooltip::before,
.rail-sub .tooltip::before {
  top: 50%;
  bottom: auto;
  left: -4px;
  margin-top: -3.5px;
  width: 7px;
  height: 7px;
  border: none;
  border-left: 1px solid var(--warm-edge);
  border-bottom: 1px solid var(--warm-edge);
  transform: rotate(45deg);
  border-radius: 0 0 0 2px;
}

/* simplest: no tail, no theatre — a small quiet label beside
   the key, and nothing else */
.rail-link .tooltip,
.rail-sub .tooltip {
  border-radius: 6px;
  padding: 5px 9px;
  font-size: 11.5px;
  box-shadow: 0 1px 3px rgba(22, 28, 38, 0.12);
}

.rail-link .tooltip::before,
.rail-sub .tooltip::before {
  content: none;
}

/* the key keeps its face under the cursor: the wash lies over
   the white keycap instead of replacing it, and the hop retires */
.rail-nav .rail-link:hover,
.rail-nav .rail-sub:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(255, 255, 255, 0.62);
  transform: none;
}

/* ============================================================
   Optically centred, not just mathematically: the well and the
   keys drop their one-sided bevels (bright left, dark right —
   the thing that made every face look pushed left) for even
   hairline rings. Same geometry, now the eye agrees with it.
   ============================================================ */
.rail-group,
.rail-group.active {
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.rail-nav .rail-link,
.rail-nav .rail-sub {
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.rail-nav .rail-link:hover,
.rail-nav .rail-sub:hover {
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.4);
}

.rail-group.active .rail-link,
.rail-nav .rail-link.pressed,
.rail-nav .rail-sub.active {
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.4);
}

/* ============================================================
   ONE BLUE, NOT THREE

   The wall calms down into the rail's own grey family. The bar
   goes porcelain with ink; the chosen tool sits pressed in grey
   like a rail key; the blue keeps exactly two jobs — the wash
   under the cursor, and the ring around the chosen painting.
   And the wallpapers become a grid of pictures, the way a
   wallpaper picker should be: swatches first, the placard
   naming the current one beneath.
   ============================================================ */

/* ---- the bar: porcelain, ink */
.loupe-panel .pod-chrome {
  background: linear-gradient(180deg, #f7f8f9 0%, #eef0f2 62%, #e7eaec 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.loupe-panel.open .pod-chrome {
  border-bottom: 1px solid rgba(85, 86, 90, 0.35);
}

.pod-name {
  color: #23262b;
  text-shadow: none;
}

.pod-close svg {
  stroke: #23262b;
  opacity: 0.55;
}

.loupe-panel.open .pod-close:hover svg {
  opacity: 1;
}

/* ---- the nav: chosen = pressed grey, like a rail key */
.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover,
.loupe-panel.open .pod-row:active {
  background: rgba(174, 174, 170, 0.5);
  color: #16181b;
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.loupe-panel.open .pod-row.active .pod-row-go,
.loupe-panel.open .pod-row:active .pod-row-go {
  color: rgba(35, 38, 43, 0.45);
}

/* ---- the wallpapers: a grid of pictures */
.loupe-panel.open .gallery-choices {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 12px 14px 10px;
}

.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover {
  display: block;
  width: auto;
  height: auto;
  padding: 0;
  margin: 0;
  background: none;
  border: none;
  border-radius: 4px;
  box-shadow: none;
}

.loupe-panel.open .gallery-row + .gallery-row {
  border-top: none;
  box-shadow: none;
}

.loupe-panel.open .gallery-row img {
  display: block;
  width: 100%;
  height: 54px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid rgba(85, 86, 90, 0.3);
  box-shadow: none;
  transition: box-shadow 0.12s ease, border-color 0.12s ease;
}

.loupe-panel.open .gallery-row:hover img {
  border-color: rgba(90, 130, 210, 0.7);
  box-shadow: 0 0 0 1px rgba(90, 130, 210, 0.5);
}

/* the one blue that means "chosen" */
.loupe-panel.open .gallery-row.active img {
  border-color: #4a75cf;
  box-shadow: 0 0 0 1.5px #4a75cf;
}

.loupe-panel.open .gallery-row .g-meta {
  display: none;
}

/* the placard under the grid names the current painting */
.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-now {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0 14px 4px;
}

.loupe-panel.open .loupe-now .now-work {
  font-size: 14px;
  line-height: 1.3;
  color: #16181b;
}

.loupe-panel.open .loupe-now .now-hand {
  font-size: 12.5px;
  line-height: 1.3;
  color: rgba(22, 24, 27, 0.7);
}

/* the gallery page grid needs its own breathing room, not the
   list's full-bleed manner */
.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-body {
  padding: 0 0 10px;
  gap: 0;
}

/* ============================================================
   The accordion: every room folds out right under its own row.
   The menu is the whole wall now and scrolls as one; the open
   row's chevron turns down; the drawer stands empty behind.
   ============================================================ */
.loupe-panel.open .pod-menu {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  border-bottom: none;
}

.loupe-panel.open .pod-menu .tool-section {
  border-bottom: 1px solid rgba(85, 86, 90, 0.16);
}

.loupe-panel.open .pod-row.active .pod-row-go svg {
  transform: rotate(90deg);
}

.pod-row-go svg {
  transition: transform 0.18s ease;
}

.loupe-panel.open .tool-drawer {
  display: none;
}

/* open rows speak the blue again: the letter's wash over white,
   not the grey press */
.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover,
.loupe-panel.open .pod-row:active {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.2),
      rgba(90, 130, 210, 0.2)
    ),
    rgba(255, 255, 255, 0.5);
  color: #16181b;
  box-shadow: none;
}

.loupe-panel.open .pod-row.active .pod-row-go {
  color: rgba(35, 38, 43, 0.5);
}

/* ============================================================
   The rail sheds its box: no lit left edge, no double moldings —
   one hairline on its right, parting it from the page, and
   nothing else drawn around it. Its dividers give up their
   engraved echo too: one line each, no white twin beneath.
   ============================================================ */
.rail {
  box-shadow: 1px 0 0 rgba(85, 86, 90, 0.4);
}

.rail-bottom::before,
.rail-tools::before,
.rail-avatar::after,
.rail-nav::before,
.rail-nav::after {
  box-shadow: none;
}

/* ============================================================
   Rows that read as rows: each tool row wears its own pale face
   on the glass, parted by hairlines, so the shut ones still
   look like things to press — not loose words. The wall behind
   stays the left rail's exact glass.
   ============================================================ */
.loupe-panel.open {
  background: rgba(207, 207, 203, 0.42);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
}

.loupe-panel.open .pod-row {
  background: rgba(252, 253, 255, 0.5);
  border-bottom: 1px solid rgba(85, 86, 90, 0.18);
}

.loupe-panel.open .pod-row:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(252, 253, 255, 0.5);
}

.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover,
.loupe-panel.open .pod-row:active {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.2),
      rgba(90, 130, 210, 0.2)
    ),
    rgba(252, 253, 255, 0.55);
  border-bottom: 1px solid rgba(85, 86, 90, 0.18);
}

/* ============================================================
   ONE MACHINE, TWO COLUMNS

   The wall borrows the rail's own parts outright. Its title
   speaks like LANG and SIZE do — small engraved capitals on a
   flat strip. Its rows are keycap faces. Its opened rooms are
   the sunken wells the rail sets its keys in. Same greys, same
   rings, same voice, left and right.
   ============================================================ */
.loupe-panel .pod-chrome {
  background: rgba(240, 240, 237, 0.6);
  box-shadow: none;
}

.loupe-panel.open .pod-chrome {
  border-bottom: 1px solid rgba(85, 86, 90, 0.3);
}

.pod-name {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: #55565a;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6);
}

/* rows: the rail's keycap face, one hairline apart */
.loupe-panel.open .pod-row {
  background: rgba(240, 240, 237, 0.5);
  border-bottom: 1px solid rgba(85, 86, 90, 0.25);
}

.loupe-panel.open .pod-row:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover,
.loupe-panel.open .pod-row:active {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.2),
      rgba(90, 130, 210, 0.2)
    ),
    rgba(240, 240, 237, 0.55);
  border-bottom: 1px solid rgba(85, 86, 90, 0.25);
}

/* opened rooms: the rail's sunken well */
.loupe-panel.open .pod-menu .tool-section {
  background: rgba(190, 190, 186, 0.3);
  border-bottom: 1px solid rgba(85, 86, 90, 0.25);
}

/* the reset takes the keycap face too */
.pod-reset,
.pod-reset:hover,
.pod-reset:active {
  border-radius: 0;
}

.pod-reset {
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.pod-reset:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

.pod-reset:active {
  background: rgba(174, 174, 170, 0.5);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.4);
}

.pod-reset:active svg {
  stroke: #23262b;
}

.pod-reset:active span {
  color: #16181b;
}

.loupe-panel.open .pod-foot {
  border-top: 1px solid rgba(85, 86, 90, 0.3);
}

/* breathing room in the wall: the placard keeps its distance
   from the next row, and every room's floor gets some air */
.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-now {
  padding: 2px 14px 14px;
}

.loupe-panel.open .gallery-choices {
  padding: 14px 14px 10px;
}

.loupe-panel.open .pod-menu .tool-section .loupe-body {
  padding-top: 14px;
  padding-bottom: 16px;
}

.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-body {
  padding-top: 0;
  padding-bottom: 2px;
}

/* the portrait stands bare, as it always did: no ring, no face */
.rail-group:nth-child(1) .rail-link,
.rail-group:nth-child(1) .rail-link:hover,
.rail-group:nth-child(1).active .rail-link,
.rail-group:nth-child(1) .rail-link.pressed {
  background: none;
  box-shadow: none;
}

/* the first group carries no box either: the portrait and its
   signs stand directly on the rail */
.rail-group:nth-child(1),
.rail-group:nth-child(1).active {
  background: none;
  box-shadow: none;
}

/* ============================================================
   The wallpapers return to their iPod list: one painting per
   row — swatch, artist, work — and the chosen one riding the
   full-width Aqua bar. The grid retires; the list names
   everything, so the placard sleeps again.
   ============================================================ */
.loupe-panel.open .gallery-choices {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}

.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: auto;
  margin: 0;
  padding: 8px 14px;
  border: none;
  border-radius: 0;
  box-shadow: none;
  text-align: left;
}

.loupe-panel.open .gallery-row {
  background: none;
}

.loupe-panel.open .gallery-row + .gallery-row {
  border-top: 1px solid rgba(85, 86, 90, 0.14);
}

.loupe-panel.open .gallery-row:hover {
  background: rgba(90, 130, 210, 0.16);
}

.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover {
  background: linear-gradient(180deg, #6f97e0 0%, #4a75cf 100%);
}

.loupe-panel.open .gallery-row img,
.loupe-panel.open .gallery-row.active img {
  display: block;
  width: 54px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid rgba(85, 86, 90, 0.3);
  box-shadow: none;
  flex-shrink: 0;
}

.loupe-panel.open .gallery-row.active img {
  border-color: rgba(251, 251, 249, 0.85);
}

.loupe-panel.open .gallery-row .g-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.loupe-panel.open .gallery-row .g-artist {
  font-size: 14px;
  line-height: 1.15;
  color: #16181b;
}

.loupe-panel.open .gallery-row .g-title {
  font-size: 12.5px;
  line-height: 1.25;
  color: rgba(22, 24, 27, 0.76);
  white-space: normal;
}

.loupe-panel.open .gallery-row.active .g-artist {
  color: #fff;
}

.loupe-panel.open .gallery-row.active .g-title {
  color: rgba(255, 255, 255, 0.85);
}

/* the list names every painting; the placard rests */
.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-now {
  display: none;
}

.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-body {
  padding: 0 0 4px;
}

/* ============================================================
   Selection wraps, nothing floats. The wallpaper rows become
   inset capsules — the wash and the Aqua bar hug each row with
   the letter's radius, sidebar-style, instead of running edge
   to edge. The effect cards settle down: quieter glass, less
   lift, the same rounded selection language.
   ============================================================ */
.loupe-panel.open .gallery-choices {
  padding: 6px 0 8px;
  gap: 1px;
}

.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover {
  width: calc(100% - 16px);
  margin: 0 8px;
  padding: 7px 8px;
  border-radius: 6px;
}

.loupe-panel.open .gallery-row + .gallery-row {
  border-top: none;
}

/* the effect cards, quieted */
.loupe-panel.open .fx-previews {
  gap: 10px 8px;
}

.loupe-panel.open .fx-tile {
  background: rgba(255, 255, 255, 0.3);
}

.loupe-panel.open .fx-tile,
.loupe-panel.open .fx-tile:hover,
.loupe-panel.open .fx-tile.active,
.loupe-panel.open .fx-tile.active:hover {
  padding: 6px 6px 7px;
  border-radius: 6px;
  box-shadow: none;
}

.loupe-panel.open .fx-tile:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(255, 255, 255, 0.3);
}

.loupe-panel.open .fx-tile span {
  font-size: 12.5px;
  padding: 2px 3px 0;
}

/* ============================================================
   No masthead. The wall opens straight onto Wallpaper; all
   that remains above is the small X on bare glass. And the
   rooms breathe: taller rows, more air around every list.
   ============================================================ */
.loupe-panel .pod-chrome,
.loupe-panel.open .pod-chrome {
  height: 26px;
  padding: 0 8px;
  background: none;
  border-bottom: none;
  box-shadow: none;
}

.pod-name {
  display: none;
}

/* air */
.loupe-panel.open .pod-row {
  height: 36px;
  padding: 0 16px;
}

.loupe-panel.open .gallery-choices {
  padding: 8px 0 10px;
  gap: 3px;
}

.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover {
  padding: 9px 10px;
}

.loupe-panel.open .gallery-row .g-meta {
  gap: 3px;
}

.loupe-panel.open .pod-menu .tool-section .loupe-body {
  padding-top: 16px;
  padding-bottom: 20px;
}

.loupe-panel.open .tool-section[data-tool="gallery"] .loupe-body {
  padding-top: 0;
  padding-bottom: 6px;
}

/* wider air still: taller capsules, real gaps between them */
.loupe-panel.open .gallery-choices {
  padding: 10px 0 12px;
  gap: 6px;
}

.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover {
  padding: 11px 12px;
  gap: 14px;
}

/* the spacing holds in every state: hovered, chosen, and the
   instant the mouse is down — one geometry throughout */
.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row:active,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover,
.loupe-panel.open .gallery-row.active:active {
  padding: 11px 12px;
  gap: 14px;
  width: calc(100% - 16px);
  margin: 0 8px;
  border-radius: 6px;
}

.loupe-panel.open .pod-row,
.loupe-panel.open .pod-row:hover,
.loupe-panel.open .pod-row:active,
.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover {
  height: 36px;
  padding: 0 16px;
}

/* the accordion never squeezes its children: rows and rooms
   keep their true height and the column scrolls instead */
.loupe-panel.open .pod-menu > * {
  flex: none;
}

/* settled rhythm: snug rows, one constant hairline on every
   swatch — no border theatrics on hover or choice */
.loupe-panel.open .gallery-choices {
  padding: 6px 0 8px;
  gap: 2px;
}

.loupe-panel.open .gallery-row,
.loupe-panel.open .gallery-row:hover,
.loupe-panel.open .gallery-row:active,
.loupe-panel.open .gallery-row.active,
.loupe-panel.open .gallery-row.active:hover,
.loupe-panel.open .gallery-row.active:active {
  padding: 8px 10px;
  gap: 13px;
}

.loupe-panel.open .gallery-row img,
.loupe-panel.open .gallery-row:hover img,
.loupe-panel.open .gallery-row.active img,
.loupe-panel.open .gallery-row.active:hover img {
  border: 1px solid rgba(85, 86, 90, 0.3);
  box-shadow: none;
}

/* ============================================================
   ONE GLASS, FLOATING KEYS

   The wall stops being three materials. One sheet of the rail's
   own glass runs from the top edge to the foot — no strip wells,
   no sunken greys, no pale bands. On it, the tool rows float as
   keycap capsules the way keys float on the rail, and the rooms'
   contents sit directly on the glass. Top, middle, and foot are
   finally the same surface.
   ============================================================ */
.loupe-panel.open {
  background: rgba(207, 207, 203, 0.42);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
}

.loupe-panel.open .pod-menu {
  background: none;
  border-bottom: none;
  padding: 6px 0 10px;
  gap: 6px;
}

.loupe-panel.open .pod-menu .tool-section {
  background: none;
  border-bottom: none;
}

.loupe-panel.open .pod-foot {
  border-top: none;
  box-shadow: none;
}

/* the tool rows: keycap capsules afloat on the glass */
.loupe-panel.open .pod-row,
.loupe-panel.open .pod-row:hover,
.loupe-panel.open .pod-row:active,
.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover {
  width: calc(100% - 16px);
  margin: 0 8px;
  border-radius: 6px;
  border-bottom: none;
  height: 36px;
  padding: 0 12px;
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.loupe-panel.open .pod-row {
  background: rgba(240, 240, 237, 0.5);
}

.loupe-panel.open .pod-row:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover,
.loupe-panel.open .pod-row:active {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.2),
      rgba(90, 130, 210, 0.2)
    ),
    rgba(240, 240, 237, 0.55);
}

/* ============================================================
   Simpler still, and bold. The trigger drops its keycap and its
   little painting: one bare bold picture-frame glyph, drawn in
   the same heavy line as the GitHub and mail marks at the
   rail's foot — white over the art, with a breath of shadow.
   Inside, the rows lose their faces and rings: plain words on
   the glass, the wash alone saying hover and open. The X and
   the chevrons thicken to match.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 40px;
  height: 38px;
  background: none;
  border: none;
  box-shadow: none;
  border-radius: 0;
}

.pod-key-sign {
  display: none;
}

.pod-key-glyph {
  width: 23px;
  height: 23px;
  fill: none;
  stroke: rgba(255, 255, 255, 0.85);
  stroke-width: 2;
  stroke-linecap: square;
  stroke-linejoin: miter;
  display: block;
  filter: drop-shadow(0 1px 2px rgba(15, 18, 24, 0.7));
  transition: stroke 0.15s ease;
}

.pod-key-glyph circle {
  fill: rgba(255, 255, 255, 0.85);
  stroke: none;
}

.pod-key:hover .pod-key-glyph {
  stroke: #fff;
}

.pod-key:hover .pod-key-glyph circle {
  fill: #fff;
}

/* the rows: plain words on glass, wash only */
.loupe-panel.open .pod-row,
.loupe-panel.open .pod-row:active {
  background: none;
  box-shadow: none;
}

.loupe-panel.open .pod-row:hover {
  background: rgba(90, 130, 210, 0.16);
  box-shadow: none;
}

.loupe-panel.open .pod-row.active,
.loupe-panel.open .pod-row.active:hover {
  background: rgba(90, 130, 210, 0.2);
  box-shadow: none;
}

/* bold marks */
.pod-close svg {
  width: 11px;
  height: 11px;
  stroke-width: 2.2;
}

.pod-row-go svg {
  width: 7px;
  height: 11px;
  stroke-width: 2;
}

.loupe-panel.open .pod-row .pod-row-go {
  color: rgba(22, 24, 27, 0.55);
}

/* ============================================================
   THE QUIET PAGE AND THE RAIL OF SIGNS

   The wall becomes two things only. Down its right edge, a slim
   rail of bold signs — the X above, one glyph per tool, the
   chosen one resting on a soft face. To the left, the page: the
   tool's name as a plain serif heading, its contents beneath,
   the reset dial small in the heading's corner. No rows, no
   chevrons, no strips, no foot bar.
   ============================================================ */
.loupe-panel.open {
  flex-direction: row;
}

/* the rail of signs */
.loupe-panel.open .pod-menu {
  order: 2;
  flex: none;
  width: 46px;
  height: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 12px 0 14px;
  margin: 0;
  background: none;
  border-left: 1px solid rgba(85, 86, 90, 0.25);
  border-bottom: none;
  overflow: visible;
}

.pod-ico {
  flex: none;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: none;
  box-shadow: none;
  cursor: pointer;
}

.pod-ico svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: rgba(22, 24, 27, 0.72);
  stroke-width: 2;
  stroke-linecap: square;
  stroke-linejoin: miter;
  display: block;
  transition: stroke 0.15s ease;
}

.pod-ico:hover {
  background: rgba(90, 130, 210, 0.16);
}

.pod-ico:hover svg {
  stroke: #16181b;
}

.pod-ico.active,
.pod-ico.active:hover {
  background: rgba(255, 255, 255, 0.55);
}

.pod-ico.active svg {
  stroke: #16181b;
}

/* the X leads the rail */
.loupe-panel.open .pod-menu .pod-close {
  flex: none;
  width: 32px;
  height: 26px;
  margin: 0 0 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
}

.loupe-panel.open .pod-menu .pod-close svg {
  width: 11px;
  height: 11px;
  stroke: rgba(22, 24, 27, 0.6);
  stroke-width: 2.2;
  stroke-linecap: square;
  opacity: 1;
}

.loupe-panel.open .pod-menu .pod-close:hover svg {
  stroke: #16181b;
}

/* the page */
.loupe-panel.open .tool-drawer {
  order: 1;
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  margin: 0;
}

.loupe-panel.open .tool-drawer-inner {
  height: 100%;
  max-height: none;
  overflow-y: auto;
  background: none;
}

/* the tool's name stands as a plain heading */
.loupe-panel.open .loupe-header {
  display: flex;
  align-items: center;
  height: auto;
  padding: 18px 16px 8px;
  background: none;
  border: none;
  box-shadow: none;
}

.loupe-panel.open .loupe-header svg {
  display: none;
}

.loupe-panel.open .loupe-title {
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.2px;
  text-transform: none;
  color: #16181b;
  text-shadow: none;
}

/* the old chrome strip and foot retire */
.loupe-panel.open .pod-chrome {
  display: none;
}

.loupe-panel.open .pod-foot {
  display: none;
}

/* the reset dial, small in the heading's corner */
.loupe-panel.open .pod-reset {
  position: absolute;
  top: 14px;
  right: 58px;
  z-index: 3;
  display: flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: none;
  box-shadow: none;
  cursor: pointer;
}

.loupe-panel.open .pod-reset:hover {
  background: rgba(90, 130, 210, 0.16);
}

.loupe-panel.open .pod-reset:active {
  background: rgba(90, 130, 210, 0.24);
}

.loupe-panel.open .pod-reset svg {
  width: 15px;
  height: 15px;
  stroke: rgba(22, 24, 27, 0.65);
  stroke-width: 2;
  stroke-linecap: square;
  opacity: 1;
  transition: stroke 0.15s ease, transform 0.3s ease;
}

.loupe-panel.open .pod-reset:hover svg {
  stroke: #16181b;
}

.loupe-panel.open .pod-reset span {
  display: none;
}

/* the page fills its column */
.loupe-panel.open .tool-drawer-inner {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
}

/* the heading shrinks and levels with the marks: title, dial,
   and X on one line across the top. The dial speaks emoji now. */
.loupe-panel.open .loupe-header {
  padding: 13px 16px 6px;
}

.loupe-panel.open .loupe-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.3px;
}

.loupe-panel.open .pod-reset {
  top: 9px;
  right: 56px;
  width: 28px;
  height: 28px;
}

.loupe-panel.open .pod-reset svg {
  display: none;
}

.loupe-panel.open .pod-reset::before {
  content: "\1F504";
  font-size: 13px;
  line-height: 1;
  filter: saturate(0.85);
}

.loupe-panel.open .pod-menu {
  padding-top: 9px;
}

/* the numeral keys wear the painting key's exact face: same
   bright cap, same ring — nothing pre-pressed about them */
.rail-nav .rail-sub {
  background: rgba(255, 255, 255, 0.62);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

.rail-nav .rail-sub:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(255, 255, 255, 0.62);
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

/* shut, only the frame glyph remains — the dial sleeps inside */
.loupe-panel:not(.open) .pod-reset {
  display: none;
}

/* the numerals wear exactly what the painting key wears — same
   face, same bevel, stroke for stroke */
.rail-nav .rail-sub,
.rail-nav .rail-sub:hover {
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.rail-nav .rail-sub:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

/* a gentle press: the key settles a shade, no deep sink */
.rail-nav .rail-sub:active,
.rail-nav .rail-sub.active,
.rail-nav .rail-link.pressed,
.rail-group.active .rail-link {
  background: rgba(216, 216, 212, 0.55);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.26),
    inset -1px -1px 0 rgba(255, 255, 255, 0.55);
}

/* ============================================================
   The trigger, recut: a small chip of the wall itself — the
   rail's glass with the bold ink frame-glyph set in it. What
   you press is a piece of what opens.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 38px;
  height: 36px;
  background: rgba(207, 207, 203, 0.5);
  -webkit-backdrop-filter: blur(12px) saturate(1.25);
  backdrop-filter: blur(12px) saturate(1.25);
  border: 1px solid rgba(85, 86, 90, 0.5);
  box-shadow: none;
  border-radius: 0;
}

.pod-key:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(207, 207, 203, 0.5);
}

.pod-key:active {
  background: rgba(216, 216, 212, 0.6);
}

.pod-key-glyph {
  width: 21px;
  height: 21px;
  stroke: rgba(22, 24, 27, 0.8);
  filter: none;
}

.pod-key-glyph circle {
  fill: rgba(22, 24, 27, 0.8);
}

.pod-key:hover .pod-key-glyph {
  stroke: #16181b;
}

.pod-key:hover .pod-key-glyph circle {
  fill: #16181b;
}

/* ============================================================
   The trigger becomes a small magic: a wand afloat over the
   painting, bobbing the way a fairy hovers — slow, three
   pixels, forever — with one shy sparkle that blinks beside it.
   Touch it and it perks up.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 44px;
  height: 44px;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: none;
  box-shadow: none;
  overflow: visible;
  position: relative;
}

.pod-key-glyph {
  display: none;
}

.pod-key::before {
  content: "\1F9DA\FE0F";
  font-size: 23px;
  line-height: 1;
  display: block;
  filter: drop-shadow(0 2px 3px rgba(15, 18, 24, 0.55));
  animation: wand-float 3.4s ease-in-out infinite;
  transition: transform 0.25s ease;
}

.pod-key:hover::before {
  transform: rotate(-14deg) scale(1.12);
}

@keyframes wand-float {
  0%,
  100% {
    translate: 0 0;
    rotate: 0deg;
  }
  50% {
    translate: 0 -4px;
    rotate: -5deg;
  }
}

/* the shy sparkle */
.pod-key::after {
  content: "\2728";
  position: absolute;
  top: 3px;
  right: 2px;
  font-size: 9px;
  line-height: 1;
  opacity: 0;
  animation: wand-spark 3.4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes wand-spark {
  0%,
  55%,
  100% {
    opacity: 0;
  }
  70% {
    opacity: 0.9;
  }
  82% {
    opacity: 0.15;
  }
  90% {
    opacity: 0.6;
  }
}

/* ============================================================
   The float stays; the fairy goes back to system. The bold
   white frame-glyph itself hovers — the same slow three-pixel
   breath — and beside it a small typographic star ✦ blinks,
   set in the site's own ink-and-serif voice.
   ============================================================ */
.pod-key::before {
  content: none;
}

.pod-key-glyph {
  display: block;
  width: 22px;
  height: 22px;
  stroke: rgba(255, 255, 255, 0.88);
  filter: drop-shadow(0 1px 2px rgba(15, 18, 24, 0.7));
  animation: wand-float 3.6s ease-in-out infinite;
  transition: stroke 0.15s ease;
}

.pod-key-glyph circle {
  fill: rgba(255, 255, 255, 0.88);
}

.pod-key:hover .pod-key-glyph {
  stroke: #fff;
}

.pod-key:hover .pod-key-glyph circle {
  fill: #fff;
}

.pod-key::after {
  content: "\2726";
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  color: rgba(255, 255, 255, 0.9);
  text-shadow: 0 1px 2px rgba(15, 18, 24, 0.6);
  font-size: 10px;
  top: 4px;
  right: 3px;
}

/* ============================================================
   The key returns to its best self: the keycap holding a small
   framed swatch of the very painting on the wall. No fairy, no
   float — the picture is the invitation.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 38px;
  height: 36px;
  background: rgba(240, 240, 237, 0.5);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: none;
  border-radius: 0;
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
  overflow: hidden;
}

.pod-key:hover {
  background: rgba(248, 248, 245, 0.62);
}

.pod-key:active {
  background: rgba(216, 216, 212, 0.55);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.26),
    inset -1px -1px 0 rgba(255, 255, 255, 0.55);
}

.pod-key::before,
.pod-key::after {
  content: none;
  animation: none;
}

.pod-key-glyph {
  display: none;
}

.pod-key-sign {
  display: block;
  width: 26px;
  height: 24px;
  background-size: cover;
  border: 1px solid rgba(85, 86, 90, 0.55);
  box-shadow: inset 0 0 0 1px rgba(251, 251, 249, 0.35);
  animation: none;
}

/* the LANG and SIZE wells flatten like everything else: one
   hairline ring, no engraved white twin at their edges */
.rail-langs,
.rail-sizes {
  box-shadow: inset 0 0 0 1px rgba(85, 86, 90, 0.3);
}

/* one line, not two: the exits' divider was drawn twice — once
   as a border, once as a bar. The border goes. */
.rail-bottom {
  border-top: none;
}

.rail-bottom::before {
  background: rgba(85, 86, 90, 0.28);
}

/* ============================================================
   The Noted rows line up with everything else on the paper: the
   mark leaves the end of the sentence and stands at the column's
   right edge, on the same 10px the shelves and lists use. The
   date a thought was written waits inside, under its title.
   ============================================================ */
.chain {
  position: relative;
  padding-right: 34px;
}

.chain-long .chain-line::after {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 0;
  vertical-align: 0;
  opacity: 0.6;
}

.chain-long:hover .chain-line::after,
.chain-long.reading .chain-line::after {
  opacity: 1;
  transform: translate(1px, calc(-50% - 1px));
}

/* the writing date, quiet under the panel's title */
.chain-panel .chain-date {
  margin: 4px 0 0;
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: 0.19px;
  opacity: 0.55;
}

/* a thought's own emoji, sized to sit in the line */
.chain-emoji {
  font-size: 15px;
  line-height: 1;
  margin-left: 6px;
  vertical-align: -0.06em;
}

/* where a line came from: a film, a person — set small and
   quiet at the end of the thought */
.chain-src {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  line-height: 1.6;
  letter-spacing: 0.19px;
  opacity: 0.55;
}

/* ============================================================
   THE READING SHEET JOINS THE MACHINE

   The dark slab retires. A thought now opens on the same glass
   the tool wall is cut from — the rail's own grey, its hairline
   edge — and it is read in ink, in the letter's hand. The way
   out is the wall's bare X in the corner, nothing else.
   ============================================================ */
.chain-stage {
  width: min(38vw, 430px);
  padding: 0;
  background: rgba(207, 207, 203, 0.42);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
  border-left: 1px solid rgba(85, 86, 90, 0.5);
  box-shadow: none;
}

.chain-panel {
  padding: 0 20px 32px;
  max-width: none;
}

.chain-panel header {
  align-items: baseline;
  gap: 10px;
  margin: 0 0 14px;
  padding: 13px 0 6px;
}

.chain-panel .chain-no {
  font-size: 14px;
  color: rgba(22, 24, 27, 0.5);
}

.chain-panel h3 {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: #16181b;
}

.chain-panel .chain-date {
  color: rgba(22, 24, 27, 0.55);
  opacity: 1;
}

.chain-panel p,
.chain-panel li {
  font-size: 14px;
  line-height: 1.7;
  letter-spacing: 0.19px;
  color: rgba(22, 24, 27, 0.82);
}

.chain-panel h4 {
  font-size: 14px;
  font-weight: 600;
  color: #16181b;
}

.chain-panel em {
  color: rgba(22, 24, 27, 0.6);
}

.chain-panel a {
  color: rgba(22, 24, 27, 0.82);
  text-decoration-color: rgba(22, 24, 27, 0.35);
}

.chain-panel blockquote {
  border-left: 1px solid rgba(85, 86, 90, 0.3);
}

/* the way out: the wall's own bare mark */
.chain-close {
  margin: 0 14px 0 0;
  padding: 0;
  width: 26px;
  height: 26px;
  top: 9px;
  border-radius: 0;
  background: none;
  color: rgba(22, 24, 27, 0.6);
  font-size: 15px;
  line-height: 1;
}

.chain-close:hover {
  background: none;
  color: #16181b;
}

@media (max-width: 900px) {
  .chain-stage {
    width: 100%;
    padding-top: 0;
  }
}

/* the sheets' inner edge is cut exactly as the rail's is: one
   hairline of the same weight, drawn outside the width so the
   contents keep their true measure */
.chain-stage,
.loupe-panel.open {
  border-left: none;
  box-shadow: -1px 0 0 rgba(85, 86, 90, 0.4);
}

/* every inner edge in the machine is the rail's hairline: the
   wall's left edge, and the divider before its rail of signs */
.loupe-panel.open,
.loupe-panel.open:hover {
  border-left: none;
  box-shadow: -1px 0 0 rgba(85, 86, 90, 0.4);
}

.loupe-panel.open .pod-menu {
  border-left: none;
  box-shadow: -1px 0 0 rgba(85, 86, 90, 0.4);
}

/* said with the weight it needs: the wall's own edge */
aside.loupe-panel.open,
aside.loupe-panel.open:hover {
  border-left: none !important;
  box-shadow: -1px 0 0 rgba(85, 86, 90, 0.4) !important;
}

/* the wall clips its own overflow, so its edge is drawn inside:
   an inset hairline of the rail's exact weight */
aside.loupe-panel.open,
aside.loupe-panel.open:hover {
  box-shadow: inset 1px 0 0 rgba(85, 86, 90, 0.4) !important;
}

.loupe-panel.open .pod-menu {
  box-shadow: inset 1px 0 0 rgba(85, 86, 90, 0.4);
}

/* a thought's small mark, cut in the same ink line as the rest
   of the site: quiet enough to sit inside a sentence */
.chain-mark {
  display: inline-block;
  width: 0.82em;
  height: 0.82em;
  margin: 0 2px;
  vertical-align: -0.1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: square;
  stroke-linejoin: miter;
  opacity: 0.6;
}

/* the marks stand in full ink, as black as the words */
.chain-mark {
  opacity: 1;
  stroke: #16181b;
}

/* ============================================================
   A THOUGHT AS A DOCUMENT

   One piece opens the way a file does: the sheet goes dark, the
   lines are numbered down a gutter, and the words are set in the
   machine's own monospace. The rest of Noted keeps its paper
   voice; this is the exception that proves it.
   ============================================================ */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  background: rgba(22, 23, 27, 0.95);
  -webkit-backdrop-filter: blur(20px) saturate(0.9);
  backdrop-filter: blur(20px) saturate(0.9);
  box-shadow: inset 1px 0 0 rgba(236, 231, 219, 0.14);
}

body:has(.chain-panel.chain-code.reading) .chain-close {
  color: rgba(236, 231, 219, 0.6);
}

body:has(.chain-panel.chain-code.reading) .chain-close:hover {
  color: #f2efe8;
}

.chain-panel.chain-code {
  padding: 0 0 40px;
}

.chain-panel.chain-code header {
  margin: 0 0 16px;
  padding: 13px 20px 10px;
  border-bottom: 1px solid rgba(236, 231, 219, 0.12);
}

.chain-panel.chain-code .chain-no {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 12px;
  color: rgba(236, 231, 219, 0.45);
}

.chain-panel.chain-code h3 {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0;
  color: rgba(236, 231, 219, 0.92);
}

/* every line counted in its gutter */
.chain-panel.chain-code .code-line {
  position: relative;
  margin: 0;
  padding: 0 20px 0 52px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.85;
  letter-spacing: 0;
  color: rgba(236, 231, 219, 0.82);
}

.chain-panel.chain-code .code-line::before {
  content: attr(data-ln);
  position: absolute;
  left: 0;
  width: 34px;
  text-align: right;
  color: rgba(236, 231, 219, 0.28);
}

.chain-panel.chain-code .code-blank {
  min-height: 1.85em;
}

/* ============================================================
   THE FILE OPENS WHERE THE PAINTING IS

   A document does not slide in from the edge; it opens in the
   room, the way the paintings do. The code sheet leaves the wall
   and becomes a window set into the open air right of the letter
   — its own frame, its own shadow, resting on the picture.
   ============================================================ */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  top: 50%;
  right: auto;
  bottom: auto;
  width: min(38vw, 560px);
  max-height: min(72vh, 640px);
  transform: translateY(-50%) translateX(24px);
  border-radius: 6px;
  overflow: hidden;
  background: rgba(22, 23, 27, 0.94);
  box-shadow: inset 0 0 0 1px rgba(236, 231, 219, 0.16),
    0 24px 60px rgba(8, 10, 14, 0.5);
  transition: transform 0.38s cubic-bezier(0.22, 0.9, 0.3, 1),
    opacity 0.3s ease, visibility 0s linear 0.38s;
  opacity: 0;
}

body:has(.chain-panel.chain-code.reading) .chain-stage.open {
  transform: translateY(-50%);
  opacity: 1;
}

/* the window's own bar: a name and the way out */
body:has(.chain-panel.chain-code.reading) .chain-close {
  position: absolute;
  top: 8px;
  right: 8px;
  margin: 0;
  z-index: 2;
}

.chain-panel.chain-code {
  padding: 0 0 26px;
}

.chain-panel.chain-code header {
  position: sticky;
  top: 0;
  z-index: 1;
  background: rgba(30, 31, 36, 0.96);
  margin: 0 0 14px;
  padding: 10px 20px;
  border-bottom: 1px solid rgba(236, 231, 219, 0.12);
}

/* the window sits in the air right of the letter, and never
   past the screen's own edge */


body:has(.chain-panel.chain-code.reading) .chain-stage {
  transform: translateY(-50%) translateX(20px) !important;
}

body:has(.chain-panel.chain-code.reading) .chain-stage.open {
  transform: translateY(-50%) !important;
}


/* the document stands full height: a column between the letter
   and the tools, floor to ceiling, its own edges hairlined */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  top: 0;
  bottom: 0;
  max-height: none;
  height: 100vh;
  border-radius: 0;
  box-shadow: inset 1px 0 0 rgba(236, 231, 219, 0.14),
    inset -1px 0 0 rgba(236, 231, 219, 0.14);
}

body:has(.chain-panel.chain-code.reading) .chain-stage,
body:has(.chain-panel.chain-code.reading) .chain-stage.open {
  transform: translateY(var(--doc-y, 0px)) !important;
}

body:has(.chain-panel.chain-code.reading) .chain-stage {
  opacity: 0;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}

body:has(.chain-panel.chain-code.reading) .chain-stage.open {
  opacity: 1;
}

.chain-panel.chain-code header {
  padding: 14px 20px 12px;
}

/* the numbers step aside: a thought is not a source file, and
   the gutter was counting for no one. The lines keep their
   monospace calm and simply breathe wider. */
.chain-panel.chain-code .code-line::before {
  content: none;
}

.chain-panel.chain-code .code-line {
  padding: 0 26px;
  font-size: 13px;
  line-height: 1.9;
}

.chain-panel.chain-code header {
  padding: 14px 26px 12px;
}

/* the date takes its place beside the title, not under it */
.chain-panel.chain-code header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: nowrap;
}

.chain-panel.chain-code .chain-date {
  margin: 0;
  flex: none;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 11.5px;
  color: rgba(236, 231, 219, 0.42);
}

.chain-panel.chain-code h3 {
  flex: 1 1 auto;
  min-width: 0;
}

/* the date stops short of the X's corner */
.chain-panel.chain-code header {
  padding-right: 46px;
}


/* ============================================================
   THE PHONE'S WALL SLIDES IN FROM THE EDGE

   No floating card on a small screen: the tools stand as a wall
   pinned to the right edge, floor to ceiling, arriving the way
   the desk's wall does — from the right, in one motion.
   ============================================================ */
@media (max-width: 720px) {
  .loupe-panel.open {
    top: 0 !important;
    bottom: 0 !important;
    right: 0 !important;
    left: auto !important;
    width: min(86vw, 400px) !important;
    max-height: none !important;
    height: 100% !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: inset 1px 0 0 rgba(85, 86, 90, 0.4),
      -12px 0 40px rgba(20, 24, 32, 0.3) !important;
    animation: wall-in-phone 0.34s cubic-bezier(0.22, 0.9, 0.3, 1);
  }

  @keyframes wall-in-phone {
    from {
      transform: translateX(100%);
    }
    to {
      transform: none;
    }
  }

  /* the rail of signs keeps the wall's right edge */
  .loupe-panel.open .pod-menu {
    width: 52px;
  }

  .pod-ico {
    width: 36px;
    height: 36px;
  }

  .pod-ico svg {
    width: 21px;
    height: 21px;
  }

  /* touch-height rows in the list */
  .loupe-panel.open .gallery-row,
  .loupe-panel.open .gallery-row:hover,
  .loupe-panel.open .gallery-row.active {
    padding: 10px 12px;
  }
}

/* on a phone the document comes in from the right and stops
   short: a hand's width of painting stays visible behind it, so
   you never lose the room you are standing in */
@media (max-width: 720px) {
  body:has(.chain-panel.chain-code.reading) .chain-stage {
    left: auto !important;
    right: 0 !important;
    /* the tools wall measures min(86vw, 400px); the reading
       sheet sits a touch inside it, since it carries no rail of
       signs and the letter behind should stay reachable */
    width: min(84vw, 392px) !important;
    top: 0;
    bottom: 0;
    height: 100%;
  }
}

/* the key keeps its old proportions; only its place moves —
   raised so the air above equals the air to its right */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 38px;
  height: 36px;
}

.pod-key-sign {
  width: 26px;
  height: 24px;
}

.loupe-panel:not(.open),
.loupe-panel:not(.open):hover {
  top: 22px;
  right: 22px;
}

/* the portrait is the way home, so it stands at the very top:
   the phone rail starts flush, one breath under the edge */
@media (max-width: 720px) {
  .rail {
    padding-top: 10px;
  }

  .rail-avatar {
    margin-bottom: 12px;
  }
}

/* the portrait rides higher on a phone: it is the way home, so
   it meets the top of the screen almost at once */
@media (max-width: 720px) {
  .rail {
    padding-top: 6px;
  }

  .rail-group:nth-child(1) {
    margin-top: 0;
  }

  .rail-nav {
    margin-top: 0;
  }
}

/* the column starts where the screen does: the portrait, the way
   home, meets the top with only a breath above it — desk and
   phone alike */
.rail {
  padding-top: 8px;
}

.rail-nav {
  margin-top: 0;
}

@media (max-width: 720px) {
  .rail {
    padding-top: 6px;
  }
}

/* ============================================================
   THE WINDOW BELONGS TO ITS LINE

   Opened, a thought should read as that line unfolded, not as a
   second thing arriving beside it. So the chosen row stays lit
   like an open drawer, a thread runs from its edge to the
   window, and the window repeats the row's own head: the number,
   then the title, in the same order the list gives them.
   ============================================================ */

/* the row stays open: pressed in, its mark turned to face the
   window it opened */
.chain-long.reading {
  background: rgba(90, 130, 210, 0.24);
}

.chain-long.reading .chain-line::after {
  opacity: 1;
  transform: translate(2px, calc(-50% - 2px));
}


/* the window's head answers the row: number, then title, in the
   list's own order and rhythm */
.chain-panel.chain-code header {
  gap: 14px;
}

.chain-panel.chain-code .chain-no {
  color: rgba(236, 231, 219, 0.5);
}

/* and the window's own edge glows where the thread meets it */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  box-shadow: inset 1px 0 0 rgba(236, 231, 219, 0.14),
    inset -1px 0 0 rgba(236, 231, 219, 0.14),
    0 20px 60px rgba(8, 10, 14, 0.42);
}

/* ============================================================
   THE WINDOW GROWS OUT OF THE LINE

   Instead of a thread across the page, the window itself says
   where it came from: it unfolds from the left, the side the
   list stands on, and carries the list's own head — the number
   in the list's grey, the title in the list's words — over a
   lit seam on that same left edge. Read the row, and the panel
   is that row continued.
   ============================================================ */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  transform-origin: left center;
  box-shadow: inset 1px 0 0 rgba(236, 231, 219, 0.12),
    inset -1px 0 0 rgba(236, 231, 219, 0.12),
    0 20px 60px rgba(8, 10, 14, 0.42);
  animation: doc-unfold 0.3s cubic-bezier(0.22, 0.9, 0.3, 1);
}

@keyframes doc-unfold {
  from {
    opacity: 0;
    transform: translateX(-14px) scaleX(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* the head repeats the row exactly: number in its grey, title
   in its ink, one rule beneath as the list has none */
.chain-panel.chain-code header {
  background: rgba(30, 31, 36, 0.96);
  border-bottom: 1px solid rgba(236, 231, 219, 0.12);
}

/* the row it came from stays open behind, held in the wash the
   whole site uses for a thing in hand */
.chain-long.reading {
  background: rgba(90, 130, 210, 0.2);
}

/* ============================================================
   SET AS SOMEONE WROTE IT

   The document stops looking like a terminal dump and starts
   looking like a page: a measure the eye can carry, paragraphs
   parted by air rather than a blank numbered line, the first
   line given its weight, and generous margins around the
   column. Monospace stays, since that is the voice; only the
   setting changes.
   ============================================================ */
.chain-panel.chain-code {
  padding: 0 0 12px;
}

.chain-panel.chain-code .code-line {
  max-width: 62ch;
  margin: 0 auto;
  padding: 0 30px;
  font-size: 13px;
  line-height: 2;
  letter-spacing: 0.1px;
  color: rgba(236, 231, 219, 0.86);
}

/* the blank counting-lines retire: paragraphs breathe instead */
.chain-panel.chain-code .code-blank {
  display: none;
}

.chain-panel.chain-code .code-line + .code-line {
  margin-top: 1.15em;
}

/* the opening line carries a little more light, the way a first
   sentence does on paper */
.chain-panel.chain-code .code-line:first-of-type {
  color: rgba(243, 239, 231, 0.95);
}

/* a heading inside a piece */
.chain-panel.chain-code .code-head {
  margin-top: 2em;
  color: #f2efe8;
}

/* the head sits over the same measure as the words */
.chain-panel.chain-code header {
  padding: 14px 30px 12px;
}

/* ---- the sheet carries the whole run: one piece follows another
   inside the window, so a long read never sends you back to the
   letter to find the next one */
.chain-foot {
  max-width: 62ch;
  margin: 40px auto 0;
  padding: 18px 30px 8px;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  border-top: 1px solid rgba(236, 231, 219, 0.12);
}

.chain-step {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  text-align: left;
  color: rgba(236, 231, 219, 0.6);
  transition: color 0.15s ease;
}

.chain-step:last-child {
  text-align: right;
  align-items: flex-end;
}

.chain-step:hover {
  color: #f2efe8;
}

.chain-step[hidden] {
  display: none;
}

.chain-step-way {
  font-size: 10.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  opacity: 0.6;
}

.chain-step-name {
  font-size: 12.5px;
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}


/* the way on is said the way the list says it: a number, then a
   title, in the same order and rhythm as the run behind it */
.chain-foot {
  gap: 24px;
}

.chain-step {
  flex-direction: row;
  align-items: baseline;
  gap: 12px;
}

.chain-step:last-child {
  justify-content: flex-end;
}

.chain-step-no {
  flex: none;
  font-size: 12.5px;
  opacity: 0.5;
}

.chain-step-name {
  font-size: 12.5px;
}

/* laid over the letter, the document casts its own shadow so the
   sheet beneath reads as beneath */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  box-shadow: inset 1px 0 0 rgba(236, 231, 219, 0.14),
    inset -1px 0 0 rgba(236, 231, 219, 0.14),
    -18px 0 48px rgba(8, 10, 14, 0.45),
    0 20px 60px rgba(8, 10, 14, 0.35);
}

/* ============================================================
   THE DOCUMENT CONTINUES THE LETTER

   It is the same column of paper, picked up where the letter's
   edge falls: same width, same margins inside. Its bar keeps the
   date clear of the X, and the page scrolls as any page does.
   ============================================================ */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  overflow-y: auto;
  overscroll-behavior: contain;
  box-shadow: inset 1px 0 0 rgba(236, 231, 219, 0.14),
    inset -1px 0 0 rgba(236, 231, 219, 0.14),
    -14px 0 40px rgba(8, 10, 14, 0.4);
}

/* the letter holds its words 40px in from each edge; the
   document does the same, so the two columns line up */
.chain-panel.chain-code .code-line,
.chain-panel.chain-code .code-head {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  padding: 0 40px;
}

.chain-panel.chain-code .code-line + .code-line {
  margin-top: 1.15em;
}

.chain-panel.chain-code header {
  padding: 14px 52px 12px 40px;
}

.chain-foot {
  max-width: none;
  margin: 34px 0 0;
  padding: 0 26px;
}

/* the way out sits clear of the date it shares the bar with */
body:has(.chain-panel.chain-code.reading) .chain-close {
  top: 10px;
  right: 12px;
}

/* at the wall's measure the column narrows, so its margins come
   in to match the wall's own */
.chain-panel.chain-code .code-line,
.chain-panel.chain-code .code-head {
  padding: 0 20px;
}

.chain-panel.chain-code header {
  padding: 14px 44px 12px 20px;
}

.chain-foot {
  padding: 0 8px;
}

/* the Noted rows reach the same right edge the shelves and lists
   reach, so every arrow on the paper stands on one line */
.chain {
  width: calc(100% + 20px);
  margin-right: -10px;
}

/* and the section's own name is set like the notes beneath it,
   not in bold */
#writings h2 {
  font-weight: 400;
}

/* the document runs the screen's height, as the tools wall does */
body:has(.chain-panel.chain-code.reading) .chain-stage {
  top: 0;
  bottom: 0;
  height: 100vh;
  max-height: none;
  transform-origin: left center;
}

/* on a phone a thought closes and you are back in the list, so
   the way-on rows are not needed there */
@media (max-width: 720px) {
  .chain-foot {
    display: none;
  }
}

/* the way-on rows retire: a thought ends, and the list is a
   click away */
.chain-foot {
  display: none;
}

/* the X belongs to the bar, so it travels inside it: the header
   is what sticks, and the mark rides along */
body:has(.chain-panel.chain-code.reading) .chain-close {
  display: none;
}

.chain-panel.chain-code header {
  position: sticky;
  top: 0;
  z-index: 2;
}

.chain-panel.chain-code .head-close {
  flex: none;
  width: 26px;
  height: 26px;
  margin-left: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  color: rgba(236, 231, 219, 0.6);
  font-size: 15px;
  line-height: 1;
  transition: color 0.14s ease;
}

.chain-panel.chain-code .head-close:hover {
  color: #f2efe8;
}

.chain-panel.chain-code header {
  padding-right: 14px;
}

/* a mark belongs to the line it opens: when a thought runs to a
   second line, the arrow stays level with the first */
.chain-long .chain-line::after {
  top: 0.85em;
  transform: none;
}

.chain-long:hover .chain-line::after,
.chain-long.reading .chain-line::after {
  transform: translate(1px, -1px);
}

/* and a source runs on from the words it belongs to, rather than
   dropping to a line of its own */
.chain-src {
  display: inline;
  margin-left: 8px;
}

/* the fold control moves to the sheet's left corner, where a
   window's own controls live */
.pillar-shade {
  justify-content: flex-start;
  padding-left: 26px;
  padding-right: 0;
}

.pillar-shade .shade-close {
  left: 10px;
  right: auto;
}

/* the document is the letter's own drawer, so it rides the
   letter's motion: when the sheet folds down, it goes too */
.chain-stage {
  transition: transform 0.42s cubic-bezier(0.22, 0.9, 0.3, 1),
    visibility 0s linear 0.42s;
}

body:has(.chain-panel.chain-code.reading) .chain-stage {
  transform: translateY(var(--doc-y, 0px));
}

/* the mark centres on the first line's own height: half a line
   down, less half the mark, so it sits level with the words */
.chain-long .chain-line::after {
  top: calc(0.5lh - 0.29em);
}

/* no mark to press: a thought closes when you read on */
.chain-panel.chain-code .head-close {
  display: none;
}

/* said last, and plainly: the document carries no close mark */
.chain-panel.chain-code header .head-close,
body:has(.chain-panel.chain-code.reading) .chain-close {
  display: none !important;
}

/* the mark lines up with the letterforms, not the line box: a
   serif sits low in its own line, so the arrow drops with it */
.chain-long .chain-line::after {
  top: calc(0.5lh - 0.29em + 0.16em);
}

/* measured against the glyphs themselves: the mark's centre now
   meets the centre of the letterforms it stands beside */
.chain-long .chain-line::after {
  top: calc(0.5lh - 0.29em + 0.16em - 3px);
}

/* the chosen sign is held, not spotlit: a breath of white on the
   glass rather than a lit plate */
.pod-ico.active,
.pod-ico.active:hover {
  background: rgba(255, 255, 255, 0.26);
}

.pod-ico.active svg {
  stroke: #16181b;
}

/* ============================================================
   The Noted mark stops being positioned and starts being set:
   it rides in the text flow, pushed to the right edge by its own
   margin. Type sets it on the line, exactly as type sets the
   words, so it shares their baseline without arithmetic.
   ============================================================ */
.chain-long .chain-line::after {
  position: static;
  float: right;
  top: auto;
  right: auto;
  margin: 0 0 0 12px;
  transform: none;
  vertical-align: baseline;
}

.chain-long:hover .chain-line::after,
.chain-long.reading .chain-line::after {
  transform: translate(1px, -1px);
}

/* ============================================================
   The tools shelf follows the site's own grammar: the name on
   the left, its small grey word held at the right beside the
   arrow, the way every other shelf and list on the paper sets
   its second line.
   ============================================================ */
.paper .shelf-cell {
  justify-content: space-between;
}

.paper .shelf-cell .shelf-name {
  flex: 0 1 auto;
  min-width: 0;
}

.paper .shelf-cell .shelf-note {
  flex: none;
  margin-left: auto;
  text-align: right;
}

/* ============================================================
   The Noted rows are set the way the lists are set: the row
   centres its parts, and the mark is placed from the right edge
   at half the row's height, exactly as .site-list does. Same
   grammar, same result.
   ============================================================ */
.chain {
  align-items: center;
}

.chain-long .chain-line::after {
  position: absolute;
  float: none;
  right: 24px;
  top: 50%;
  margin: 0;
  transform: translateY(-50%);
}

.chain-long:hover .chain-line::after,
.chain-long.reading .chain-line::after {
  transform: translate(1px, calc(-50% - 1px));
}

/* the mark measures from the row, as the lists measure from the
   link that fills theirs */
.chain-long .chain-line {
  position: static;
}

/* ============================================================
   PARAGRAPHS THAT BREATHE

   A wall of monospace is hard to enter, so the document gives
   its paragraphs a rhythm the eye can hold: real air between
   them, a faint rule drawn in that air, and a measure that
   stops before the line grows tiring. Apple's own notes read
   this way — the structure is visible before a word is.
   ============================================================ */
.chain-panel[data-chain-panel="30"] .code-line,
.chain-panel[data-chain-panel="30"] .code-head {
  max-width: 54ch;
  line-height: 2.05;
}

.chain-panel[data-chain-panel="30"] .code-line + .code-line {
  margin-top: 0;
  padding-top: 1.5em;
  position: relative;
}

/* the rule sits in the air, held in from both margins so it
   reads as a pause rather than a border */
.chain-panel[data-chain-panel="30"] .code-line + .code-line::before {
  content: "";
  position: absolute;
  top: 0.75em;
  left: 0;
  right: 0;
  height: 1px;
  background: rgba(236, 231, 219, 0.1);
}

/* the mark stands on the same vertical the shelves and lists
   keep: ten pixels in from the row's own right edge */
.chain-long .chain-line::after {
  right: 10px;
}

/* ============================================================
   A ROW READS BY ITS FIRST LINE

   However many lines a thought runs to, the row is set as if it
   were one: the number and the mark both hold the first line's
   own height, and the words wrap beneath them. The row centres
   nothing; it starts everything at the top.
   ============================================================ */
.chain {
  align-items: flex-start;
}

.chain-no {
  line-height: 1.7; /* the first line's height, so it sits on it */
}

.chain-long .chain-line::after {
  top: 0;
  margin-top: 0.7em; /* down to the middle of the first line only */
  transform: none;
}

.chain-long:hover .chain-line::after,
.chain-long.reading .chain-line::after {
  transform: translate(1px, -1px);
}

/* the shelf's small grey word sits on the name's own middle, the
   way every other second line on the paper does, rather than
   hanging from the baseline */
.paper .shelf-cell {
  align-items: center;
}

/* the mark reads off the letterforms, not the line box: half of
   the ink's own height, the way the lists land it at zero */
.chain-long .chain-line::after {
  margin-top: 0.58em;
}

/* the painting key answers the cursor exactly as the numerals
   beneath it do: the letter's wash laid over its own face */
.rail-nav .rail-group:nth-child(2) .rail-link:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

/* the three exits below the folder answer the cursor the way the
   wall's signs do — the same rounded square, held fainter */
.rail-bottom .rail-link,
.rail-group:nth-child(1) .rail-subs .rail-sub {
  width: 32px;
  height: 32px;
  margin: 0 auto;
  border-radius: 8px;
}

.rail-bottom .rail-link:hover,
.rail-group:nth-child(1) .rail-subs .rail-sub:hover {
  background: rgba(255, 255, 255, 0.14);
  box-shadow: none;
  transform: none;
}

/* ============================================================
   THE PHONE READS THE SAME RULES

   On a narrow screen the row has less room, so the words were
   running under the mark and the numbers were losing their
   column. The row keeps a lane for the mark on the right, the
   number keeps its own on the left, and the reading window
   stops short of the screen's edge so the letter behind it is
   still there to go back to.
   ============================================================ */
@media (max-width: 720px) {
  .chains {
    width: 100%;
  }

  .chain {
    width: 100%;
    margin: 0;
    padding: 8px 34px 8px 0; /* the lane the mark stands in */
    align-items: flex-start;
  }

  .chain-no {
    width: 30px;
    flex: none;
  }

  .chain-line {
    flex: 1 1 auto;
    min-width: 0;
  }

  .chain-long .chain-line::after {
    right: 6px;
  }

  /* the document window: a hand's width of letter stays visible */
  body:has(.chain-panel.chain-code.reading) .chain-stage {
    left: auto !important;
    right: 0 !important;
    width: min(86vw, 400px) !important;
  }

  .chain-panel.chain-code .code-line,
  .chain-panel.chain-code .code-head {
    max-width: none;
    padding: 0 18px;
  }

  .chain-panel.chain-code header {
    padding: 12px 18px 10px;
  }
}

/* ============================================================
   The key becomes a hung picture

   Same size as before; only what is inside changes. The painting
   grows to within two pixels of the key's edge and takes a
   gallery frame: a dark rabbet, a pale slip inside it, and the
   faintest shadow, as a small panel hung on a wall would have.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 38px;
  height: 36px;
  padding: 0;
}

.pod-key-sign {
  width: 34px;
  height: 32px;
  border: 1px solid rgba(52, 48, 42, 0.8);
  box-shadow: inset 0 0 0 1.5px rgba(246, 243, 236, 0.85),
    inset 0 0 0 2.5px rgba(52, 48, 42, 0.35),
    0 1px 2px rgba(20, 24, 32, 0.3);
}

/* ============================================================
   The button is the frame

   No keycap behind it, no white slip around it: the painting
   hangs on the glass in a thin dark moulding of its own, lifted
   by a shadow. Resting on it lifts it a little further; pressing
   sets it back against the wall.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: auto;
  height: auto;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
  border-radius: 0;
  transition: transform 0.16s ease, box-shadow 0.16s ease;
}

.pod-key-sign {
  display: block;
  width: 40px;
  height: 38px;
  border: 1px solid rgba(38, 34, 30, 0.85);
  border-radius: 0;
  box-shadow: 0 2px 6px rgba(16, 20, 26, 0.45);
  transition: box-shadow 0.16s ease;
}

.pod-key:hover .pod-key-sign {
  box-shadow: 0 4px 10px rgba(16, 20, 26, 0.5);
}

.pod-key:hover {
  transform: translateY(-1px);
}

.pod-key:active {
  transform: translateY(0);
}

.pod-key:active .pod-key-sign {
  box-shadow: 0 1px 3px rgba(16, 20, 26, 0.5);
}

/* ============================================================
   The key is a rail key again

   The frame-on-glass lost the button. This is the rail's own
   keycap, stroke for stroke: the same pale face, the same lit
   top-left and shadowed bottom-right, the same wash under the
   cursor and the same quiet sink on a press. The painting sits
   inside it as a small plate, the way the numerals sit in theirs.
   ============================================================ */
.pod-key,
.pod-key:hover,
.pod-key:active {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 36px;
  padding: 0;
  border: none;
  border-radius: 0;
  transform: none;
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.pod-key:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

.pod-key:active {
  background: rgba(216, 216, 212, 0.55);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.26),
    inset -1px -1px 0 rgba(255, 255, 255, 0.55);
}

/* the painting, set in the key as a small plate */
.pod-key-sign,
.pod-key:hover .pod-key-sign,
.pod-key:active .pod-key-sign {
  display: block;
  width: 26px;
  height: 24px;
  border: 1px solid rgba(85, 86, 90, 0.55);
  border-radius: 0;
  box-shadow: none;
  transform: none;
}

.pod-key:active .pod-key-sign {
  transform: translate(1px, 1px);
}

/* the key steps down a size: smaller than the rail's own keys, so
   it sits in the corner without claiming it */
.pod-key,
.pod-key:hover,
.pod-key:active {
  width: 30px;
  height: 28px;
}

.pod-key-sign,
.pod-key:hover .pod-key-sign,
.pod-key:active .pod-key-sign {
  width: 22px;
  height: 20px;
}



/* the letter ends on the rhythm it kept all the way down: one
   section's worth of air below the last one, and then the road
   carries on into Design (js/main.js) */
body.theme-painting .page {
  padding-bottom: 96px;
}

/* ============================================================
   The mark comes down onto its line

   The arrow was measured from the top of the row's box and
   forgot the row's own padding, so it floated above the words.
   Its centre now sits exactly on the centre of the first text
   line: the row's padding down, then half of one line-height.
   ============================================================ */
.chain-long .chain-line::after {
  top: calc(9px + 0.56em); /* 9px pad + (0.85em half-line - 0.29em half-arrow) */
  margin-top: 0;
}

@media (max-width: 720px) {
  .chain-long .chain-line::after {
    top: calc(8px + 0.56em); /* the phone rows pad 8px */
  }
}

/* ============================================================
   Design continues the scroll instead of opening a new screen

   Arriving from the foot of Home, the reader is mid-scroll: the
   next heading should stand one section-gap below the fold, the
   same ninety-six pixels that separate every section of the
   letter, not forty per cent of a fresh viewport.
   ============================================================ */
body.design-dark .page {
  padding-top: 96px;
}

body.design-dark .paper > h1 {
  margin-top: 0;
}

/* the shelf's marks centre the way every list's do: half their
   own height off the row's middle, not an eyeballed em */
.paper .shelf-cell::after {
  top: 50%;
  margin-top: 0;
  transform: translateY(-50%);
}

.paper .shelf-cell:hover::after {
  transform: translate(1px, calc(-50% - 1px));
}

/* ============================================================
   Design rises like the letter

   Arriving on Design, the sheet comes up from below the fold,
   easing to rest the way the letter unfolds at home. Only once
   it has settled does the wall behind soften, slowly (the frost
   above waits 1.1s and takes 2s), so nothing swims while the
   page is still moving.
   ============================================================ */
@keyframes sheet-rise {
  from {
    transform: translateY(22vh);
  }
  to {
    transform: none;
  }
}

body.design-dark .paper {
  animation: sheet-rise 0.85s cubic-bezier(0.22, 0.9, 0.3, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  body.design-dark .paper {
    animation: none;
  }

  :root:has(body.design-dark)::after {
    transition: none;
  }
}


/* ============================================================
   THE BENTO

   Design's own key, top-right where Home keeps its painting
   key and wearing the same keycap face. One press slides every
   visual on the page into a wordless grid, tile after tile;
   pressing again (or Escape) hands the story back.
   ============================================================ */
.bento-key {
  position: fixed;
  top: 22px;
  right: 22px;
  z-index: 40;
  width: 30px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(240, 240, 237, 0.5);
  box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.8),
    inset -1px -1px 0 rgba(85, 86, 90, 0.45);
}

.bento-key:hover {
  background: linear-gradient(
      0deg,
      rgba(90, 130, 210, 0.16),
      rgba(90, 130, 210, 0.16)
    ),
    rgba(240, 240, 237, 0.5);
}

.bento-key:active,
.bento-key.on {
  background: rgba(216, 216, 212, 0.55);
  box-shadow: inset 1px 1px 0 rgba(85, 86, 90, 0.26),
    inset -1px -1px 0 rgba(255, 255, 255, 0.55);
}

.bento-glyph {
  display: grid;
  grid-template-columns: 6px 6px;
  grid-auto-rows: 5px;
  gap: 2px;
}

.bento-glyph i {
  background: rgba(58, 61, 66, 0.7);
}

.bento {
  position: fixed;
  inset: 0 0 0 var(--rail-width);
  z-index: 30;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 74px 34px 34px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  /* every dish the same small size: the row rules the height, so
     nothing can lean on anything else */
  grid-auto-rows: 104px;
  gap: 18px;
  align-content: start;
  background: rgba(238, 240, 243, 0.35);
  backdrop-filter: blur(12px) saturate(1.1);
}

.bento[hidden] {
  display: none;
}

body.bento-open {
  overflow: hidden;
}

.bento-tile {
  position: relative; /* the dish sets the size; the food fills it */
  border-radius: 6px;
  overflow: hidden;
  background: rgba(252, 253, 255, 0.5);
  box-shadow: 0 0 0 1px rgba(85, 86, 90, 0.35),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
  animation: tile-in 0.5s cubic-bezier(0.22, 0.9, 0.3, 1) both;
  animation-delay: calc(var(--i) * 35ms);
}

.bento-tile img,
.bento-tile video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@keyframes tile-in {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 720px) {
  .bento {
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    grid-auto-rows: 76px;
    gap: 12px;
    padding: 58px 14px 14px;
  }

  .bento-key {
    top: 14px;
    right: 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bento-tile {
    animation: none;
  }
}

/* ============================================================
   The phone reads the shelves in one column

   Two columns of tools cannot fit a phone's width: the right one
   ran off the screen with its marks half-lost. One column, each
   row whole. The TechEquity card also stops bleeding past the
   paper's edge (a desktop gesture) and lets its line wrap.
   ============================================================ */
@media (max-width: 720px) {
  .shelf-grid {
    grid-template-columns: 1fr;
  }

  .post-card {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }

  .post-card .post-sub {
    white-space: normal;
  }
}

/* ============================================================
   The larger A reaches everything on the paper

   The toggle only grew the letter's paragraphs; the notes, the
   lists, the shelves, the chains, the card and the whole Design
   page kept their size, so the press felt half-applied. The same
   twelve per cent step now covers them all: the 16px family goes
   to 18, the letter's 16.5 to 18.5 (set above), the small-caps
   notes from 9 to 10, and the card's subtitle from 12.5 to 14.
   ============================================================ */
body.text-large .paper p,
body.text-large .paper li,
body.text-large .paper h1,
body.text-large .paper h2,
body.text-large .site-list a,
body.text-large .shelf-name,
body.text-large .chain-line,
body.text-large .chain-no,
body.text-large .post-card .post-title,
body.text-large .paper .craft li,
body.text-large .paper .meta {
  font-size: 18px;
}

body.text-large .aside-note {
  font-size: 18.5px;
}

body.text-large .site-list span,
body.text-large .shelf-note {
  font-size: 10px;
}

body.text-large .post-card .post-sub {
  font-size: 14px;
}

/* the book and film titles keep the row's own voice when the large
   A is pressed: the label rule above ties them on specificity, so
   this says it once more, later and heavier */
body.text-large .song-list a > span.t {
  font-size: inherit;
}

/* the sentences that rearranged her grow too */
body.text-large .quote blockquote,
body.text-large .quote cite {
  font-size: 18px;
}

/* and a shelf cell may shrink below its note's width, so the two
   columns stay twins */
.paper .shelf-cell {
  min-width: 0;
}

/* ============================================================
   THE MACHINE ROOM

   A third page, and its own room: no painting, no glass. A
   plain archive wall the colour of card stock, specimen cards
   in a grid, each machine on a white plate with its number in
   the corner, the way a collection is kept. The rail stays.
   ============================================================ */
body.machine-room {
  background: #eceae4;
}

body.machine-room .page {
  padding: 96px 40px 18vh;
}

body.machine-room .paper {
  max-width: 1060px;
  margin: 0 auto;
  background: none;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
}

body.machine-room h1 {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.2px;
  margin: 0 0 18px;
}

.mr-intro {
  font-size: 16px;
  line-height: 1.74;
  max-width: 560px;
  color: rgba(22, 24, 27, 0.78);
  margin: 0;
}

/* an era is a shelf: numeral, name and years on one line over a rule */
.mr-era {
  margin-top: 96px;
}

.mr-era:first-of-type {
  margin-top: 0;
}

.mr-era-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  border-bottom: 1px solid rgba(85, 86, 90, 0.4);
  padding-bottom: 10px;
}

.mr-era-no {
  font-size: 10px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(22, 24, 27, 0.5);
}

.mr-era-head h2 {
  font-size: 16px;
  font-weight: 600;
  margin: 0;
}

.mr-era-span {
  margin-left: auto;
  font-size: 10px;
  letter-spacing: 1.2px;
  color: rgba(22, 24, 27, 0.5);
}

.mr-era-note {
  font-size: 16px;
  line-height: 1.7;
  max-width: 560px;
  color: rgba(22, 24, 27, 0.62);
  margin: 14px 0 0;
}

/* the cards */
.mr-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 40px 28px;
  margin-top: 36px;
}

.mr-card {
  margin: 0;
  position: relative;
}

.mr-no {
  font-size: 10px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(22, 24, 27, 0.45);
}

/* every machine sits on the same white plate, whatever the photo
   was: contain, one background, one hairline. The consistency is
   the whole game. */
.mr-plate {
  margin-top: 8px;
  aspect-ratio: 4 / 3;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 0 0 1px rgba(85, 86, 90, 0.35),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
}

.mr-plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* the logo is the one image that wants air, not a crop */
.mr-plate-logo {
  background: #f6f5f1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mr-plate-logo img {
  width: 62%;
  height: auto;
  object-fit: contain;
}

.mr-card figcaption {
  margin-top: 14px;
}

.mr-card h3 {
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 6px;
}

.mr-year {
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 1.2px;
  color: rgba(22, 24, 27, 0.5);
  margin-left: 7px;
}

.mr-card p {
  font-size: 15px;
  line-height: 1.68;
  margin: 0 0 8px;
  color: rgba(22, 24, 27, 0.78);
}

/* the interface line is the librarian's note */
.mr-iface {
  font-size: 13.5px;
  line-height: 1.6;
  color: rgba(22, 24, 27, 0.55);
}

.mr-iface a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: rgba(85, 86, 90, 0.5);
  text-underline-offset: 3px;
}

.mr-iface a:hover {
  color: var(--ink);
}

/* the photo credit is a small stamp in the plate's corner */
.mr-credit {
  position: absolute;
  top: 0;
  right: 0;
  font-size: 9px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: rgba(22, 24, 27, 0.38);
  text-decoration: none;
}

.mr-credit:hover {
  color: rgba(22, 24, 27, 0.75);
}

/* the reading room borrows the site's list grammar */
.mr-sources {
  margin-top: 26px;
}

@media (max-width: 720px) {
  body.machine-room .page {
    padding: 72px 18px 14vh;
  }

  .mr-grid {
    grid-template-columns: 1fr;
    gap: 34px;
  }

  .mr-intro {
    margin-bottom: 56px;
  }

  .mr-era {
    margin-top: 64px;
  }
}

/* the machine room's title starts at the top of the room, not a
   quarter of the way down it (the letter-page h1 offset yields) */
body.machine-room .paper > h1 {
  margin-top: 0;
}

/* The machine room's five eras, numbered the way Design's projects
   are: roman figures set in the same button the tools wear */
.rail-group:nth-child(4) .rail-sub::before {
  -webkit-mask: none;
  mask: none;
  background: none;
  width: auto;
  height: auto;
  font-family: "EB Garamond", "Apple Garamond", Garamond, Georgia, serif;
  font-size: 11px;
  line-height: 1;
  color: #4a4d54;
  opacity: 0.75;
}

.rail-group:nth-child(4) .rail-sub:nth-of-type(1)::before { content: "I"; }
.rail-group:nth-child(4) .rail-sub:nth-of-type(2)::before { content: "II"; }
.rail-group:nth-child(4) .rail-sub:nth-of-type(3)::before { content: "III"; }
.rail-group:nth-child(4) .rail-sub:nth-of-type(4)::before { content: "IV"; }
.rail-group:nth-child(4) .rail-sub:nth-of-type(5)::before { content: "V"; }

.rail-group:nth-child(4) .rail-sub.active::before {
  opacity: 1;
  color: #23262b;
}

/* the machine room's key is a bare bold icon, the way the X and
   the GitHub marks are: one dark shape, no keycap face under it */
.rail-group:nth-child(4) .rail-link,
.rail-group:nth-child(4) .rail-link:hover,
.rail-group:nth-child(4).active .rail-link,
.rail-group:nth-child(4) .rail-link.pressed {
  background: none;
  box-shadow: none;
}

.rail-group:nth-child(4) .rail-link svg {
  width: 17px;
  height: 17px;
  color: var(--ink);
  opacity: 0.8;
  transition: opacity 0.15s ease;
}

.rail-group:nth-child(4) .rail-link:hover svg,
.rail-group:nth-child(4).active .rail-link svg {
  opacity: 1;
}

/* the machine room asks for no furniture in the rail: no group
   tray, no numbered minis, just the one outlined mark, the way
   the icons at the rail's foot stand */
.rail-group:nth-child(4),
.rail-group:nth-child(4).active {
  background: none;
  box-shadow: none;
  padding: 0;
}

.rail-group:nth-child(4) .rail-subs {
  display: none;
}

/* ============================================================
   THE REGISTER

   The grid becomes a ledger: one machine to a line, photograph
   on the left, entry on the right, a hairline between lines,
   the way a collection is written into a book. And the whole
   room speaks in one voice, the design page's rule: everything
   in Garamond at sixteen, numbers included; nothing changes
   size, only weight and softness.
   ============================================================ */
.mr-grid {
  display: block;
  margin-top: 0;
}

.mr-card {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 12px 30px;
  align-items: start;
  padding: 34px 0;
  border-bottom: 1px solid rgba(85, 86, 90, 0.22);
}

.mr-grid .mr-card:last-child {
  border-bottom: none;
}

.mr-plate {
  margin-top: 0;
  grid-row: 1 / 3;
}

.mr-no {
  font-size: 16px;
  letter-spacing: 0.2px;
  text-transform: none;
  color: rgba(22, 24, 27, 0.45);
  line-height: 1.7;
}

.mr-card figcaption {
  margin-top: 0;
}

.mr-card h3 {
  font-size: 16px;
  margin: 0 0 6px;
}

.mr-year {
  font-size: 16px;
  letter-spacing: 0.2px;
  margin-left: 8px;
  color: rgba(22, 24, 27, 0.5);
}

.mr-card p,
.mr-iface {
  font-size: 16px;
  line-height: 1.7;
  color: rgba(22, 24, 27, 0.78);
}

.mr-iface {
  color: rgba(22, 24, 27, 0.55);
}

/* the credit reads as the entry's last quiet word, not a stamp */
.mr-credit {
  position: static;
  display: inline-block;
  font-size: 16px;
  letter-spacing: 0.2px;
  text-transform: none;
  color: rgba(22, 24, 27, 0.4);
  text-decoration: underline;
  text-decoration-color: rgba(85, 86, 90, 0.35);
  text-underline-offset: 3px;
}

/* the era shelf keeps its rule but takes the same voice */
.mr-era-no,
.mr-era-span {
  font-size: 16px;
  letter-spacing: 0.2px;
  text-transform: none;
  color: rgba(22, 24, 27, 0.5);
}

.mr-era {
  margin-top: 84px;
}

.mr-era-note {
  margin-top: 14px;
  margin-bottom: 6px;
}

@media (max-width: 900px) {
  .mr-card {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .mr-plate {
    grid-row: auto;
    max-width: 420px;
  }
}

/* ============================================================
   THE PAIRING IS THE ARGUMENT

   The register grows pictures. Each entry is now an image band
   across the full measure: where the interface survives, the
   machine and its screen stand side by side, hardware left,
   software right, each with a quiet word underneath; the entry
   reads beneath the band. Every other line swaps sides, so the
   ledger walks down the page left, right, left.
   ============================================================ */
.mr-card {
  display: block;
  padding: 40px 0;
}

.mr-card .mr-no {
  display: block;
  margin-bottom: 10px;
}

.mr-plate {
  grid-row: auto;
  aspect-ratio: auto;
  height: 340px;
}

.mr-pair {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: 14px;
}

/* every other entry walks the other way */
.mr-grid .mr-card:nth-child(even) .mr-pair {
  grid-template-columns: 2fr 3fr;
}

.mr-grid .mr-card:nth-child(even) .mr-pair .mr-shot:first-child {
  order: 2;
}

.mr-shot {
  min-width: 0;
}

.mr-tag {
  display: block;
  margin-top: 8px;
  font-size: 16px;
  line-height: 1.5;
  color: rgba(22, 24, 27, 0.45);
  text-decoration: none;
}

a.mr-tag {
  text-decoration: underline;
  text-decoration-color: rgba(85, 86, 90, 0.3);
  text-underline-offset: 3px;
}

a.mr-tag:hover {
  color: rgba(22, 24, 27, 0.75);
}

.mr-card figcaption {
  margin-top: 18px;
  max-width: 640px;
}

@media (max-width: 900px) {
  .mr-plate {
    height: 230px;
    max-width: none;
  }

  .mr-pair,
  .mr-grid .mr-card:nth-child(even) .mr-pair {
    grid-template-columns: 1fr;
    gap: 12px;
  }

  .mr-grid .mr-card:nth-child(even) .mr-pair .mr-shot:first-child {
    order: 0;
  }
}

/* the pixel Mac reads best at an even multiple of its grid */
.rail-group:nth-child(4) .rail-link svg {
  width: 20px;
  height: 20px;
}

/* ============================================================
   The register returns

   The full-width bands read worse than the ledger did, so the
   line comes back: photograph left, entry right, a hairline
   between lines. Where an interface survives it keeps its place,
   as a second, smaller print under the machine in the same
   column, with its quiet word.
   ============================================================ */
.mr-card {
  display: grid;
  grid-template-columns: 300px 1fr;
  grid-template-rows: auto 1fr; /* the entry hugs its number */
  gap: 12px 30px;
  align-items: start;
  padding: 34px 0;
}

.mr-card .mr-no {
  display: block;
  margin-bottom: 0;
}

.mr-pair {
  display: block;
  grid-column: 1;
  grid-row: 1 / 3;
}

.mr-shot + .mr-shot {
  margin-top: 14px;
}

.mr-plate {
  height: auto;
  aspect-ratio: 4 / 3;
  grid-row: 1 / 3;
}

.mr-pair .mr-plate {
  grid-row: auto;
}

.mr-card figcaption {
  margin-top: 0;
  max-width: none;
}

@media (max-width: 900px) {
  .mr-card {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .mr-pair,
  .mr-plate {
    grid-row: auto;
    grid-column: auto;
  }

  .mr-plate {
    height: auto;
    max-width: 420px;
  }
}

/* ============================================================
   THE MONITOR AND THE TIMELINE

   Infinite Mac's idea in this site's clothes: every machine's
   photograph sits inside a little beige case with a dark bezel,
   its specimen number on the chin where the badge would be. And
   a year runs down the left of the register on its own vertical
   line, one tick per machine.
   ============================================================ */
.mr-card {
  grid-template-columns: 64px 300px 1fr;
}

.mr-tick {
  grid-column: 1;
  grid-row: 1;
  font-size: 16px;
  line-height: 1.4;
  color: rgba(22, 24, 27, 0.55);
  position: relative;
  padding-left: 20px;
}

/* the line itself, and the tick that sits on it */
.mr-grid {
  position: relative;
}

.mr-grid::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(85, 86, 90, 0.3);
}

.mr-tick::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 7px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #eceae4;
  box-shadow: inset 0 0 0 1.5px rgba(85, 86, 90, 0.65);
}

.mr-card .mr-no {
  display: none; /* the number lives on the case's chin now */
}

.mr-year {
  display: none; /* the year stands on the timeline instead */
}

.mr-pair,
.mr-card > .mr-plate {
  grid-column: 2;
  grid-row: 1 / 3;
}

.mr-card figcaption {
  grid-column: 3;
  grid-row: 1 / 3;
}

/* the case: beige shell, dark bezel, chin badge */
.mr-plate[data-chin] {
  aspect-ratio: auto;
  height: auto;
  overflow: visible;
  background: #e9e5d8;
  border-radius: 10px;
  padding: 14px 14px 26px;
  box-shadow: 0 0 0 1px rgba(85, 86, 90, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.65);
  position: relative;
}

.mr-plate[data-chin] img {
  aspect-ratio: 4 / 3;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: 3px;
  box-shadow: 0 0 0 5px #1a1b1e;
}

.mr-plate[data-chin]::after {
  content: attr(data-chin);
  position: absolute;
  left: 0;
  right: 0;
  bottom: 7px;
  text-align: center;
  font-size: 9px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(22, 24, 27, 0.45);
}

/* the interface print stays a flat little photograph beneath */
.mr-pair .mr-shot + .mr-shot .mr-plate {
  background: none;
  padding: 0;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 0 0 1px rgba(85, 86, 90, 0.35),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
}

.mr-pair .mr-shot + .mr-shot .mr-plate img {
  border-radius: 0;
  box-shadow: none;
}

@media (max-width: 900px) {
  .mr-card {
    grid-template-columns: 1fr;
  }

  .mr-tick,
  .mr-pair,
  .mr-card > .mr-plate,
  .mr-card figcaption {
    grid-column: auto;
    grid-row: auto;
  }

  .mr-grid::before {
    display: none;
  }

  .mr-tick {
    padding-left: 0;
  }

  .mr-tick::before {
    display: none;
  }
}

/* ============================================================
   THE LOBBY AND THE DARK HALL

   Split the way the reference splits: a light landing at the
   top, and below it the whole collection hangs in a dark hall,
   the beige cases doing their work against it. The timeline
   quiets right down: a faint line, dim years, no dots.
   ============================================================ */
body.machine-room {
  background: #26282c;
}

body.machine-room .page {
  padding-top: 0;
}

.mr-lobby {
  /* the reference's own morning blue, running flush to the rail:
     the oversized bleed cannot leave a sliver on either side */
  background: #eceae4;
  margin: 0 -100vw 40px;
  padding: 56px 100vw 40px;
}

body.machine-room {
  overflow-x: hidden;
}

/* the room below speaks in light ink */
body.machine-room .mr-era-head h2,
body.machine-room .mr-card h3 {
  color: rgba(238, 239, 241, 0.92);
}

body.machine-room .mr-era-no,
body.machine-room .mr-era-span {
  color: rgba(238, 239, 241, 0.45);
}

body.machine-room .mr-era-head {
  border-bottom-color: rgba(238, 239, 241, 0.16);
}

body.machine-room .mr-era-note,
body.machine-room .mr-card p {
  color: rgba(238, 239, 241, 0.72);
}

body.machine-room .mr-iface {
  color: rgba(238, 239, 241, 0.5);
}

body.machine-room .mr-tag,
body.machine-room .mr-credit {
  color: rgba(238, 239, 241, 0.4);
}

body.machine-room a.mr-tag,
body.machine-room .mr-credit {
  text-decoration-color: rgba(238, 239, 241, 0.25);
}

body.machine-room a.mr-tag:hover,
body.machine-room .mr-credit:hover {
  color: rgba(238, 239, 241, 0.8);
}

body.machine-room .mr-card {
  border-bottom-color: rgba(238, 239, 241, 0.1);
}

body.machine-room .mr-iface a {
  color: inherit;
  text-decoration-color: rgba(238, 239, 241, 0.3);
}

body.machine-room .mr-iface a:hover {
  color: rgba(238, 239, 241, 0.85);
}

/* the quiet timeline */
body.machine-room .mr-grid::before {
  background: rgba(238, 239, 241, 0.12);
}

body.machine-room .mr-tick {
  color: rgba(238, 239, 241, 0.4);
}

body.machine-room .mr-tick::before {
  display: none;
}

/* the case keeps its beige; its ring adapts to the dark */
body.machine-room .mr-plate[data-chin] {
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45),
    0 6px 18px rgba(0, 0, 0, 0.3);
}

/* the interface prints ring in light */
body.machine-room .mr-pair .mr-shot + .mr-shot .mr-plate {
  box-shadow: 0 0 0 1px rgba(238, 239, 241, 0.18);
}

/* the reading room reads in the dark too */
body.machine-room .mr-sources a {
  color: rgba(238, 239, 241, 0.85);
}

body.machine-room .mr-sources li > span {
  color: rgba(238, 239, 241, 0.45);
}

body.machine-room .mr-sources a::after {
  background: rgba(238, 239, 241, 0.6);
}

@media (max-width: 720px) {
  .mr-lobby {
    padding-top: 72px;
    padding-bottom: 40px;
    margin-bottom: 44px;
  }
}

/* ============================================================
   The cases come off

   No shell, no bezel, no chin: the photographs hang plainly in
   the dark, every one in the same rounded tile with a light
   hairline, machine and interface alike.
   ============================================================ */
.mr-plate[data-chin] {
  background: none;
  padding: 0;
  border-radius: 6px;
  overflow: hidden;
  aspect-ratio: 4 / 3;
}

body.machine-room .mr-plate[data-chin] {
  box-shadow: 0 0 0 1px rgba(238, 239, 241, 0.18);
}

.mr-plate[data-chin] img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
  box-shadow: none;
}

.mr-plate[data-chin]::after {
  content: none;
}

/* ============================================================
   The timeline stands apart

   The card rules were running clean across the year column and
   crossing the timeline's own line. The separators now begin
   where the entry begins, so the left gutter holds nothing but
   the one faint vertical and its dim years.
   ============================================================ */
.mr-card {
  border-bottom: none;
  position: relative;
}

.mr-card::after {
  content: "";
  position: absolute;
  left: 94px; /* the year gutter stays unruled */
  right: 0;
  bottom: 0;
  height: 1px;
  background: rgba(238, 239, 241, 0.1);
}

.mr-grid .mr-card:last-child::after {
  content: none;
}

@media (max-width: 900px) {
  .mr-card::after {
    left: 0;
  }
}

/* ============================================================
   Smaller prints, and the tall ones uncropped

   The photographs step down a size, and a portrait photograph
   keeps its own proportions instead of being cut to landscape:
   the tile simply takes the picture's shape.
   ============================================================ */
.mr-card {
  grid-template-columns: 64px 240px 1fr;
}

.mr-card::after {
  left: 88px;
}

.mr-tall,
.mr-plate[data-chin].mr-tall {
  aspect-ratio: auto;
}

.mr-tall img,
.mr-plate[data-chin].mr-tall img {
  aspect-ratio: auto;
  height: auto;
  object-fit: unset;
}

@media (max-width: 900px) {
  .mr-card::after {
    left: 0;
  }

  .mr-plate {
    max-width: 340px;
  }
}


/* the timeline's own line stops short of the shelf rules above
   and the hall's end below: it floats, touching nothing */
.mr-grid::before {
  top: 42px;
  bottom: 42px;
}

/* the era's year range steps down: the timeline already says it */
.mr-era-span {
  display: none;
}

/* the little signs stop whispering: full ink whether or not their
   section is the one on screen */
.rail-group:nth-child(1) .rail-sub {
  opacity: 1;
}

.rail-group:nth-child(1) .rail-sub .sig {
  filter: none;
}



/* ============================================================
   THE MAP THAT UNDERSTOOD PEOPLE

   One picture given a whole wall of the letter, the way the
   reference hangs its painting: heading above, the sheet-wide
   map in the site's own thin ring, a quiet caption below.
   ============================================================ */
.map-frame {
  margin: 14px 0 0;
}

.map-frame img {
  /* the Rumsey Collection scan of the first printing: the card
     carries its own cream margin and blue border, so it hangs
     bare, square-cornered, at the sheet's full width */
  width: 100%;
  height: auto;
  display: block;
  border-radius: 0;
}

.map-frame figcaption {
  margin-top: 14px;
  font-size: 16px;
  font-style: italic;
  line-height: 1.7;
  color: rgba(22, 24, 27, 0.62);
  max-width: 540px;
}

/* ============================================================
   THE GRAPHICS ROOM

   The machine room's split lobby and dark hall, borrowed whole;
   only the prints differ. Each diagram hangs at the sheet's full
   width with its caption in light italic, and the fifth key in
   the rail stands bare like the fourth.
   ============================================================ */
body.graphics-room .map-frame {
  margin-top: 26px;
}

body.graphics-room .map-frame figcaption {
  color: rgba(238, 239, 241, 0.55);
  max-width: 640px;
}

.rail-group:nth-child(5),
.rail-group:nth-child(5).active {
  background: none;
  box-shadow: none;
  padding: 0;
}

.rail-group:nth-child(5) .rail-subs {
  display: none;
}

.rail-group:nth-child(5) .rail-link,
.rail-group:nth-child(5) .rail-link:hover,
.rail-group:nth-child(5).active .rail-link,
.rail-group:nth-child(5) .rail-link.pressed {
  background: none;
  box-shadow: none;
}

.rail-group:nth-child(5) .rail-link svg {
  width: 20px;
  height: 20px;
  color: var(--ink);
  opacity: 0.8;
  transition: opacity 0.15s ease;
}

.rail-group:nth-child(5) .rail-link:hover svg,
.rail-group:nth-child(5).active .rail-link svg {
  opacity: 1;
}

/* ============================================================
   THE GRAPHICS ROOM, REHUNG

   Not the machine room's split: one deep wall the whole way
   down, gallery-dark, and the two diagrams hung facing each
   other as a pair. The parts are all the site's own — the small
   caps, the Garamond, the hairline, the italic line — arranged
   as museum plaques under each print.
   ============================================================ */
body.graphics-room {
  background: #26282c;
}

body.graphics-room .page {
  padding: 84px 40px 16vh;
}

body.graphics-room .paper {
  max-width: 1180px;
  margin: 0 auto;
  background: none;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
}

body.graphics-room h1 {
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 16px;
  color: rgba(238, 239, 241, 0.92);
}

.gr-intro {
  font-size: 16px;
  line-height: 1.74;
  max-width: 520px;
  color: rgba(238, 239, 241, 0.66);
  margin: 0;
}

/* the pair: two prints facing each other across a seam */
.gr-wall {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  margin-top: 72px;
  align-items: start;
}

.gr-print {
  margin: 0;
}

.gr-print img {
  width: 100%;
  height: auto;
  display: block;
  /* a print under gallery light: square, bare, lifted a little */
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.42);
}

/* the plaque: number, city, one italic line */
.gr-plaque {
  margin-top: 22px;
  max-width: 440px;
}

.gr-no {
  font-size: 10px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(238, 239, 241, 0.4);
}

.gr-plaque h2 {
  font-size: 16px;
  font-weight: 600;
  margin: 6px 0 8px;
  color: rgba(238, 239, 241, 0.92);
  border-bottom: 1px solid rgba(238, 239, 241, 0.16);
  padding-bottom: 8px;
}

.gr-plaque p {
  font-size: 16px;
  font-style: italic;
  line-height: 1.7;
  margin: 0;
  color: rgba(238, 239, 241, 0.55);
}

@media (max-width: 900px) {
  body.graphics-room .page {
    padding: 72px 18px 12vh;
  }

  .gr-wall {
    grid-template-columns: 1fr;
    gap: 56px;
    margin-top: 48px;
  }
}

/* ============================================================
   THE IDENTITY PAIR

   Below the two diagrams, the two marks, drawn rather than
   scanned: the roundel in its own red and blue, and the route
   bullets one disc per line, each on a paper specimen panel
   under the same gallery light as the prints.
   ============================================================ */
.gr-wall-2 {
  margin-top: 96px;
}

.gr-panel {
  background: #f2efe6;
  min-height: 340px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 44px 30px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.42);
}

/* the roundel: a red wheel, a blue bar, Johnston-ish letters */
.roundel {
  position: relative;
  width: 210px;
  height: 210px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.roundel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 34px solid #dc241f;
}

.roundel-bar {
  position: relative;
  z-index: 1;
  width: 268px;
  background: #10069f;
  color: #fff;
  text-align: center;
  padding: 9px 0 8px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: 2.5px;
}

/* the bullets: one disc per route, colour by trunk line */
.bullets {
  display: grid;
  grid-template-columns: repeat(6, 46px);
  gap: 14px;
  justify-content: center;
}

.bl {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--c);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 23px;
  font-weight: 600;
}

.bl-dark {
  color: #111;
}

@media (max-width: 900px) {
  .gr-wall-2 {
    margin-top: 64px;
  }

  .gr-panel {
    min-height: 280px;
  }

  .bullets {
    grid-template-columns: repeat(5, 40px);
    gap: 11px;
  }

  .bl {
    width: 40px;
    height: 40px;
    font-size: 20px;
  }
}

/* ============================================================
   ONE ROW PER CITY

   The map takes the width it deserves and its mark stands
   beside it: diagram left, identity panel and plaque stacked on
   the right, one row for London, one for New York.
   ============================================================ */
.gr-city {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 40px;
  align-items: start;
  margin-top: 84px;
}

.gr-city:first-of-type {
  margin-top: 72px;
}

.gr-city .gr-print {
  margin: 0;
}

.gr-side {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.gr-side .gr-panel {
  min-height: 0;
  padding: 38px 20px;
}

/* the roundel and the discs sit smaller in the side bay */
.gr-side .roundel {
  width: 150px;
  height: 150px;
}

.gr-side .roundel::before {
  border-width: 25px;
}

.gr-side .roundel-bar {
  width: 196px;
  font-size: 14.5px;
  letter-spacing: 2px;
  padding: 7px 0 6px;
}

.gr-side .bullets {
  grid-template-columns: repeat(4, 40px);
  gap: 11px;
}

.gr-side .bl {
  width: 40px;
  height: 40px;
  font-size: 20px;
}

@media (max-width: 900px) {
  .gr-city {
    grid-template-columns: 1fr;
    gap: 30px;
    margin-top: 64px;
  }
}

/* ============================================================
   THE SPREAD

   Back to the pair, grown up: the two cities as facing pages of
   one open book. A faint seam runs down the middle, each page
   opens with its city set in small caps over a rule, and map,
   plaque, mark and line read down each side in one column.
   ============================================================ */
.gr-spread {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 88px;
  margin-top: 72px;
  align-items: start;
}

/* the seam between the pages */
.gr-spread::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 12px;
  bottom: 12px;
  width: 1px;
  background: rgba(238, 239, 241, 0.1);
}

.gr-col-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 1px solid rgba(238, 239, 241, 0.16);
  padding-bottom: 10px;
  margin-bottom: 26px;
}

.gr-col-head span {
  font-size: 10px;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: rgba(238, 239, 241, 0.6);
}

.gr-col-head .gr-col-year {
  color: rgba(238, 239, 241, 0.35);
}

.gr-col .gr-print {
  margin: 0;
}

.gr-col .gr-plaque {
  margin: 20px 0 44px;
  max-width: none;
}

.gr-col .gr-plaque:last-child {
  margin-bottom: 0;
}

/* the identity panels keep the side-bay scale from before */
.gr-col .gr-panel {
  min-height: 0;
  padding: 40px 24px;
}

.gr-col .roundel {
  width: 150px;
  height: 150px;
}

.gr-col .roundel::before {
  border-width: 25px;
}

.gr-col .roundel-bar {
  width: 196px;
  font-size: 14.5px;
  letter-spacing: 2px;
  padding: 7px 0 6px;
}

.gr-col .bullets {
  grid-template-columns: repeat(6, 40px);
  gap: 11px;
}

.gr-col .bl {
  width: 40px;
  height: 40px;
  font-size: 20px;
}

@media (max-width: 900px) {
  .gr-spread {
    grid-template-columns: 1fr;
    gap: 64px;
    margin-top: 48px;
  }

  .gr-spread::before {
    display: none;
  }
}

/* facing pages open level: the letter's section rhythm does not
   reach into the spread */
.gr-spread section,
.gr-spread section + section {
  margin-top: 0;
}

/* ============================================================
   Bigger prints, no seam, the credit as a small line

   The wall widens and the pages sit closer so the diagrams get
   the size; the seam goes; and the collection's credit reads as
   one small line under each print instead of living inside the
   scan.
   ============================================================ */
body.graphics-room .paper {
  max-width: 1340px;
}

.gr-spread {
  gap: 56px;
}

.gr-spread::before {
  content: none;
}

.gr-copy {
  margin: 8px 0 0;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: rgba(238, 239, 241, 0.3);
}

/* ============================================================
   ONE COLUMN, DAYLIGHT

   The spread folds to a single column, the machine room's way:
   London first, then New York, each print at the full measure.
   And the dark hall lifts — the room goes back to card stock,
   with the ink dark and the panels ringed by a hairline.
   ============================================================ */
body.graphics-room {
  background: #eceae4;
}

body.graphics-room .paper {
  max-width: 1000px;
}

body.graphics-room h1 {
  color: var(--ink);
}

.gr-intro {
  color: rgba(22, 24, 27, 0.72);
}

.gr-spread {
  grid-template-columns: 1fr;
  gap: 92px;
}

.gr-col-head span {
  color: rgba(22, 24, 27, 0.55);
}

.gr-col-head .gr-col-year {
  color: rgba(22, 24, 27, 0.38);
}

.gr-col-head {
  border-bottom-color: rgba(85, 86, 90, 0.4);
}

.gr-print img {
  box-shadow: 0 8px 26px rgba(20, 24, 32, 0.18);
}

.gr-panel {
  background: #f7f5ee;
  box-shadow: 0 0 0 1px rgba(85, 86, 90, 0.3),
    0 8px 26px rgba(20, 24, 32, 0.12);
}

.gr-no {
  color: rgba(22, 24, 27, 0.45);
}

.gr-plaque p {
  color: rgba(22, 24, 27, 0.62);
}

.gr-copy {
  color: rgba(22, 24, 27, 0.35);
}

/* ============================================================
   THE SIGNAGE PANEL

   Not a scan: set live, the way Unimark set it. Helvetica cut
   tight and black, then the discs, on the same paper panel.
   The old full grid of bullets stands down.
   ============================================================ */
.gr-panel-sign {
  justify-content: flex-start;
  padding: 44px 46px;
}

.bullets-hidden {
  display: none;
}

.signage {
  width: 100%;
}

.sign-lines {
  margin: 0 0 18px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 34px;
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: -0.5px;
  color: #111;
}

.sign-bullets {
  display: flex;
  gap: 9px;
  margin-top: 9px;
}

.sign-bullets .bl {
  width: 44px;
  height: 44px;
  font-size: 22px;
}

@media (max-width: 900px) {
  .sign-lines {
    font-size: 26px;
  }

  .sign-bullets .bl {
    width: 38px;
    height: 38px;
    font-size: 19px;
  }
}

/* nothing ringed, nothing lifted: the pictures and panels on this
   page sit flat on the paper, no outline, no shadow */
body.graphics-room .gr-print img,
body.graphics-room .gr-panel {
  box-shadow: none;
}

/* the marks stand on the paper itself: no panel behind them, and
   they align left with the words like everything else */
body.graphics-room .gr-panel {
  background: none;
  padding: 26px 0;
  min-height: 0;
  justify-content: flex-start;
}

body.graphics-room .gr-col .bullets {
  justify-content: start;
}

/* ============================================================
   Caption under the map, mark beside its words

   The specimen numbers go. Each map keeps its italic line right
   beneath it; each identity reads as a row of its own, the
   explanation in upright type on the left and the mark standing
   in its own column at the far right.
   ============================================================ */
.gr-ident {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 48px;
  align-items: center;
  margin-top: 48px;
}

.gr-ident-text p {
  margin: 0;
  font-size: 16px;
  font-style: normal;
  line-height: 1.72;
  color: rgba(22, 24, 27, 0.72);
  max-width: 480px;
}

.gr-ident .gr-panel {
  padding: 0;
}

.gr-col .gr-plaque {
  margin: 16px 0 0;
}

@media (max-width: 900px) {
  .gr-ident {
    grid-template-columns: 1fr;
    gap: 22px;
  }
}

/* the identity row takes its paper back: one pale panel across
   the measure, words on the left half, the mark centred in the
   right half */
.gr-ident {
  background: #f7f5ee;
  padding: 46px 48px;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
}

.gr-ident .gr-panel {
  justify-self: center;
  justify-content: center;
}

@media (max-width: 900px) {
  .gr-ident {
    grid-template-columns: 1fr;
    padding: 30px 24px;
  }

  .gr-ident .gr-panel {
    justify-self: start;
  }
}

/* half and half: the words keep the bare page on the left, and
   the pale panel is the right half itself, the mark centred in it */
.gr-ident {
  background: none;
  padding: 0;
  gap: 48px;
  align-items: stretch;
}

.gr-ident .gr-panel {
  background: #f7f5ee;
  justify-self: stretch;
  width: 100%;
  min-height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
}

.gr-ident .gr-ident-text {
  align-self: center;
}

@media (max-width: 900px) {
  .gr-ident .gr-panel {
    min-height: 240px;
  }
}

/* said once more, heavier: the right half IS the panel, and the
   mark stands in its centre */
body.graphics-room .gr-ident .gr-panel {
  background: #f7f5ee;
  justify-content: center;
}

/* ============================================================
   THE LINEAGE CONTINUES: HELVETICA IN THE SKY, MOVE ON SCREEN

   Two more walls, drawn live like the roundel and the discs.
   The AA wordmark set half red half blue; a Helvetica specimen;
   the Uber word white on black; a Move-style sample. All of it
   type, none of it scanned.
   ============================================================ */
.gr-print-panel {
  min-height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px 30px;
  background: #f7f5ee;
}

body.graphics-room .gr-print-panel {
  background: #f7f5ee;
  justify-content: center;
}

.aa-mark {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 700;
  font-size: clamp(34px, 6.4vw, 74px);
  letter-spacing: -1.5px;
  line-height: 1;
  white-space: nowrap;
}

.aa-red {
  color: #d0112b;
}

.aa-blue {
  color: #223a7a;
}

.helv-spec,
.move-spec {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #17181b;
}

.helv-aa {
  font-size: 96px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -2px;
}

.helv-name {
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.4px;
}

/* the dark print: Uber's word, white on black */
body.graphics-room .gr-print-panel.gr-panel-dark {
  background: #101114;
}

.uber-mark {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 500;
  font-size: clamp(48px, 8vw, 92px);
  letter-spacing: -1px;
  line-height: 1;
  color: #fff;
}

.move-line {
  font-size: 72px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -1.5px;
}

.move-abc {
  font-size: 20px;
  font-weight: 500;
  letter-spacing: 1.5px;
  color: rgba(23, 24, 27, 0.6);
}

@media (max-width: 900px) {
  .gr-print-panel {
    min-height: 200px;
    padding: 40px 18px;
  }

  .helv-aa {
    font-size: 68px;
  }

  .move-line {
    font-size: 52px;
  }
}

/* the wordmark scales down to live inside its half panel */
.gr-ident .aa-mark {
  font-size: clamp(24px, 3vw, 34px);
  letter-spacing: -0.8px;
}

/* the photo credit may be a link */
a.gr-copy {
  display: inline-block;
  text-decoration: none;
}

a.gr-copy:hover {
  color: rgba(22, 24, 27, 0.7);
}


/* the diagram hangs on the letter now: full width of the paper,
   dark ink caption, nothing ringed */
.paper .map-frame img {
  max-width: none;
  border-radius: 0;
  box-shadow: none;
}

.paper .map-frame figcaption {
  color: rgba(22, 24, 27, 0.62);
  max-width: 640px;
}
