/* ============================================================
   Plumline — shared page chrome
   The header, hero, bands, cards, rows and footer that every
   content page uses. Built only from tokens.css: no raw hex,
   no one-off radius. Written up in docs/style-guide.md.

   The map page (index.html) links this file too, after its own
   styles.css. The plumliners' pages are moving onto it one at a time,
   with plumliners.css after it for the cooler ground they stand on;
   the ones still on styles.css alone are listed at the end of
   this file.
   ============================================================ */

* { box-sizing: border-box; }
/* Hidden is hidden, whatever display a class gives the thing: a script that
   hides a .btn, as the introduction's Send does once it has sent, means it.
   Every page loads this sheet, so this is the one rule for it, as are the
   two below. */
[hidden] { display: none !important; }
/* Words for a screen reader alone. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* A field takes the type of the words around it, not the browser's own. */
button, input, select, textarea { font: inherit; }
html { scroll-behavior: smooth; scroll-padding-top: 4.8rem; }
/* Jumping to an anchor must not park the heading under the sticky header.
   The bar is one line at every width — on a phone the section links fold
   under Menu rather than wrapping into more rows — and 4.8rem clears it.
   Re-measure if the bar itself grows. */

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font); font-size-adjust: var(--x-height);
  font-size: 17px;
  line-height: 1.65;
}
/* A page shorter than the window keeps its footer at the foot of the
   window, with the spare room above it; a longer page runs on as before.
   The main part takes the full width it had, so a main that is also a
   .wrap still centres at the same width. */
body { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
body > main { flex: 1 0 auto; width: 100%; }

img { max-width: 100%; height: auto; display: block; }
/* Links take the side's highlight: plum where the public reads, indigo where
   plumliners work. Read through --sect-text, which body sets below and plumliners.css
   re-points, rather than naming plum here. */
a { color: var(--sect-text); text-decoration: none; }
/* A button dressed as a link, for words in a sentence that open something
   on the page rather than go somewhere. */
.linklike {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: var(--sect-text); cursor: pointer;
}
/* A link among words also wears a fine underline, so it can be found
   without hunting for the colour. A link with a class of its own is dressed
   as something else (a button, a row, a card) and draws itself, and the
   links in a menu or a trail of places are plainly links already. */
a:not([class]), .linklike { text-decoration: var(--link-underline); text-underline-offset: var(--link-offset); }
nav a:not([class]) { text-decoration: none; }
a:hover, .linklike:hover, nav a:not([class]):hover { text-decoration: underline; }
/* A page's title is set light, in FiraGO's Light at 300, and every heading
   under it bold, at 700, so the two are never taken for each other
   (Alipasha, 11 Oct 2026). The plumliners' side keeps its own weight
   (plumliners.css). */
h1, h2, h3 { line-height: 1.2; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 0.5em; }
h4, h5, h6 { font-weight: 700; }
/* A title and the line under it are read as shapes before they are read as
   words, so the browser is asked to even the lines rather than leave one word
   stranded on the last of them. Every page, not only this one. */
h1 { font-size: clamp(1.9rem, 5vw, 3rem); font-weight: 300; text-wrap: balance; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.2rem; }
p { margin: 0 0 1em; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }

/* ---- section colour ----------------------------------------
   The public side has one highlight, and it is plum. The sections
   used to wear a family each — sage, rose, indigo — and four
   families were more than a calm page could carry. Every page still
   names its section on <body>, and everything below reads --sect, so
   a family could come back here without touching a page. */
body { --sect: var(--plum); --sect-text: var(--plum-text); --sect-soft: var(--plum-soft); }

/* the readable measure, nested inside .wrap so it stays left-aligned
   against the container rather than centring itself in the window */
.measure { max-width: 64ch; }
:focus-visible { outline: var(--focus-ring); outline-offset: 2px; border-radius: var(--radius-xs); }

.skip {
  position: absolute; left: -9999px;
  background: var(--card); color: var(--ink);
  padding: 0.6rem 1rem; border-radius: var(--radius-xs); z-index: 100;
}
.skip:focus { left: 20px; top: 0.6rem; }

/* ---- header ------------------------------------------------
   Sticky, translucent, hairline bottom border. The frame never
   takes a section colour — all the saturation lives in content. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--ground-blur);
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--rule);
}
.site-header .bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.6rem 1rem; flex-wrap: wrap;
  max-width: var(--maxw); margin: 0 auto; padding: 0.7rem 20px;
}
/* The name at the body's weight, with its letters at their own spacing
   (Alipasha, 12 Oct 2026). */
.wordmark {
  display: flex; align-items: center; color: var(--ink);
  font-weight: 400; font-size: 1.1rem;
}
.wordmark:hover { text-decoration: none; }
.sangha { display: inline-flex; }
.wordmark .sangha { margin-right: 0.5rem; }
.sangha span {
  font-size: 1.1rem; line-height: 1; margin-right: -0.62em;
  filter: drop-shadow(0 0 1.5px var(--ground));
}
.sangha span:last-child { margin-right: 0; }

/* Every place in the bar has the room round it that the page you are on
   has, so a word stays where it is whichever page is open; the room between
   two words is the two paddings, about what the gap was (Alipasha,
   12 Oct 2026). */
.site-header nav { display: flex; flex-wrap: wrap; gap: 0.3rem 0; font-size: 0.95rem; }
.site-header nav a { color: var(--ink); padding: 0.1rem 0.6rem; }
.site-header nav a[aria-current] { background: var(--accent-soft); border-radius: var(--radius-pill); }
/* Home, About, Builders and Contact, then a line, then the Sangha Finder in the
   accent, set apart as the thing the site is for (Alipasha, 11 Oct 2026),
   at the same weight as the words beside it; Sangha Builders is Builders in
   the bar and the footer (12 Oct 2026). The line is drawn, not read.
   Plumliners lives in the footer. */
.site-header nav .nav-sep {
  align-self: stretch;
  width: 1px;
  margin: 0.2rem 0.5rem;
  background: color-mix(in srgb, var(--muted) 45%, var(--rule));
}
.site-header nav .nav-sep + a:not([aria-current]) { color: var(--accent-strong); }
/* The main site's bar, the one with the line before the Sangha Finder
   (Alipasha, 11 Oct 2026): the band's colour with a shadow falling from it,
   as the finder's own bar has; every word in the ink with a white line
   under it, as if pressed into the band; the page you are on sunk into the
   band; and the Sangha Finder raised as a button. A sangha contact has the
   same bar, with My Sanghas in the Sangha Finder's place (13 Oct 2026).
   Pages that carry both sides' bars hold the line even while the
   plumliners' side is showing, so the band is only for the public side:
   a page with no plumliners' side (no .plumliners), the warm side of one, or
   Sign In, which is public for everyone until they are signed in. */
:where(html.warm, body:not(.plumliners), body.sign-in-page) .site-header:has(.nav-sep) {
  background: var(--ground-2);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: 0 1px 4px rgb(30 20 30 / 14%);
}
:where(html.warm, body:not(.plumliners), body.sign-in-page) .site-header:has(.nav-sep) :is(.wordmark, nav a) { color: var(--ink); text-shadow: white 0px 1px 1px; }
:where(html.warm, body:not(.plumliners), body.sign-in-page) .site-header:has(.nav-sep) nav a[aria-current] {
  background: var(--sunk-face);
  box-shadow: var(--sunk-face-lines);
  border-radius: var(--radius-xs);
}
/* Raised as a button everywhere but its own pages. There it is the page you
   are on, and is drawn exactly as any page you are on is, by the rule above
   (Alipasha, 11 Oct 2026). It stays plum when the other buttons on this
   side turn white (16 Oct 2026). */
:where(html.warm, body:not(.plumliners), body.sign-in-page) .site-header:has(.nav-sep) nav .nav-sep + a:not([aria-current]) {
  background: linear-gradient(oklch(from var(--accent-strong) calc(l + 0.2) calc(c * 0.8) h), var(--accent-strong));
  border-radius: var(--radius-xs);
  color: white;
  text-decoration: none;
  text-shadow: oklch(from var(--accent-strong) calc(l - 0.1) c h) 0px -1px;
  box-shadow: var(--lift);
}
/* Plain colours for Safari before 18 (see tokens.css). */
@supports not (color: oklch(from red calc(l + 0.1) c calc(h + 1))) {
  :where(html.warm, body:not(.plumliners), body.sign-in-page) .site-header:has(.nav-sep) nav .nav-sep + a:not([aria-current]) {
    background: linear-gradient(#a179ba, var(--accent-strong));
  }
}
/* My Sanghas, in the Sangha Finder's place for a sangha contact, takes the
   Sangha Finder's room, so the words before it stay where they are from page
   to page (Alipasha, 13 Oct 2026): the longer name is laid in the same cell,
   unseen and unread. Set softly, so a rule that hides one side's bar
   still wins. */
:where(.site-header nav) a[data-room] { display: inline-grid; justify-items: center; }
:where(.site-header nav) a[data-room]::after { content: attr(data-room); height: 0; overflow: hidden; visibility: hidden; }
/* Below 620px the same links fold under Menu. The class is set before the
   page is painted, so the list does not flash open. Without it — a browser
   with scripts turned off — the links stay in the bar and Menu stays put away. */
.site-header .nav-menu { display: none; }
@media (min-width: 621px) {
  .site-header .nav-menu { display: none; }
}
@media (max-width: 620px) {
  .site-header .bar { position: relative; padding-bottom: 0.5rem; }
  /* The first word keeps the page's left edge, its room hanging outside it.
     A bar without Menu still wraps onto the next line. */
  .site-header nav { width: calc(100% + 0.5rem); margin-left: -0.5rem; font-size: 0.85rem; gap: 0.2rem 0; }
  .site-header nav a { padding-inline: 0.5rem; }
  /* The line before the Sangha Finder would only dangle at the end of a line. */
  .site-header nav .nav-sep { display: none; }
  /* Wordmark and Menu on one line; the list, once open, on the line under them. */
  html.nav-ready .site-header:has(.nav-menu) .bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 0.6rem;
  }
  html.nav-ready .site-header:has(.nav-menu) .wordmark { grid-column: 1; grid-row: 1; }
  html.nav-ready .site-header:has(.nav-menu) > .bar > nav,
  html.nav-ready .site-header:has(.nav-menu) .bar > nav { display: none; }
  html.nav-ready .site-header .nav-menu {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    display: inline-flex;
    align-items: center;
    margin: 0;
    padding: 0.35rem 0.55rem;
    font: inherit;
    font-size: 0.95rem;
    line-height: 1.2;
    color: var(--ink);
    text-shadow: white 0px 1px 1px;
    background: transparent;
    border: 0;
    border-radius: var(--radius-xs);
    cursor: pointer;
  }
  /* Open, Menu sinks into the band, as the page you are on does. */
  html.nav-ready .site-header.nav-open .nav-menu {
    background: var(--sunk-face);
    box-shadow: var(--sunk-face-lines);
  }
  html.nav-ready .site-header.nav-open .bar > nav {
    grid-column: 1 / -1;
    grid-row: 2;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    width: calc(100% + 0.5rem);
    min-width: 0;
    margin: 0.35rem 0 0.15rem -0.5rem;
    gap: 0.05rem;
  }
  html.nav-ready .site-header.nav-open .bar > nav a { padding-block: 0.45rem; }
}

/* ---- page scaffolding -------------------------------------- */
.hero { padding-block: var(--space-page) 1rem; }
.kicker {
  font-size: 0.8rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--sect-text); margin-bottom: 0.6rem;
}
/* The words under a page's title are the page's own words, in the body's
   size and colour, not a grey subtitle a size up (Alipasha, 12 Oct 2026).
   The plumliners' pages keep their line under the title (plumliners.css). */
