/* magdalena.ca — shared stylesheet
   Built from the magdalena.ca 2.0 Figma (Web Design - Desktop).
   FONTS: brand faces are Neue Haas Grotesk Display (sans) and Canela (serif wordmark).
   Licenses not yet purchased — stand-in stacks below. To swap after purchase:
   add @font-face blocks and change the two --font-* variables. Nothing else moves. */

:root {
  --bg: #0f0f0f;
  --chalk: #f4f4f2;          /* soft chalk white */
  --grey-light: #d6d8d4;     /* cool light grey */
  --grey-mid: #9ea1a0;       /* mid structural grey */
  --grey-anchor: #6e7271;    /* anchor grey */

  --font-sans: "Neue Haas Grotesk Display", "neue-haas-grotesk-display", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-serif: "Canela", "Times New Roman", Georgia, serif;

  --content-w: 1152px;
  --gutter: 24px;
  --section-pad: 120px;
  --col-gap: 96px;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--chalk);
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 17px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

/* ---------- type ---------- */
/* 55 Roman stands in at 400 site-wide — 500 pulled Helvetica's Medium and
   read thicker than the Figma (Hannah, 2026-08-20). Re-map when Neue Haas lands. */
.h4 { font-weight: 400; font-size: 24px; line-height: 1; letter-spacing: 0.1em; text-transform: uppercase; color: var(--chalk); }
.h5 { font-weight: 400; font-size: 17px; line-height: 1; letter-spacing: 0.1em; text-transform: uppercase; color: var(--chalk); }
.h6 { font-weight: 400; font-size: 16px; line-height: 1; letter-spacing: 0.3em; text-transform: uppercase; color: var(--chalk); }
.eyebrow { font-weight: 400; font-size: 14px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--grey-mid); }
.body-copy { color: var(--grey-light); }
.body-copy p + p { margin-top: 1.5em; }
.muted { color: var(--grey-mid); }

.serif { font-family: var(--font-serif); font-weight: 400; }

/* inline links — one style for every link inside prose, site-wide (Hannah, 2026-08-18: it
   lives here so it stays consistent across the entire site and changes in one place).
   A hairline underline in the anchor grey, ink on hover; the text keeps its own colour.
   Nav, buttons, cards, and the wordmark's three doors keep their own treatments. */
p a, li a, .body-copy a { color: inherit; text-decoration: underline; text-decoration-color: var(--grey-anchor); text-underline-offset: 3px; text-decoration-thickness: 1px; transition: text-decoration-color .2s ease; }
p a:hover, li a:hover, .body-copy a:hover { text-decoration-color: var(--chalk); }
.wordmark-sub a { text-decoration: none; }

/* ---------- layout ---------- */
.container { width: min(var(--content-w), calc(100% - 2 * var(--gutter))); margin-inline: auto; }
.section { padding-block: var(--section-pad); }
.section--flush-top { padding-top: 0; }
/* adjacent sections share one 120px gap instead of stacking two paddings */
.section + .section { padding-top: 0; }

.two-col { display: grid; grid-template-columns: 564px 1fr; gap: var(--col-gap); align-items: start; }
.two-col--text-first { grid-template-columns: 1fr 564px; }
.two-col > .col-media img { width: 100%; height: 407px; object-fit: cover; }
.two-col > .col-media--tall img { height: 100%; min-height: 500px; }
/* media column that matches the text column's height exactly (desktop only —
   the absolute fill has no intrinsic height, so single-column mobile keeps
   the base image sizing) */
@media (min-width: 961px) {
  .two-col > .col-media--stretch { align-self: stretch; position: relative; }
  .two-col > .col-media--stretch img { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; object-fit: cover; }
}

.stack-96 { display: flex; flex-direction: column; gap: 96px; align-items: flex-start; }
.stack-48 { display: flex; flex-direction: column; gap: 48px; align-items: flex-start; }
.stack-24 { display: flex; flex-direction: column; gap: 24px; align-items: flex-start; }

.rule { border: 0; border-top: 1px solid var(--grey-anchor); width: 100%; }

/* anchored jumps land clear of the sticky header, with air above the target */
[id] { scroll-margin-top: 96px; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 16px 24px; border: 1.5px solid var(--chalk); border-radius: 4px;
  font-family: var(--font-sans); font-weight: 400; font-size: 17px;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey-light);
  background: transparent; cursor: pointer;
  transition: background-color .5s ease, color .5s ease;
}
.btn:hover { background: var(--chalk); color: var(--bg); }
.btn--dark { border-color: var(--bg); color: var(--bg); }
.btn--dark:hover { background: var(--bg); color: var(--chalk); }

/* ---------- header / nav ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--bg);
  border-bottom: 1px solid rgba(110, 114, 113, 0.25);
}
.site-header .container { display: flex; align-items: center; justify-content: space-between; height: 51px; }
.site-header a {
  font-weight: 300; font-size: 17px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--grey-anchor); padding: 14px 20px; transition: color .2s ease;
}
.site-header a:hover, .site-header a[aria-current="page"] { color: var(--chalk); }
.nav-toggle { display: none; }


/* ---------- the wordmark — Home, once ----------
   Not a page heading: the institution's name at the front door. Built from
   the 2026-08-12 Figma masthead (node 1099:3730). MAGDALENA is sized to hold
   the design's ratio at every width — 142.222px against a 1151px content
   column — so the lockup occupies the same share of the measure on a phone
   as on a desktop. LADY rides at 0.75 of it and tucks up into it. */