.lede { max-width: 64ch; }
.note { font-size: 0.95rem; color: var(--muted); max-width: 64ch; }
section.block { padding: clamp(2.2rem, 6vw, 3.4rem) 0; border-top: 1px solid var(--rule); }
section.block.alt { background: var(--ground-2); }
/* A section's heading has the room under it that the page's title has,
   so a heading and its words sit together the same way everywhere. */
:is(section.block > .wrap, section.block .measure, .beside-photo > div, .songbook-section, .directory-body > section) > h2 {
  margin-bottom: var(--space-title);
}
body:not(.plumliners) .hero h1 { margin-bottom: var(--space-title); }


/* ---- buttons ----------------------------------------------
   No button is filled with a colour, but for the Sangha Finder link
   raised in the bar: the one that acts is a white button like the
   rest, its words saying what it does (Alipasha, 16 Oct 2026; until
   then it was filled plum). */
/* A button is a control, so it is drawn like every other control: the
   smallest corner the page has, the card surface where it is not filled, and
   --lift, which is the one amount of depth a thing you press ever carries.
   It used to be a pill that rose a pixel under the pointer; the rise is gone
   with it, because depth that moves is a second amount. Its words are in
   the regular weight, as the words around it are (Alipasha, 11 Oct 2026). */
.btn {
  display: inline-flex; align-items: center; gap: 0.5em;
  font-family: var(--font); font-size-adjust: var(--x-height); font-weight: 400; font-size: var(--control-font);
  line-height: var(--control-line); padding: var(--control-pad-y) var(--control-pad-x);
  border-radius: var(--radius-xs);
  border: var(--control-border) solid transparent; cursor: pointer; text-decoration: none;
  box-shadow: var(--lift);
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.btn:hover { text-decoration: none; }
/* A white button stands up from the page: white at its top, running down
   to the ground's own colour, with no line round it but a soft shadow, and
   a line a little darker than the ground along its foot (Alipasha,
   12 Oct 2026). Its edge is kept but clear, with the face drawn under it,
   so it stays as tall as a filled button beside it; the line along its foot
   is drawn on the face for the same reason, where an inset shadow would sit
   inside the clear edge. A little darker under the pointer. The button that
   acts, .btn-primary, is drawn the same (16 Oct 2026). */
.btn-ghost, .btn-primary {
  color: var(--ink);
  background: var(--white-face);
  border-color: var(--white-face-edge);
  box-shadow: var(--white-face-lines);
}
:is(.btn-ghost, .btn-primary):hover {
  background: var(--white-face-hover);
}

/* ---- cards -------------------------------------------------
   The recurring unit: kicker, title, three lines of muted
   description, one link ending in an arrow. */
.cards { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 621px) { .cards { grid-template-columns: 1fr 1fr; } }
@media (min-width: 901px) { .cards.three { grid-template-columns: 1fr 1fr 1fr; } }
.card {
  display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.3rem 1.3rem 1.4rem;
  transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--sect); }
.card h3 { margin: 0 0 0.3rem; }
.card p { margin: 0; color: var(--muted); font-size: 0.95rem; }
.card.sect { border-top: 3px solid var(--sect); }
/* The cards on the public side: Home's three ways in, each one link;
   Sangha Builders' three other ways in, under the events, each name a
   link; and the first of those where Contact's photograph was. The name
   first, small and at 500; under it a photograph in a white mat, as the
   others are but thinner, every one cut to the same shape; then its words,
   on the page itself. No box round them, nothing that moves under the
   pointer, and wider apart (Alipasha, 12 Oct 2026). */