.wordmark {
  /* Sized from the WIDTH it must occupy, not from the Figma's font-size. The
     design has MAGDALENA spanning 848.889 of a 1151 measure — 73.75% — and
     how much width a word takes depends on the face. Canela is not licensed
     yet and the stand-in is far narrower, so copying the Figma's 142.22px
     renders at 52% of the measure instead of 74%, and the logo reads small.
     --wm-word is the word's width in ems in the CURRENT face; remeasure that
     one number when Canela lands and the lockup snaps back on its own. */
  font-family: var(--font-serif); font-weight: 400; color: var(--chalk);
  text-transform: uppercase;
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
.wordmark .wm-1 {
  display: block; font-size: calc(var(--wm) * 0.75); line-height: 0.875;
  letter-spacing: 0.1em; text-indent: 0.1em;   /* re-centres against the tracking */
}
.wordmark .wm-2 {
  display: block; font-size: var(--wm); line-height: 1.031;
  letter-spacing: -0.02em; margin-top: -0.08em;
}

/* page masthead — ONE component, every interior page.
   Eyebrow / title / subtitle / rule. Pages carry no masthead styles of their
   own: the four container patterns, four eyebrow classes and drifting subtitle
   weights this replaced are the reason it lives here (Hannah, 2026-08-12). */
.masthead { padding: 96px 0 120px; text-align: center; display: flex; flex-direction: column; gap: 24px; align-items: center; }
/* The masthead owns the whole separation below itself. Two paddings meeting
   sum to a number nobody chose — 64 + 72 was reading as 136 — so whatever
   follows contributes none, the same way adjacent sections already share one.
   The display masthead is excluded: it sets its own padding and keeps the
   following section's. */
.masthead + .section,
.masthead + .in-dev { padding-top: 0; }
/* Same stacking at the foot of the page: the last section's bottom padding met
   the footer's top padding and summed to 216. The footer owns that separation
   at 120 (Hannah, 2026-08-12). */
main > .section:last-child { padding-bottom: 0; }
/* one curve at every width — 48 floor, 64 cap (Hannah, 2026-08-13: the old
   5vw curve bottomed the tablet and phone titles out at 40 and read
   undersized; the title carries its weight on every surface now) */
.masthead .serif { font-size: clamp(48px, 6.9vw, 64px); letter-spacing: 0.06em; text-transform: uppercase; }
.masthead .eyebrow { font-size: 16px; }
/* H3 per Hannah's Figma text style (2026-08-20): Haas Grot Disp R Trial
   55 Roman · 28 · line-height Auto · letter spacing 15% — carried by the
   --font-sans stand-in until Neue Haas loads. 55 Roman is a book-weight
   roman: the stand-in carries it at 400 (Helvetica Neue Regular) — 500 pulled
   Helvetica's Medium and read thicker than the Figma (Hannah, 2026-08-20).
   Re-map to the 55 Roman cut when the real face lands. */
.masthead-sub {
  font-weight: 400; font-size: 28px; line-height: normal;
  letter-spacing: 0.15em; text-transform: uppercase; color: var(--grey-mid);
}
.masthead .rule { margin-top: 96px; }

/* The wordmark's frame — Home, once. Its own component, sharing no selector
   with .masthead: a size modifier on the page heading is an open invitation,
   a job name makes a second use read as an error (Component Standard).
   120 above, 48 down to the subtitle, 120 to the rule. Unlike the masthead
   it owns no separation below itself — the next section pays its own way. */
.wordmark-frame {
  /* the lockup's sizing vars live on the frame so the subtitle can reference
     the same width the wordmark occupies */
  --wm-word: 6.26;   /* MAGDALENA, uppercase, in the stand-in face */
  --wm-share: 0.7375;
  --wm-measure: min(1152px, calc(100vw - 48px));
  --wm: calc(var(--wm-share) * var(--wm-measure) / var(--wm-word));
  padding: 120px 0 0; text-align: center; display: flex; flex-direction: column; gap: 48px; align-items: center;
}
.wordmark-sub {
  font-weight: 400; font-size: clamp(18px, 1.95vw, 28px); line-height: normal;
  letter-spacing: 0.15em; text-transform: uppercase; color: var(--grey-mid);
  display: flex; gap: 48px;   /* three words, no middots — the 2026-08-13 Figma */
}
/* the SEPARATION under the triad is 120 (Hannah, 2026-08-13): the frame's 48
   gap plus this margin. It measured 168 as a stacked sum before — two numbers
   meeting is not a decision. */
.wordmark-frame .rule { margin-top: 72px; }

/* ---------- forms ---------- */
.form { display: flex; flex-direction: column; gap: 24px; }
.form-field { display: flex; flex-direction: column; gap: 8px; }
.form-field > label { font-weight: 400; font-size: 14px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--chalk); }
.form-field .hint { font-size: 14px; color: var(--grey-mid); letter-spacing: 0.02em; }
.field {
  width: 100%; padding: 16px 20px;
  background: transparent; border: 1px solid var(--grey-anchor); border-radius: 4px;
  color: var(--chalk); font-family: var(--font-sans); font-weight: 300; font-size: 17px; letter-spacing: 0.02em;
}
.field::placeholder { color: var(--grey-anchor); }
.field:focus { outline: none; border-color: var(--grey-light); }
textarea.field { min-height: 140px; resize: vertical; }
.field-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.choice-row { display: flex; flex-wrap: wrap; gap: 12px 28px; }
.choice { display: flex; align-items: center; gap: 10px; color: var(--grey-light); font-size: 17px; cursor: pointer; }
.choice input { width: 18px; height: 18px; accent-color: var(--chalk); }
.checklist { display: flex; flex-direction: column; gap: 12px; }

/* honeypot */
.hp { position: absolute; left: -9999px; opacity: 0; pointer-events: none; }

/* ---------- footer ---------- */
.site-footer { padding: 120px 0 96px; display: flex; flex-direction: column; gap: 96px; }
.newsletter { display: flex; flex-direction: column; gap: 48px; align-items: center; }
.newsletter-head { text-align: center; display: flex; flex-direction: column; gap: 24px; align-items: center; }
.newsletter-form { display: flex; gap: 24px; width: 100%; }
.newsletter-form .field { flex: 1; }
.footer-bottom { display: flex; flex-direction: column; gap: 48px; }
.footer-row { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.footer-row p, .footer-row a { font-weight: 300; font-size: 17px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey-mid); }
.social { display: flex; gap: 24px; align-items: center; }
.social img { width: 31px; height: 31px; }

/* ---------- cal embed ---------- */
.cal-embed { width: 100%; min-height: 640px; }

/* ---------- reference layer (the definition pages) ----------
   /field/ and its three domains. One format, four pages: masthead, axiom,
   a plate column beside a prose column, and a placement that runs centred.
   Plate column 564 + prose column 492 + 96 gutter = the 1152 grid. */

.axiom { display: flex; flex-direction: column; gap: 24px; align-items: center; text-align: center; }
.axiom p { max-width: 760px; font-weight: 400; font-size: 24px; line-height: 1.35; letter-spacing: 0.1em; color: var(--grey-light); }
/* An axiom that has dropped its label is the section, so it is set in caps.
   Keyed to being the only child rather than a modifier class: the label's
   absence is the condition, so markup and treatment cannot drift apart. */
.axiom > p:only-child { text-transform: uppercase; }

/* 492 plates : 564 prose — inverted from the Figma's 564/492 on Hannah's
   ruling, Paris confirming (2026-08-13): the prose is the subject and the
   plates are evidence, so the argument owns the wider track. fr units hold
   the ratio while the container narrows, so nothing overflows between the
   961px breakpoint and the 1152px grid. */
.ref-cols { display: grid; grid-template-columns: 492fr 564fr; gap: var(--col-gap); align-items: start; }
.ref-plates, .ref-prose { display: flex; flex-direction: column; gap: 96px; min-width: 0; }

/* a plate is a figure: line-work above, caption below, never interpreted */
.plate { display: flex; flex-direction: column; gap: 24px; align-items: center; width: 100%; }
.plate > img { width: 100%; height: auto; }
/* 12px at every width — Hannah set 12 in Figma and ruled it site-wide after
   the phone pass tried 13 and 11 (2026-08-13) */
/* (2026-08-18: the 300 max-measure below was retired for the 24 gutter — kept as record)
/* 300 max-measure: ~40 characters at 12px — a plate label, not a footnote.
   One number at every width; the phone column never reaches it (Paris, from
   Hannah's 300–350 range, 2026-08-13) */
/* the caption — one font for every caption on the site (Hannah, 2026-08-18): 12px at every
   width, ruled site-wide 2026-08-13; lives here so it changes in one place */
figcaption { font-weight: 300; font-size: 12px; line-height: normal; letter-spacing: 0.02em; text-align: center; color: var(--chalk); } /* Haas 45 Light 12 / 2% / auto, centred — Hannah, 2026-08-18: "perfect"; the one caption font, site-wide */
/* every caption sits 24 in from either edge of its image — one gutter, site-wide (Hannah,
   2026-08-18; the field plates' 300 max-measure retired for it) */
.plate figcaption { width: calc(100% - 48px); }
.plate--wide { width: 100%; }

/* Figma crop window. The frame crops each fill to a box of its own ratio and
   offsets the image inside it; `.fig` is that box, and the inline percentages on
   the image are the frame's own transform, so the crop holds at any width.
   Serve the FULL source image — the percentages assume an uncropped fill. */
.fig { position: relative; overflow: hidden; width: 100%; }
.fig > img { position: absolute; display: block; max-width: none; }
.fig--cover > img { inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* A plate whose source ground sits darker than the page reads as a patch cut
   into it. `lighten` floors the source to the page ground — max(--bg, pixel) —
   so the plate's field and the page become one surface. Nothing lighter than
   the ground is touched, and the JPEG is never re-encoded. Dark pages only. */
.fig--ground { background: var(--bg); isolation: isolate; }
.fig--ground > img { mix-blend-mode: lighten; }

/* fascia's two Deep Front Line crops: separate windows into one source,
   set side by side at the frame's own 297 : 267 split */
.fig-pair { display: grid; grid-template-columns: 297fr 267fr; align-items: start; width: 100%; }

/* a prose block: section label, section title, then the body */
.ref-block { display: flex; flex-direction: column; gap: 48px; }
.ref-head { display: flex; flex-direction: column; gap: 24px; }
/* the section labels (THE DEFINITION / THE FUNCTION / THE PLACEMENT) run
   45 Light, not 55 Roman — Hannah's Figma, 2026-08-13 */
.ref-block .h5 { font-weight: 300; }
.ref-sub { display: flex; flex-direction: column; gap: 24px; }

/* ---------- definition pages — sub-nav + back/forward (Hannah's Figma, nodes
   1216:2932 + 1120:3874, moved to main.css 2026-08-20) ----------
   The bar sits flush under the masthead rule, sticky at top 0 above the site
   header (z 101 over its 100) so it replaces the top nav on scroll. Both
   hairlines around it run 25% (Hannah, 2026-08-20). The bar's rule spans the
   1152 row, not the viewport. */
.masthead:has(+ .def-subnav) { padding-bottom: 0; }
.masthead:has(+ .def-subnav) .rule { border-top-color: rgba(110, 114, 113, 0.25); }
.def-subnav { position: sticky; top: 0; z-index: 101; background: var(--bg); }
.def-subnav .def-subnav-row {
  display: flex; align-items: center; justify-content: space-between; height: 51px;
  border-bottom: 1px solid rgba(110, 114, 113, 0.25);
}
.def-subnav a {
  font-weight: 300; font-size: 17px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--grey-anchor); padding: 14px 20px; transition: color .2s ease;
}
.def-subnav a:hover { color: var(--chalk); }
.def-subnav a[aria-current="page"] { color: var(--grey-light); }
/* the bottom back/forward pair — circular through the layer */
.defs-nav-pair { display: flex; align-items: center; justify-content: center; gap: 120px; margin-top: 96px; }
.defs-nav-pair a {
  font-weight: 300; font-size: 17px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--grey-anchor); padding: 14px 20px; transition: color .2s ease;
}
.defs-nav-pair a:hover { color: var(--chalk); }