:is(.home-ways .cards, .cards.ways) { gap: 2.5rem 3rem; }
:is(.home-ways .card, .card.way) {
  padding: 0; background: none; border: 0; border-radius: 0; transition: none;
  color: var(--ink);
}
:is(.home-ways .card, .card.way):hover { transform: none; box-shadow: none; text-decoration: none; }
:is(.home-ways .card, .card.way .way-picture) > img {
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover;
  border: 5px solid var(--frame);
  box-shadow: 0 4px 7px oklch(from var(--ground) calc(l - 0.15) calc(c * 3) h);
}
:is(.home-ways .card, .card.way) h2 { font-size: 1.1rem; font-weight: 500; margin: 0 0 0.8rem; }
:is(.home-ways .card, .card.way) > p { margin: 0; }
:is(.home-ways .card > img, .card.way > .way-picture) + p { margin-top: 1rem; }
/* On Sangha Builders and Contact the picture leads where the name above it
   does, so a person can press either (Alipasha, 20 Oct 2026). It is a second
   way to the same place, so it is kept out of the tab order and hidden from
   screen readers, which have the name already. Apply for a Mentor's picture
   is a button, as its name is, and opens the same form. */
.card.way .way-picture {
  display: block; width: 100%; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; cursor: pointer;
}
/* A card that leads somewhere says so with an arrow after its name, where a
   link elsewhere has its underline: on Home the whole card is the link, on
   Sangha Builders and Contact the name and its picture are (Alipasha, 12 and
   20 Oct 2026). Apply for a Mentor is a button, since it opens its form on
   the page, and looks like the other names. The arrow is Alipasha's drawing,
   laid on a small white disc raised as the white buttons are, so it says
   there is somewhere to go without calling out: the disc comes after the
   name and the arrow over it. Both are drawn, so a screen reader has nothing
   to read out; the arrow's shape is public/art/arrow.svg. */
.card.way h2 :is(a, button) {
  display: inline-flex; align-items: center;
  color: inherit; text-decoration: none; font: inherit; text-align: inherit;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.home-ways .card h2 { display: flex; align-items: center; }
:is(.home-ways .card h2, .card.way h2 :is(a, button))::after {
  content: ""; order: 2; flex: none; width: 1.15em; height: 1.15em; margin-left: 0.45em;
  border-radius: 50%;
  background: var(--white-knob);
  box-shadow: var(--white-face-lines);
}
:is(.home-ways .card h2, .card.way h2 :is(a, button))::before {
  content: ""; order: 3; flex: none; width: 1.15em; height: 1.15em; margin-left: -1.15em;
  background: var(--sect-text);
  -webkit-mask: url("/art/arrow.svg") center / 82% no-repeat;
  mask: url("/art/arrow.svg") center / 82% no-repeat;
}
.card.way .form-status:not(:empty) { margin: 0.6rem 0 0; }
.card.way > .credit { margin-top: 0.5rem; }
/* On Contact the card stands where a photograph stands on the other
   pages' heads, at the same width, and under the words on a narrow
   screen. */
.page-welcome .way-column { min-width: 0; }
@media (max-width: 900px) {
  .page-welcome .way-column { max-width: 30rem; margin-top: clamp(1.5rem, 4vw, 2.4rem); }
}
/* On Contact the title has a row of its own, so the card's top meets the
   top of the words under it, not the title's (Alipasha, 12 Oct 2026). Their
   first line is trimmed to its capitals, as the title is, and what that
   takes off, a little under half a rem, is given back above both, so the
   words stay where they were. Under 900px the four stack. */
.contact-head > h1 { grid-column: 1; }
.contact-head > .welcome-words { grid-column: 1; grid-row: 3; }
.contact-head > .way-column { grid-column: 2; grid-row: 3; }
.contact-head > .welcome-words > p:first-child { text-box: trim-start cap alphabetic; }
.contact-head > :is(.welcome-words, .way-column) { margin-top: 0.49rem; }
@media (max-width: 900px) {
  .contact-head > :is(h1, .welcome-words, .way-column) { grid-column: auto; grid-row: auto; }
  .contact-head > .way-column { margin-top: clamp(1.5rem, 4vw, 2.4rem); }
}

.card.sect .kicker { margin-bottom: 0.3rem; }

/* ---- grouped rows -----------------------------------------
   Long lists are bands with generous padding, each row a title
   and one italic line — never a dense table. */
.rows { border-top: 1px solid var(--rule); margin-top: 1.4rem; max-width: 48rem; }
.rows a.row, .rows div.row {
  display: block; padding: 0.95rem 0.2rem;
  border-bottom: 1px solid var(--rule); color: var(--ink);
}
.rows a.row:hover { text-decoration: none; background: var(--card); }
.rows a.row:hover .row-title { color: var(--sect-text); }
.row-title { font-weight: 600; font-size: 1rem; }
.row-note { display: block; font-style: italic; color: var(--muted); font-size: 0.95rem; line-height: 1.5; max-width: 64ch; }



/* ---- a list of sessions ------------------------------------
   Events on Sangha Builders, one under another, on the band, each with
   its date on a tile at the left, the month over the day (Alipasha,
   12 Oct 2026; plain rules between them before, from #66). Each session
   is a <details>: the date, title and teacher are always in view, and
   the description and times open on a click. No JavaScript, so it works
   with scripting off.

   Each is a thing to press, so it wears the white button's face: white
   running down to the ground, the soft shadow and the line along its
   foot. At its right a round control says it opens: a chevron pointing
   down on a raised disc, turned up once it is open (Alipasha, 12 Oct
   2026). The disc stays white when it is open, the whole card lightens
   under the pointer, and the date's tile is sunk into the card as the page
   you are on is into the bar (Alipasha, 14 Oct 2026). A card that neither
   opens nor leads anywhere stays as it is under the pointer (15 Oct). */
.sessions { max-width: 52rem; margin-top: 1rem; display: grid; gap: 0.7rem; }
.sessions .session {
  background: var(--white-face);
  border: 1px solid var(--white-face-edge); border-radius: var(--radius-xs);
  box-shadow: var(--white-face-lines);
}
.sessions :is(a, details).session:hover {
  background: var(--white-face-hover);
}
.sessions summary {
  display: grid; grid-template-columns: 4rem 1fr auto; gap: 0.15rem 1rem; align-items: center;
  padding: 0.8rem 0.9rem 0.8rem 0.8rem; cursor: pointer; list-style: none;
}
.sessions summary::-webkit-details-marker { display: none; }
/* The disc, then the chevron laid over it, in the same cell. */
.sessions summary::before,
.sessions summary::after {
  content: ""; grid-column: 3; grid-row: 1; width: 2rem; height: 2rem; border-radius: 50%;
}
.sessions summary::before {
  background: var(--white-knob);
  box-shadow: var(--white-face-lines);
}
.sessions summary::after {
  background: var(--sect-text);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5l4 4 4-4'/%3E%3C/svg%3E") center / 55% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5l4 4 4-4'/%3E%3C/svg%3E") center / 55% no-repeat;
}
.sessions .session[open] summary::after { transform: rotate(180deg); }
/* The tile is debossed, pressed into the card: a shadow inside along its
   top, a darker line round its inside edge, and a white line under its
   foot where the card's own face catches the light (Alipasha, 16 Oct 2026). */
.sessions .when {
  display: block; line-height: 1.25; padding: 0.45rem 0; text-align: center;
  background: var(--sunk-face);
  box-shadow: inset 0 2px 3px oklch(from var(--ground-2) calc(l - 0.4) calc(c * 3) h / 45%),
    inset 0 0 0 1px oklch(from var(--ground-2) calc(l - 0.14) calc(c * 2) h),
    0 1px 0 white;
  border-radius: var(--radius-xs);
}
.sessions .mon {
  display: block; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--sect-text);
}
/* The day in ink: muted on the sunk disc read 4.09:1, short of the 4.5:1 that
   small words need (PageSpeed, 16 Oct 2026). */