/* the placement runs centred and full width on the three domain pages */
.ref-center { max-width: 760px; margin-inline: auto; display: flex; flex-direction: column; gap: 24px; align-items: center; text-align: center; }
.ref-center .ref-block { gap: 48px; align-items: center; }
.ref-center .ref-head { align-items: center; }

/* astrology's two reference tables */
/* zodiac carries seven columns to the planets' five, so it takes the wider half */
.astro-tables { display: grid; grid-template-columns: 1.14fr 1fr; gap: 48px; align-items: start; }
.astro-tables > div { display: flex; flex-direction: column; gap: 48px; align-items: center; min-width: 0; }
.table-scroll { width: 100%; overflow-x: auto; }
.astro-table { width: 100%; border-collapse: collapse; border: 1.5px solid var(--grey-mid); }
.astro-table th, .astro-table td {
  border: 1px solid rgba(214, 216, 212, 0.45); padding: 8px 7px;
  color: var(--grey-light); font-size: 13px; line-height: 1.45; font-weight: 300;
}
.astro-table th { font-size: 10px; font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; text-align: center; }
.astro-table td { text-align: center; }
/* glyphs must resolve from a text font, never the colour emoji face */
.astro-table td.glyph { font-size: 20px; font-family: "Apple Symbols", "Segoe UI Symbol", "Noto Sans Symbols 2", var(--font-sans); }
.astro-table td.term { text-align: left; }

/* ---------- essays list — the contents page (/essays/) ----------
   From the "essay" row component in the magdalena.ca 2.0 Figma (156:516,
   read off the node 2026-08-18). One row per essay: a 564 text column and a
   296 plate, 96 apart, centred — 956 wide, 98 inside each 1152 rule (Hannah's
   "row 1", ruled 2026-08-18). The whole row is the link. */

.essay-list:empty { display: none; }
/* The masthead's 120 below its rule yields to the row's own 96 — the essay
   frame runs rule → 96 → title, and two paddings meeting would sum to 216. */
.masthead ~ .essay-list { margin-top: -120px; }

.essay-row {
  display: block; position: relative; padding: 96px 0; color: inherit; text-decoration: none; /* 96/96 off the node (Hannah, 2026-08-18: back to 96) */
}
/* the divider: 1px, 1152, on the row's bottom edge; the last row leans on the
   footer's rule instead of doubling it */
.essay-row::after {
  content: ""; position: absolute; left: 50%; bottom: -0.5px; transform: translateX(-50%);
  width: min(var(--content-w), calc(100% - 2 * var(--gutter))); height: 1px; background: var(--grey-anchor);
}
.essay-row:last-child::after { display: none; }
/* a consistent 96 above the footer's rule at this iteration (Hannah, 2026-08-18): the last
   row keeps its 96 and the footer contributes none on this page — one separation, one owner */
.essays-index .site-footer { padding-top: 0; }
.essay-row__inner {
  display: flex; gap: var(--col-gap); align-items: center; justify-content: center;
  width: min(956px, calc(100% - 2 * var(--gutter))); margin: 0 auto;
}
/* title → 24 → DATE → 48 → the line; the block top-aligns to the plate (Hannah, 2026-08-18:
   48 under DATE, from the essay component's light variant) */
.essay-row__text { width: 564px; min-height: 296px; display: flex; flex-direction: column; gap: 48px; min-width: 0; }
/* title → DATE: the frame carries 16, which is off the 24/48/96/120 scale — a separation,
   not a control's padding, so it normalises to 24 (Component Standard; Hannah, 2026-08-18) */
.essay-row__head { display: flex; flex-direction: column; gap: 24px; }
/* two lines, no more — the boundary every essay title keeps (Hannah, 2026-08-18);
   /publish-essay holds the character ceiling, this clamp is the safety net */
.essay-row__title { font-size: 48px; line-height: normal; letter-spacing: -0.02em; color: var(--chalk); transition: color .2s ease;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.essay-row:hover .essay-row__title { color: var(--grey-mid); }
.essay-row__date { font-weight: 300; font-size: 17px; line-height: normal; letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey-mid); }
/* three lines, no more (Hannah, 2026-08-18) — /publish-essay holds the ceiling, this is the net */
.essay-row__excerpt { font-weight: 300; font-size: 17px; line-height: 1.5; letter-spacing: 0.02em; color: var(--chalk);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.essay-row__plate { flex: 0 0 296px; width: 296px; height: 296px; border-radius: 4px; overflow: hidden; }
.essay-row__plate img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ---------- essay page — the standard layout every published essay wears ----------
   From the "essay contents" component in the magdalena.ca 2.0 Figma (1145:2947 in
   frame 559:627, read off the node 2026-08-18). Its own component, sharing no selector
   with the site masthead. Centred head (back → 48 → title → 48 → byline), 48 → rule,
   96 → body: 296 plate · 96 · 564 text = 958, the rule's width. Every separation on
   the 24 / 48 / 96 / 120 scale. */

.essay { padding: 96px 0 120px; }
.essay__inner { width: min(958px, calc(100% - 2 * var(--gutter))); margin: 0 auto; display: flex; flex-direction: column; gap: 96px; }
.essay__head { display: flex; flex-direction: column; align-items: center; gap: 48px; text-align: center; }
.essay__back { font-weight: 300; font-size: 12px; line-height: normal; letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey-anchor); transition: color .2s ease; }
.essay__back:hover { color: var(--chalk); }
/* CAPS on the essay page, title case on the list — one title, two surfaces (Hannah, 2026-08-18) */
.essay__title { max-width: 760px; font-size: 48px; line-height: normal; letter-spacing: -0.02em; color: var(--chalk); text-transform: uppercase; }
.essay__byline { display: flex; align-items: center; gap: 24px; }
.essay__byline p { font-weight: 300; font-size: 17px; line-height: normal; letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey-mid); }
.essay__byline img { width: 93px; height: 93px; border-radius: 50%; display: block; }
/* the head owns 96 to the rule (Hannah, 2026-08-18: 96 from the byline); the rule is the 958
   line, not the 1152 site rule. Reaffirmed 2026-08-20 (Hannah + Paris, after a 1152 trial):
   the rule is the essay's margin, not the site's floor — the room declares its proportions
   at the door, and the 958 line shares its edges with everything below it. */
.essay__head + .rule { margin-top: 0; }
/* the essay owns the 120 below its text (off the node); the footer contributes none on an
   essay page — 120 + 120 was reading as 240 (Hannah, 2026-08-18) */
.essay-page .site-footer { padding-top: 0; }
.essay__body { display: grid; grid-template-columns: 296px 564px; gap: var(--col-gap); align-items: start; justify-content: center; }
/* the left track: the main plate first, further plates stacked under it in folder order,
   48 apart (Hannah, 2026-08-18; the gap is hers to re-set from Figma) */
.essay__plates { width: 296px; display: flex; flex-direction: column; gap: 48px; }
.essay__plate { width: 296px; min-width: 0; display: flex; flex-direction: column; gap: 24px; align-items: center; margin: 0; }
.essay__plate img { display: block; width: 100%; height: auto; border-radius: 4px; }
/* the caption sits 24 in from either edge of the plate, so it never spans the image's full width */
.essay__plate figcaption { width: calc(100% - 48px); }
.essay__text { display: flex; flex-direction: column; gap: 24px; min-width: 0; font-weight: 300; font-size: 17px; line-height: 1.5; letter-spacing: 0.02em; color: var(--chalk); }
.essay__text .standfirst { font-weight: 400; }
/* section head — a sober default in the site's h-scale (Haas 55 Roman 24 / 10% caps, 48 above,
   24 below); Hannah sets the look in Figma when she is in there (2026-08-18) */
.essay__text .essay__h { font-weight: 400; font-size: 24px; line-height: 1; letter-spacing: 0.1em; text-transform: uppercase; color: var(--chalk); margin-top: 24px; }
/* body enumeration — rides the essay__text 24 rhythm; indent is the site gutter */
.essay__text .essay__list { margin: 0; padding-left: 24px; }

/* ---------- definitions nav — the doors between the reference pages ----------
   All three widths (Hannah, 2026-08-13): stacked on the phone, paired from
   the iPad tier up. Interior register one step below the page — a footnote-
   door, not a second masthead; chalk stays reserved for the room you are in.
   A door has four edges: rules-only was built, looked at, and refused. */
.defs-nav { display: grid; grid-template-columns: 1fr; gap: 24px; width: 100%; margin: 96px auto 0; }
.def-nav-card {
  border: 1px solid rgba(110, 114, 113, 0.5); border-radius: 4px; padding: 32px 24px;
  display: flex; flex-direction: column; gap: 16px; align-items: center;
  justify-content: center; text-align: center;
  transition: border-color .5s ease;
}
.def-nav-card:hover { border-color: var(--grey-anchor); }
.def-nav-card .def-nav-title { transition: color .5s ease; }
.def-nav-card:hover .def-nav-title { color: var(--chalk); }
/* four rows (Hannah: the arrows and the bookings loop are hers) */
.def-nav-eyebrow { font-weight: 400; font-size: 10px; line-height: 1; letter-spacing: 0.2em; text-transform: uppercase; color: var(--grey-anchor); }
.def-nav-room { font-weight: 400; font-size: 11px; line-height: 1; letter-spacing: 0.3em; text-transform: uppercase; color: var(--grey-anchor); }
.def-nav-title { font-weight: 400; font-size: 16px; line-height: 1.3; letter-spacing: 0.2em; text-transform: uppercase; color: var(--grey-mid); padding-inline: 24px; }
.def-nav-arrow { font-weight: 300; font-size: 14px; line-height: 1; color: var(--grey-mid); }
@media (min-width: 701px) {
  .defs-nav { grid-template-columns: 1fr 1fr; }
  .def-nav-title { white-space: nowrap; }
}
@media (min-width: 961px) {
  .defs-nav { margin-top: 120px; }
}