.sessions .day { display: block; font-size: 0.8rem; color: var(--ink); }
.sessions .session-title { display: block; font-weight: 600; font-size: 1rem; color: var(--ink); }
.sessions .session-who { display: block; font-style: italic; color: var(--muted); font-size: 0.9rem; }
.sessions .session-more { padding: 0 1.1rem 1.1rem 5.8rem; }
.sessions .session-more p { margin: 0; font-size: 0.95rem; color: var(--muted); }
.sessions .session-more p + p { margin-top: 0.5rem; }
.sessions .times { font-size: 0.9rem; font-variant-numeric: tabular-nums; }
.sessions .times + .times { margin-top: 0.2rem; }
.sessions .tz-note { margin: 0.9rem 0 0; font-size: 0.8rem; font-style: italic; color: var(--muted); }
@media (max-width: 480px) { .sessions .session-more { padding-left: 0.8rem; } }



/* ---- a lightbox --------------------------------------------
   A <dialog> in the page's own materials: the page's darker band, so
   the fields in it stand out, the hairline, the page's corner. It opens where the person is, so a
   form does not have to live at the foot of the page to be found. */
.lightbox {
  width: min(34rem, calc(100vw - 2rem)); max-height: calc(100vh - 3rem);
  /* The window that shows, so on a phone its foot is never under the toolbar. */
  max-height: calc(100dvh - 3rem);
  padding: 0; border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ground-2); color: var(--ink); box-shadow: var(--shadow);
}
.lightbox::backdrop { background: var(--backdrop, rgb(43 39 35 / 45%)); }
/* The head stays at the top while a long box scrolls under it, so its
   title and its buttons are always to hand (Alipasha, 15 Oct 2026). */
.lightbox-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem;
  padding: 1.2rem 1.4rem 0.9rem; border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 2; background: var(--ground-2);
}
.lightbox-head h2 { margin: 0; font-size: 1.35rem; }
/* Big enough for a thumb, the × where it was. */
.lightbox-close {
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
  display: inline-grid; place-items: center; min-width: 2.25rem; min-height: 2.25rem;
  margin: -0.35rem -0.55rem -0.35rem 0;
  font: inherit; font-size: 1.6rem; line-height: 1; color: var(--muted);
}
.lightbox-close:hover { color: var(--ink); }
.lightbox-body { padding: 1rem 1.4rem 1.2rem; }
.lightbox-body > p:first-child { margin-top: 0; color: var(--muted); }
.lightbox .form { margin-top: 1rem; max-width: none; }
.lightbox .field textarea { min-height: 7rem; }

/* ---- long-form reading -------------------------------------
   A page to read, such as Privacy: lists at the reading measure. */
.measure ul { padding-left: 1.15rem; margin: 0 0 1em; }
.measure li { margin-bottom: 0.35em; }


/* ---- photographs -------------------------------------------
   A photograph sits at the reading measure in a square-cornered
   white mat, and carries its credit beneath rather than over it. */