/* ---------- home — the field ---------- */
/* The field block sits over the sol figure at 10%; the band photo rides on top */
/* eyebrow-to-name 24 (the card-names group), name-to-sentence 48 (Hannah, 2026-08-20) */
.field-lede { display: flex; flex-direction: column; gap: 48px; align-items: center; text-align: center; max-width: 760px; margin-inline: auto; }
.field-lede .stack-24 { align-items: center; }
/* Inset since the 2026-08-20 Figma (node 1205:3440): the band sits in the
   1152 content column, centered — the page ground shows at the sides as the
   band's border. Supersedes the 2026-08-13 full-bleed. */
.field-band { position: relative; width: min(var(--content-w), calc(100% - 2 * var(--gutter))); margin-inline: auto; }
/* The sol paints OVER the photo at 10%, same box as the band. */
.field-band .band-sol {
  position: absolute; inset: 0; z-index: 1;
  overflow: hidden; opacity: 0.1; pointer-events: none;
}
.field-band .band-sol > img { position: absolute; display: block; max-width: none; }

/* The band crops are percentages of the band's own box, so they hold at any
   WIDTH provided the box keeps its 1152:436 SHAPE — 1152x1727 resolves to the
   photo's own 0.667, 1322x1322 to the sol's 1.000. A fixed height at the
   narrow tier broke the shape and stretched the face 2.16x vertically; the
   aspect-ratio now governs at every width and the eyes/nose crop is the same
   framing on a phone as on the desktop, just smaller. */
/* 2026-08-20, second pass: the band narrowed to 1152x418 (node 1205:3440);
   the sol is a plain cover fill now, no offset crop. */
.field-band .band-photo > img { left: -0.04%; top: -122.99%; width: 100%; height: 413.27%; }
.field-band .band-sol > img   { inset: 0; width: 100%; height: 100%; object-fit: cover; }
.field-band .band-photo { position: relative; aspect-ratio: 1152/418; }
/* the field section follows the band at 96, not the section default */
.home-field { padding-top: 96px; }

.field-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--col-gap); align-items: start; }
.field-card { display: flex; flex-direction: column; gap: 48px; align-items: center; text-align: center; }
.field-card .card-head { display: flex; flex-direction: column; gap: 24px; align-items: center; }
.field-card .card-names,
.field-lede .card-names { display: flex; flex-direction: column; gap: 24px; align-items: center; }
/* the card's figure fills the 320 card — the second start-here variant, chosen
   on the Figma home page (Hannah, 2026-08-20). Size the crop window, never
   the image, or max-width clamps the fill and the crop scale collapses */
.field-card .fig { width: 100%; }
/* the card's eyebrow runs a step quieter than its title (2026-08-13 Figma) */
.field-card .h6 { color: var(--grey-light); }
/* a closing rule takes the smaller gap above and the next rung up below,
   so it attaches to the block it closes rather than the one it precedes
   (Paris, 2026-08-12) */
.home-field > .container > .rule { margin-top: 96px; }

/* ---------- helpers ---------- */
.center { text-align: center; align-items: center; }
.in-dev { padding: 120px 0; text-align: center; display: flex; flex-direction: column; gap: 24px; align-items: center; justify-content: center; }
.in-dev[hidden] { display: none; } /* the essays list hides it once essays.json has entries */
.in-dev-label { font-weight: 400; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey-mid); }

/* ---------- light pages ---------- */
/* The Library pages (About, Courses, Essays, Alyta) run light per the Figma;
   the Temple pages (Home, the work-with-me doors) stay dark. The grey ramp
   inverts: ink where chalk was, faint grey where anchor was. */
body.light {
  --bg: #f4f4f2;
  --chalk: #0f0f0f;
  --grey-light: #3f4241;
  --grey-mid: #6e7271;
  --grey-anchor: #9ea1a0;
}
body.light .social img { filter: invert(1); }

/* ---------- responsive ---------- */
.nav-check { display: none; }
@media (max-width: 960px) {
  :root { --section-pad: 96px; --col-gap: 48px; }
  .two-col, .two-col--text-first { grid-template-columns: 1fr; }
  .two-col > .col-media { order: -1; }
  .newsletter-form { flex-direction: column; }
  .field-row { grid-template-columns: 1fr; }
  .essay-row { padding: var(--section-pad) 0; }
  .essay-row__inner { flex-direction: column; align-items: stretch; width: calc(100% - 2 * var(--gutter)); }
  .essay-row__plate { order: -1; width: 100%; height: auto; aspect-ratio: 1; flex-basis: auto; }
  .essay-row__text { width: 100%; height: auto; }
  .essay-row__title { font-size: clamp(32px, 4vw, 48px); }
  .essay { padding: var(--section-pad) 0; }
  .essay__body { grid-template-columns: 1fr; }
  .essay__plates, .essay__plate { width: min(296px, 100%); }
  .essay__title { font-size: clamp(32px, 4vw, 48px); }
  .footer-row { flex-direction: column; text-align: center; }

  /* iPad keeps the full nav bar (Hannah, 2026-08-20) — the hamburger moved to
     the ≤700 phone tier. Six links overflow this width at the desktop 17px,
     so the tier tightens them to the 15px the menu items already use. */
  .site-header a { font-size: 15px; padding: 14px 12px; }


  /* reference layer: one column — every plate falls under the prose it serves,
     so the page reads as definition→figure rather than two parallel columns.
     The two wrappers drop to `contents` so their children become the grid's own
     items, and the six `order` values interleave them into prose→plate pairs.
     Rests on the 1:1 pairing the template guarantees (3:3 on /field/, 2:2 on the
     three domain pages) — an uneven page would strand its extra child at the end. */
  /* `.h6` is line-height 1, which is right for a one-line label and too tight
     the moment one wraps — "Example: The Deep Front Line" puts LINE on its own
     row hard against the row above. A little lead, below desktop only; the
     close-set look is kept at every width where the label fits on one line
     (Hannah, 2026-08-13). */
  .h6 { line-height: 1.15; }
  .masthead-sub { font-size: 20px; }
  .wordmark-frame { padding-top: 96px; }
  .wordmark-frame .rule { margin-top: 48px; }
  .axiom p { font-size: 20px; }
  .ref-cols { grid-template-columns: 1fr; gap: 48px; }
  .ref-plates, .ref-prose { display: contents; }
  .ref-plates > *, .ref-prose > * { min-width: 0; }
  .ref-prose  > :nth-child(1) { order: 1; }
  .ref-plates > :nth-child(1) { order: 2; }
  .ref-prose  > :nth-child(2) { order: 3; }
  .ref-plates > :nth-child(2) { order: 4; }
  .ref-prose  > :nth-child(3) { order: 5; }
  .ref-plates > :nth-child(3) { order: 6; }
  /* 48 inside a pair, 96 between pairs (Paris, 2026-08-12). At two columns a
     plate sits beside its claim and belonging is a fact of the geometry; at one
     column the geometry is gone and proximity is the only cue left, so an even
     interval leaves every figure equidistant between the claim it proves and
     the one it does not. 48 is licensed here and nowhere else on the layer —
     the full-width plate keeps 96 on both sides, because it serves the page
     rather than a paragraph and one interval must not mean two things.
     Expressed as 48 added ABOVE each prose block after the first, not below
     each plate: the plate-side version assumed equal counts and silently gave
     the wrong gap on a page whose plates and prose do not pair 1:1. */
  .ref-prose > *:not(:first-child) { margin-top: 48px; }
  /* The Placement runs centred on desktop, where it closes a wide page. At one
     column it is a block of body copy like any other and reads left. */
  .ref-center { text-align: left; align-items: stretch; }
  .ref-center .ref-block,
  .ref-center .ref-head { align-items: stretch; }
  /* The three doors stay a row, not a stack (Hannah, 2026-08-12): three
     choices read as a choice; stacked they read as a list you scroll past.
     At 342px that is ~98px a card, so the type comes down to fit — the only
     place on the site where the narrow tier touches type above the body
     scale, and it is a deliberate exception to "display type does not step
     down", because here the card IS the control. */
  /* minmax(0,1fr), not 1fr: the card's figure is a fixed 256px, which is a
     min-content floor that holds the tracks open and overflows the page. */
  .field-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .field-card .fig { width: 100%; }
  /* Peer parity: the cells of a choice set are peers by definition, so a card
     riding high because its copy runs a line shorter says one door outranks
     the others — the one thing the row exists to deny. Subgrid aligns the
     name, figure and button rows across all three (Paris, 2026-08-12).
     Not solved with copy: alignment that depends on where text wraps holds
     at 390px and nowhere else. */
  .field-cards { grid-template-rows: repeat(2, auto); }
  .field-card { display: grid; grid-template-rows: subgrid; grid-row: span 2; }
  .field-card { gap: 24px; }
  .field-card .card-head { gap: 24px; }
  .field-card .card-names { gap: 12px; }
  .field-card .h6 { font-size: 9px; letter-spacing: 0.12em; }
  .field-card .h5 { font-size: 12px; letter-spacing: 0.04em; }
  .field-card .body-copy { font-size: 11px; line-height: 1.45; }
  /* 48 above / 96 below: glued upward to the field block it closes. At 96
     above it read as a line drawn on top of the photograph beneath it.
     Removing it entirely was built and looked at 2026-08-12 and rejected —
     Paris's ruling stands, the line is the one mark that says the reference
     layer closes here. */
  /* the subtitle row narrows with its type */
  .wordmark-sub { gap: 24px; }
  /* the wordmark takes nearly the whole measure on a phone — at the desktop's
     73.75% it reads as a heading rather than the front door */
  .wordmark-frame { --wm-share: 0.95; }
  /* On these two the prose and its door are one unit at this width; 96 reads
     as a section break inside a section (Hannah, 2026-08-12). */
  .home-study .stack-96, .home-story .stack-96 { gap: 48px; }
  /* stacked, the two tables are separate references rather than columns
     of one, so they take the between-things gap, not the within-one gap */
  .astro-tables { grid-template-columns: 1fr; gap: 96px; }
  .astro-table th, .astro-table td { padding: 8px 10px; font-size: 13px; }
}

/* The closing rule glues upward only where the page is one column: 48 above
   at stacked widths, the full 96 from the iPad tier up (Hannah, 2026-08-13 —
   "the space beneath the diagrams needs to be taller"). */
@media (max-width: 700px) {
  .home-field > .container > .rule { margin-top: 48px; }

  /* mobile nav: a slim bar with a centered three-line toggle; the menu drops
     down on tap. No WORK WITH ME parent on mobile — the three doors are items.
     Phone tier only since 2026-08-20 — iPad carries the full bar. */
  .site-header .container { min-height: 51px; height: auto; flex-wrap: wrap; justify-content: center; }
  .site-header .container > a { display: none; }
  .nav-toggle { display: flex; flex-direction: column; gap: 5px; padding: 18px 24px; cursor: pointer; }
  .nav-toggle span { display: block; width: 22px; height: 1.5px; background: var(--chalk); }
  .nav-check:checked ~ a { display: block; width: 100%; text-align: center; padding: 11px 12px; font-size: 15px; }
}