figure.photo { margin: 1.8rem 0; max-width: 44rem; }

/* We do not crop photographs. Every fixed ratio we tried cut people in
   half — heads off the top of a section band, bodies off the bottom of a
   letterboxed banner — and an uneven column of images is a far smaller
   price than a picture of a sangha with the sangha trimmed out of it.

   Which leaves width as the only handle on height. A banner used to run
   the full 1120px container, so an ordinary 3:2 photograph arrived 750px
   tall and pushed the page's first words off the screen. Every photograph
   now sits at one width, a little wider than the text it accompanies. */
figure.photo img { width: 100%; display: block; }
/* Every picture in a figure stands in a white mat with square corners, as a
   print would, lifted off the page by a shadow cut from the page's own
   ground: deeper, and a little stronger in its hue, so it reads as the
   page's shade rather than a grey laid over it. The globe on a sangha's page
   and the songbook's pictures are pictures too. The caption stays outside
   the mat. */
figure img,
figure.sangha-picture .globe {
  border: 10px solid var(--frame);
  box-shadow: 0 4px 7px oklch(from var(--ground) calc(l - 0.15) calc(c * 3) h);
}
figure.photo figcaption {
  font-size: 0.85rem; color: var(--muted); margin-top: 0.55rem; font-style: italic;
  max-width: 52rem;
}

/* ---- the welcome ------------------------------------------------
   The finder opens with a short welcome, because what it is offering is a way
   of finding people rather than a page to read. The welcome and the photograph
   sit side by side so that both of them and the top of the directory are on
   the first screen: stacked, the welcome alone was two screens of scrolling
   before anything could be searched. Sangha Builders opens the same way now
   (#66), so these rules live here rather than in the finder's own sheet. */
.welcome {
  display: grid;
  /* The letter is set to the measure it wants to be read at and the
     photograph to a size that ends near where the letter does; the space
     left over goes between them, with each held to the gutter it is nearest.
     Sized as fractions of the width instead, the photograph grew with the
     window until it was half again the height of the words beside it. Both
     measures are in rem so that the column and the text's own max-width
     cannot disagree — in `ch` they were worked out at two different font
     sizes and did. */
  grid-template-columns: minmax(0, 30rem) minmax(0, 26rem);
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3rem);
  /* Aligned at the top, not the middle: centred, neither the top edge nor the
     bottom lined up with anything, and two ragged edges read as a mistake
     where one reads as a decision. */
  align-items: start;
  /* The room under it is the room the section below has over it, so the rule
     between them sits in the middle of its own space rather than clinging to
     the letter. Above it there is only the gap between the title and the
     welcome: the room that keeps the page off the bar is the head's now. */
  padding-block: clamp(1.5rem, 3.5vw, 2.2rem) clamp(2.2rem, 6vw, 3.4rem);
}
/* The letter is in the body's own size, as every page's words under its
   title are (Alipasha, 12 Oct 2026); it was a little larger. */
.welcome-words { max-width: 30rem; }
.welcome-words p:last-child { margin-bottom: 0; }
.welcome figure.photo { margin: 0; max-width: none; }

/* A section with its photograph to the right, as the page's head has one:
   the words in the head's column, the photograph as wide as the head's, and
   both edges level with it; the heading trimmed to its capitals so the two
   tops meet (Alipasha, 12 Oct 2026). Under 900px the photograph comes under
   the words, as in the head. */