/* ---------- phone tier — ≤600 per the Responsive Standard ----------
   Holds only the touch floor. The tier's vertical compressions (48 section
   padding, the rule flip, 280 crops) were built 2026-08-13, looked at, and
   sent back — Hannah's word. */
@media (max-width: 600px) {
  /* The 44px touch floor, reached with padding, never type. The negative
     margins hand back exactly what the padding took, so the visible rhythm
     does not move — only the tap zone grows. */
  a.h6 { display: inline-flex; align-items: center; min-height: 44px; margin-block: -14px; }
  .footer-row a { display: inline-block; padding-block: 13.5px; margin-block: -13.5px; }
  .social a { display: inline-flex; padding: 6.5px; margin: -6.5px; }
  /* the triad never runs wider than the lockup (Hannah, 2026-08-13): on a
     phone it spans exactly MAGDALENA's own width, the dots distributing */
  .wordmark-sub { width: calc(var(--wm-share) * var(--wm-measure)); justify-content: space-between; gap: 0; }
  /* The band opens up on a phone — the first screen is the logo, the three
     words, and the gaze (Hannah, 2026-08-13). The desktop strip's percentage
     crop would distort at a taller box, so the phone recrops: cover, eyes
     centred, the sol riding the same window. */
  /* The phone band stays full-bleed per Hannah's 2026-08-13 phone framing;
     the 2026-08-20 desktop inset does not reach this tier. */
  .field-band { width: 100%; }
  .field-band .band-photo { aspect-ratio: 29/20; }
  .field-band .band-sol > img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; max-width: none;
  }
  /* The window, cut to the frame Hannah marked (2026-08-13): nails at the
     top edge, eyes on the upper-third line, lips in, chin and the wrist
     tattoo out. Proportional — the source's own aspect holds. */
  .field-band .band-photo > img {
    width: 115.6%; height: 251.3%; left: -8.1%; top: -62.1%;
  }
  /* the research image runs shorter on a phone (Hannah, 2026-08-13) */
  .home-study .col-media img { height: 280px; }
}

/* Lightbox (assets/js/lightbox.js) — [data-lightbox] elements open in a
   zoomable full-screen overlay */
[data-lightbox] { cursor: zoom-in; }
.lb-overlay {
  position: fixed; inset: 0; z-index: 200; background: rgba(15, 15, 15, 0.87); overscroll-behavior: contain;
  opacity: 0; visibility: hidden; transition: opacity 0.35s ease, visibility 0s linear 0.35s;
}
.lb-overlay.open { opacity: 1; visibility: visible; transition: opacity 0.35s ease; }
/* light pages keep the lightbox feeling like a layer over the page, not a navigation */
body.light .lb-overlay { background: rgba(244, 244, 242, 0.87); } /* 0.97 → 0.87 — Hannah, 2026-08-18: 10% more transparent */
/* smart-animate: the image box travels from its place on the page (lightbox.js sets the
   start transform); the words fade in behind it */
.lb-frame .lb-title, .lb-frame figcaption { opacity: 0; transition: opacity 0.3s ease 0.2s; }
.lb-frame--in .lb-title, .lb-frame--in figcaption { opacity: 1; }
.lb-stage { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; touch-action: none; }
/* the popup is a figure: title above, image, caption below — the caption in the site's one
   caption font, 24 in from either edge of the image, like every caption (Hannah, 2026-08-18) */
.lb-frame { display: flex; flex-direction: column; align-items: center; gap: 24px; margin: 0; }
.lb-title { font-weight: 400; font-size: 12px; line-height: normal; letter-spacing: 0.02em; text-align: center; color: var(--chalk); }
.lb-frame figcaption { color: var(--chalk); }
.lb-content { position: relative; cursor: zoom-in; transition: transform 0.2s ease-out; will-change: transform; }
.lb-content.zoomed { cursor: grab; }
.lb-content > img { display: block; width: 100%; height: 100%; object-fit: contain; }
.lb-content img { -webkit-user-drag: none; user-select: none; }
.lb-close {
  position: fixed; top: 16px; right: 24px; z-index: 201;
  background: none; border: 0; padding: 8px;
  color: var(--grey-light); font-family: var(--font-sans); font-weight: 300; font-size: 40px; line-height: 1;
  cursor: pointer;
}
.lb-close:hover { color: var(--chalk); }
/* cloned (non-img) lightbox content must fill the content box — its layers are
   absolutely positioned and would otherwise collapse to zero height */
.lb-content > div { width: 100%; height: 100%; aspect-ratio: auto; }

/* ---------- cross-page dissolve ---------- */
/* Native cross-document view transitions: the old page dissolves into the new,
   300ms ease-in-out. Browsers without support (Firefox) get a fade-in on
   arrival; reduced-motion users get instant navigation. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 300ms; animation-timing-function: ease-in-out; }
@supports not (view-transition-name: root) {
  @keyframes page-in { from { opacity: 0; } }
  body { animation: page-in 300ms ease-in-out; }
}
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  body { animation: none; }
}

/* Pluto is set as a drawn mark, not a character. U+2BD3 PLUTO FORM TWO — the
   form Hannah drew in the Figma — exists in no font on the machine or in the
   stack, so a character reference renders an empty box. An inline SVG is the
   glyph itself: exact, colour-inherited, and dependency-free. */
.astro-table td.glyph .gl {
  /* 0.72em, not 1em: the outline's ink fills 95% of its box where the
     surrounding font glyphs average 68% of theirs, so a matched box
     reads half again too big. The -0.12em drops its descender onto the
     same baseline the text glyphs sit on. */
  display: inline-block; height: 0.72em; width: auto; vertical-align: -0.12em;
  fill: currentColor; stroke: none;
}