.beside-photo {
  display: grid;
  grid-template-columns: minmax(0, 30rem) minmax(0, 26rem);
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
.beside-photo > :first-child > h2:first-child { text-box: trim-start cap alphabetic; }
.beside-photo figure.photo { margin: 0; max-width: none; }

/* Under 900px — the same width at which the finder itself gives up its second
   column — there is no room for two, so the letter takes the width and the
   photograph follows it. It is held to a size a tablet can take in at a
   glance: at the full width of that screen it is a billboard, and the
   directory below it is a scroll away for no reason. */
@media (max-width: 900px) {
  .welcome, .beside-photo { grid-template-columns: minmax(0, 1fr); }
  .welcome figure.photo, .beside-photo figure.photo { max-width: 30rem; }
}

/* About, Sangha Builders and Contact open the same way (Alipasha, 11 Oct
   2026): the kicker on a line of its own, then the title and its words in
   one column and the photograph beside them, every photograph the same
   width, its top level with the top of the title. The title's box is
   trimmed to the top of its capitals, so the two tops meet rather than the
   photograph sitting a line-gap above the letters. */
.page-welcome { row-gap: 0; padding-top: clamp(2.4rem, 6vw, 3.6rem); }
/* The kicker's margin is a kicker's plus what the trim took off the title's
   line, a fifth of the title's size, so it sits as far above the capitals as
   on every other page. */
.page-welcome > .kicker {
  grid-column: 1 / -1;
  margin-bottom: calc(0.6rem + 0.2 * clamp(1.9rem, 5vw, 3rem));
}
.page-welcome h1 { text-box: trim-start cap alphabetic; margin-bottom: var(--space-title); }
/* Under 900px the photograph comes under the words, at one width. */
@media (max-width: 900px) {
  .page-welcome figure.photo { margin-top: clamp(1.5rem, 4vw, 2.4rem); }
}

/* About opens, and its sections run, with the title or the heading on a row
   of its own, so each photograph's top meets the top of the first paragraph
   beside it rather than the heading's (Alipasha, 12 Oct 2026; Contact's head
   does the same). That first line is trimmed to its capitals, as the title
   is, so the two tops meet, and what the trim takes off, a little under half
   a rem, is given back above both. Under 900px the photograph follows the
   words, as before: the rules that undo the placing name each child as the
   rules that place it do, so they are as specific and, coming later, win.
   A plain .title-row > * loses to them, and the grid then keeps a second
   column for the photograph and leaves the words none (Christian, 12 Oct
   2026). */
.page-welcome.title-row > h1 { grid-column: 1; }
.page-welcome.title-row > .welcome-words { grid-column: 1; grid-row: 3; }
.page-welcome.title-row > figure.photo { grid-column: 2; grid-row: 3; }
.beside-photo.title-row { row-gap: 0; }
.beside-photo.title-row > h2 {
  grid-column: 1; text-box: trim-start cap alphabetic;
  margin-bottom: var(--space-title, clamp(1.2rem, 3vw, 1.8rem));
}
.beside-photo.title-row > div { grid-column: 1; grid-row: 2; }
.beside-photo.title-row > figure.photo { grid-column: 2; grid-row: 2; }
.title-row > div > p:first-child { text-box: trim-start cap alphabetic; }
.title-row > :is(div, figure.photo) { margin-top: 0.49rem; }
@media (max-width: 900px) {
  .page-welcome.title-row > :is(h1, .welcome-words, figure.photo),
  .beside-photo.title-row > :is(h2, div, figure.photo) { grid-column: auto; grid-row: auto; }
  .title-row > figure.photo { margin-top: clamp(1.5rem, 4vw, 2.4rem); }
}

/* The page's head: the kicker, where there is one, says what part of plumline
   this is; the title is the name.
   Its room above comes from here rather than from the welcome below it, which
   used to be the first thing on the page. */
.page-head {
  padding-block: clamp(2.4rem, 6vw, 3.6rem) 0;
}
/* The welcome under such a head follows the title at the title's room, as
   on every other page, with no room of its own above it; its photograph's
   top meets the top of the first paragraph beside it, the first line
   trimmed to its capitals and what the trim takes given back above both
   (Alipasha, 12 Oct 2026; the Songbook). */
.page-head h1 { margin-bottom: var(--space-title); }
.page-head + .welcome { padding-top: 0; }
.page-head + .welcome > .welcome-words > p:first-child { text-box: trim-start cap alphabetic; }
.page-head + .welcome > :is(.welcome-words, figure.photo) { margin-top: 0.49rem; }
@media (max-width: 900px) {
  .page-head + .welcome > figure.photo { margin-top: clamp(1.5rem, 4vw, 2.4rem); }
}

/* ---- forms --------------------------------------------------
   The contact page is the only form in this stylesheet so far, and
   it is built from the same tokens as everything else: the card
   surface, one hairline, and the plum focus ring that every other
   control on the site already uses. The sign-in page's email field
   is the same .field, on the plumliners' ground.

   The measure is narrower than the reading measure on purpose — a
   text field the full width of a paragraph is tiring to read back. */
.form { max-width: 34rem; margin: 1.6rem 0 0.4rem; }
/* A form among a page's opening words, as on Contact, follows them at the
   room words keep. */
.welcome-words > .form { margin-top: var(--space-text); }
.field { margin-bottom: 1.1rem; }
.field label { display: block; font-weight: 600; font-size: 0.95rem; margin-bottom: 0.35rem; }
/* A field that must be filled has a red star after its label, and a line
   above the form says what the star means. Here, not in sangha-form.css,
   so the Sangha Builders forms mark theirs too (Alipasha, 16 Oct 2026). */
.required-fields-note { margin: 0.5rem 0 0; color: var(--muted); font-size: 0.85rem; }
.required-marker { color: var(--unwhole-text); font-weight: 700; }
.field input,
.field textarea {
  width: 100%; font: inherit; font-size: var(--control-font); line-height: var(--control-line); color: var(--ink);
  background: var(--card); border: var(--control-border) solid var(--field-edge);
  border-radius: var(--radius-xs); padding: var(--control-pad-y) var(--control-pad-x);
  box-shadow: var(--sink);
}
/* A box to write in has an edge darker than a hairline, so where to write
   can be seen (--field-edge, 3:1 and over). A tick in a field keeps its
   own small square. */
.field :is(input[type="checkbox"], input[type="radio"]) { width: auto; padding: 0; box-shadow: none; }
/* Words that run to several lines need more room between them. */
.field textarea { resize: vertical; min-height: 9rem; line-height: 1.5; }
/* What a field holds before anything is written in it is set in italic, on
   every page of both sides, so it is never read as something already
   written (Alipasha, 11 Oct 2026). */
::placeholder { font-style: italic; }
/* In the page's quiet colour, not the browser's own paler grey. */
::placeholder { color: var(--muted); opacity: 1; }
.field input:focus,
.field textarea:focus {
  outline: var(--focus-ring); outline-offset: 2px;
}
.field :is(input, select, textarea):disabled,
.field label:has(:disabled) { cursor: not-allowed; }
.field-note { font-size: 0.85rem; color: var(--muted); margin: 0.35rem 0 0; }
/* A form whose names stand beside their fields rather than over them, the
   contact form's (Alipasha, 12 Oct 2026). The names share one column as wide
   as the longest, so every field starts at one edge, and what follows the
   fields, the line the form says back and the button, starts there too. A
   message's name sits level with its first line. On a phone the names go
   back over their fields. */
.form.labels-beside {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 1rem;
}
.form.labels-beside > .field {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: center;
}
.form.labels-beside > .field label { margin-bottom: 0; }
.form.labels-beside > .field:has(textarea) { align-items: start; }
.form.labels-beside > .field:has(textarea) label { padding-top: calc(var(--control-pad-y) + var(--control-border)); }
.form.labels-beside > :not(.field) { grid-column: 2; }
@media (max-width: 620px) {
  .form.labels-beside,
  .form.labels-beside > .field { display: block; }
  .form.labels-beside > .field label,
  .form.labels-beside > .field:has(textarea) label { margin-bottom: 0.35rem; padding-top: 0; }
}

/* The field only a robot fills in. Off the side of the page rather than
   display:none or hidden, both of which a fair number of them skip. */
.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* One line carries everything the form says back. It keeps its height when
   empty would collapse the page under the button as the message appears. */
.form-status { margin: 0 0 0.6rem; font-size: 0.95rem; min-height: 1.55rem; }
.form-status:empty { min-height: 0; margin: 0; }
.form-status.ok { color: var(--whole-text); }
.form-status.bad { color: var(--unwhole-text); }
.btn[disabled] { opacity: 0.6; cursor: default; box-shadow: none; }
/* The intro page, when its link has run out or cannot be read: what went
   wrong, in the colour of a thing that did not work. */
.intro-page-error {
  max-width: 34rem; padding: 0.6rem 0.9rem; border-radius: var(--radius-xs);
  background: var(--unwhole-soft); color: var(--unwhole-text);
}

/* ---- footer ------------------------------------------------
   The last band on the page, and the only place fine print lives.
   It is the deeper ground of the alternating bands, under a hairline:
   quiet, and in the page's own family rather than set against it. A
   page that ends on a band of its own is kept apart by the hairline.
   It reads only shared names, so the plumliners' side draws it cool without
   a rule of its own. Measured on the deeper ground: text 12.4:1, links
   6.6:1; on the cool side 12.1:1 and 6.1:1. Fine print is the ground
   itself, darkened and twice as rich, 4.6:1 on either: Alipasha's pick
   was lighter, 2.8:1, and Christian, reviewing #212, held it to the
   4.5:1 small type needs (test/site-footer.test.ts measures it). */
/* Its words are small, so the room above and below them is in keeping
   with them: half the room a page's first words have under the bar, which
   it had at first and which left the band mostly empty (Alipasha,
   18 Oct 2026). */
.site-footer {
  background: var(--ground-2); color: var(--ink); border-top: 1px solid var(--rule);
  padding: calc(var(--space-page) / 2) 0; margin-top: 1rem;
}
.site-footer a { color: var(--sect-text); }
.site-footer .fine { font-size: 0.85rem; color: oklch(from var(--ground-2) calc(l - 0.42) calc(c * 2) h); margin: 0.5rem 0 0; max-width: 64ch; }
/* The footer carries About, the Sangha Finder, Builders, Plumliners (the
   way in for the people who keep the directory), Contact and Privacy.
   Plumliners lives only here. The bar has Home, About, Builders and Contact,
   then the Sangha Finder set apart at its end. */
.site-footer nav { display: flex; flex-wrap: wrap; gap: 0.4rem 1.2rem; font-size: 0.95rem; margin: 0 0 0.4rem; }
/* Its links are drawn as the bar's are: in ink, the highlight kept for a
   link inside a sentence. */
.site-footer nav a { color: var(--ink); }
/* The page you are on is not marked here. The bar and the page's own heading
   already say where you are, and in the footer an underline read as a link
   set apart rather than as "you are here". The links keep aria-current, so a
   screen reader still says which one is this page. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; scroll-behavior: auto !important; }
}

/* A line while a list is still on its way. The words are the page's.
   They ease off and back so a long wait still looks alive, and they
   stay still for someone who asked for less motion. */
.loading-status { margin: 0 0 1rem; color: var(--muted); }
.loading-status.is-waiting { animation: loading-pulse 1.6s ease-in-out infinite; }
@keyframes loading-pulse { 50% { opacity: 0.45; } }
.map-page .sangha-cards > .loading-status { margin: 0; padding: 1.2rem 1rem; }
@media (prefers-reduced-motion: reduce) {
  .loading-status.is-waiting { animation: none; }
}

/* ---- small type ---------------------------------------
   Everything this sheet sets at 0.9rem or smaller, apart from
   small capitals, is set a little apart (--tracking-small in
   tokens.css). Kept in one list rather than beside each size,
   at no weight of its own, so a rule that sets its own spacing
   still has the last word. A new small size belongs here too. */
@media (max-width: 620px) {
  :where(
    .site-header nav
  ) { letter-spacing: var(--tracking-small); }
}
:where(
  .sessions .day,
  .sessions .session-who,
  .sessions .times,
  .sessions .tz-note,
  figure.photo figcaption,
  .field-note,
  .site-footer .fine
) { letter-spacing: var(--tracking-small); }
