/* ==========================================================================
   HOME - THE LINEAGE, THE GUARDIAN, CONTACT
   The page alternates paper and ink: hero (paper) / heritage (ink) /
   lineage (paper) / guardian (ink, between beams) / contact (paper) /
   footer (ink). Paper sections use the hero's paper and texture; ink
   sections reuse home-hall.css (the Guardian carries the .hall class).

   Performance notes: no fixed backgrounds, no mix-blend-mode (the paper
   texture blends inside its own background via background-blend-mode),
   images are right-sized copies from html/Images/opt.
   ========================================================================== */

:root {
  --paper: #e3e3db;
  --paper-hi: oklch(0.965 0.008 88);
  --ink: oklch(0.21 0.018 58);
  --ink-2: oklch(0.21 0.018 58 / 0.8);
  --ink-3: oklch(0.21 0.018 58 / 0.6);
  --ink-line: oklch(0.21 0.018 58 / 0.22);
  --gold-deep: oklch(0.5 0.095 70);
  --gold-soft: oklch(0.75 0.088 80);
  --sec-inline: calc(clamp(16px, 4vw, 64px) + clamp(1.5rem, 3.5vw, 4rem));
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

.lineage,
.visit {
  position: relative;
  color: var(--ink);
  background:
    url("Images/old-wall.png"),
    url("Images/asfalt-dark.png"),
    var(--paper);
  background-blend-mode: multiply, multiply, normal;
}

/* Plum-branch corner ornaments. A transparent cut of the original artwork
   (html/Images/opt/corner-branch.webp), so no blend mode is needed to sit it
   on the paper - the old version used mix-blend-mode over the whole section. */
.corner-branch {
  position: absolute;
  z-index: 0;
  width: clamp(140px, 21vw, 320px);
  height: auto;
  pointer-events: none;
  user-select: none;
}

.corner-branch--tl { top: 0; left: 0; transform: scaleY(-1); }
.corner-branch--tr { top: 0; right: 0; transform: rotate(180deg); }
.corner-branch--bl { bottom: 0; left: 0; }
.corner-branch--br { bottom: 0; right: 0; transform: rotate(180deg) scaleY(-1); }

.lineage-inner,
.visit-inner {
  position: relative;
  z-index: 1;
}

/* Shared small label above a title. */
.sec-eyebrow {
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(0.82rem, 0.3vw + 0.75rem, 0.95rem);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--eyebrow, var(--gold-deep));
  z-index: auto;
}

/* The paper sections' buttons use the shared CTA (home-cta.css). */

/* ==========================================================================
   THE LINEAGE
   ========================================================================== */

/* --lift moves the head down for more air above it; the same amount comes
   back out below (half from the gap under the head, half from the gap above
   the caption row - the bottom padding stays, so the caption keeps clear of
   the corner branch), so the section keeps its height at every width.
   --foot-raise lifts the caption row clear of the bottom branches the same
   way: taken from the gap above it, given back to the bottom padding. */
.lineage-inner {
  --lift: clamp(2rem, 3vw, 3rem);
  --foot-raise: clamp(1.5rem, 2.5vw, 2.5rem);
  max-width: 1560px;
  margin: 0 auto;
  padding:
    calc(clamp(4rem, 7vw, 6rem) + var(--lift))
    var(--sec-inline)
    calc(clamp(4rem, 7vw, 6rem) + var(--foot-raise));
}

/* Head: title left, lead right - the same two columns and gap as contact,
   so the section uses the full width instead of leaving the right half empty. */
.lineage-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(3rem, 7vw, 8rem);
  align-items: start;
}

/* Mid widths: the lead is far longer than the title, so give it more room. */
@media (max-width: 1240px) and (min-width: 961px) {
  .lineage-head {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    column-gap: clamp(2.5rem, 5vw, 4rem);
  }
}

.lineage .lineage-zh {
  margin-top: 0.9rem;
  font-family: "Yuji Boku", "Noto Serif SC", serif;
  font-size: clamp(1.4rem, 1.2vw + 1rem, 2.1rem);
  line-height: 1.1;
  letter-spacing: 0.14em;
  color: var(--gold-deep);
  z-index: auto;
}

.lineage .lineage-title {
  margin-top: 1rem;
  max-width: none;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.9rem, 2.6vw, 3.1rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: 0;
  color: var(--ink);
  text-wrap: balance;
  z-index: auto;
}

.lineage .lineage-lead {
  margin-top: 0;
  padding-left: clamp(1.5rem, 2.5vw, 2.5rem);
  border-left: 1px solid var(--ink-line);
  font-family: var(--font-text);
  font-size: clamp(1.02rem, 0.3vw + 0.93rem, 1.15rem);
  font-weight: 400;
  line-height: 1.8;
  color: var(--ink-2);
  text-wrap: pretty;
  z-index: auto;
}

/* Three masters, in lineage order - each a generation lower than the last.
   --stagger is the drop per generation; the gold thread below relies on it
   being the same step each time (the third master drops 2x). */
.lineage-masters {
  --gap: clamp(1.5rem, 3.5vw, 3.75rem);
  --stagger: clamp(2.5rem, 6vw, 6rem);
  margin: calc(clamp(3.5rem, 6vw, 5.5rem) - var(--lift) / 2) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--gap);
  align-items: start;
}

.master:nth-of-type(2) { margin-top: var(--stagger); }
.master:nth-of-type(3) { margin-top: calc(var(--stagger) * 2); }

/* Photo: clean print, slow push-in on hover. */
.master-photo {
  margin: 0;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: oklch(0.86 0.012 90);
  box-shadow:
    0 2px 4px oklch(0.25 0.02 60 / 0.14),
    0 26px 50px -18px oklch(0.25 0.02 60 / 0.4);
}

.master-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transition: transform 1.2s var(--ease-out), filter 0.8s ease;
}

.master:hover .master-photo img {
  transform: scale(1.04);
  filter: sepia(0.18) contrast(1.04);
}

/* Timeline: a gold diamond marks each generation, then its numeral. On the
   three-column layout the line is one SVG path over the list (.lineage-thread,
   drawn by home-sections.js from the real positions): from each numeral it
   runs to the column's edge, sweeps down one generation in a single S-curve
   and lands on the next diamond; after the last master it fades out - the
   lineage continues. Stacked (760px and under) each step gets a plain rule. */
.lineage-masters {
  position: relative;
  --line: 2px;
  --line-c: oklch(0.5 0.095 70 / 0.85);
}

.master .master-step {
  position: relative;
  margin-top: 1.75rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.35rem, 0.9vw + 0.95rem, 1.75rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--gold-deep);
  z-index: auto;
}

.master .master-step::before {
  content: "";
  flex: none;
  width: 11px;
  height: 11px;
  margin-inline: 2px 0.15rem;
  transform: rotate(45deg);
  background: var(--gold-deep);
  box-shadow:
    0 0 0 3px var(--paper),
    0 0 0 4px oklch(0.5 0.095 70 / 0.45);
}

.master-num {
  flex: none;
}

.lineage-thread {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.lineage-thread path {
  fill: none;
  stroke-width: var(--line);
  stroke-linecap: round;
}

/* The master entries sit above the line. */
.master {
  position: relative;
  z-index: 1;
}

.master .master-name {
  margin-top: 0.75rem;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.15rem, 0.6vw + 0.95rem, 1.45rem);
  font-weight: 600;
  line-height: 1.25;
  color: var(--ink);
  z-index: auto;
}

.master .master-dates {
  margin-top: 0.35rem;
  font-family: var(--font-text);
  font-size: 0.98rem;
  color: var(--ink-3);
  z-index: auto;
}

/* Biography: with JS the "Read biography" button opens the biography in a
   card over the page (.bio-dialog below), so the section never grows. The
   native disclosure stays in the markup as the no-JS fallback (and as the
   card's content source); home-sections.js swaps it for the button. */
.master-bio {
  margin-top: 1.1rem;
}

.master-bio-btn {
  margin-top: 1.1rem;
  padding: 0.35rem 0;
  border: 0;
  background: none;
}

.js-bio .master-bio {
  display: none;
}

.master-bio summary,
.master-bio-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  list-style: none;
  cursor: pointer;
  font-family: "Cinzel", Georgia, serif;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.master-bio summary::-webkit-details-marker {
  display: none;
}

.master-bio summary::after,
.master-bio-btn::after {
  content: "";
  width: 9px;
  height: 9px;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1px 100% no-repeat;
  transition: transform 0.4s var(--ease-out);
}

.master-bio[open] summary::after,
.master-bio-btn:hover::after,
.master-bio-btn:focus-visible::after {
  transform: rotate(90deg);
}

.master-bio summary:focus-visible,
.master-bio-btn:focus-visible {
  outline: 1px solid var(--gold-deep);
  outline-offset: 4px;
}

.master-bio-text {
  margin-top: 1rem;
  max-width: 34rem;
}

.master-bio-text p {
  font-family: var(--font-text);
  font-size: 1rem;
  line-height: 1.75;
  color: var(--ink-2);
  z-index: auto;
}

.master-bio-text p + p {
  margin-top: 0.8rem;
}

/* ---------- biography card (native <dialog>, built by home-sections.js) ----------
   A sheet of the section's own paper over a dim ink backdrop: the master's
   photo on the left, numeral, name and dates in the section's type, the
   biography beside them (scrolling inside the card if it is long). It rises
   a few pixels and fades in; transform and opacity only. */
.bio-dialog {
  width: min(960px, calc(100vw - 2rem));
  max-width: none;
  max-height: min(86svh, 680px);
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
  color: var(--ink);
}

.bio-dialog::backdrop {
  background: oklch(0.15 0.012 56 / 0.62);
  opacity: 0;
  transition: opacity 0.45s ease;
}

.bio-dialog.is-in::backdrop {
  opacity: 1;
}

.bio-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  max-height: min(86svh, 680px);
  overflow: hidden;
  background:
    url("Images/old-wall.png"),
    url("Images/asfalt-dark.png"),
    var(--paper-hi);
  background-blend-mode: multiply, multiply, normal;
  box-shadow:
    0 2px 6px oklch(0.15 0.02 60 / 0.2),
    0 40px 90px -30px oklch(0.1 0.02 60 / 0.65);
  opacity: 0;
  transform: translateY(18px) scale(0.985);
  transition: opacity 0.45s ease, transform 0.6s var(--ease-out);
}

.bio-dialog.is-in .bio-card {
  opacity: 1;
  transform: none;
}

/* A fine gold rule across the top edge. */
.bio-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 1;
  background: linear-gradient(to right, var(--gold-deep), var(--gold-soft) 50%, var(--gold-deep));
}

.bio-photo {
  margin: 0;
  min-height: 100%;
  background: oklch(0.86 0.012 90);
}

.bio-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

/* The text column scrolls on its own: the card only has a max-height, so
   the column needs its own cap or it just grows and gets clipped. */
.bio-body {
  max-height: min(86svh, 680px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(2.25rem, 4vw, 3.5rem) clamp(1.75rem, 4vw, 3.5rem) clamp(2rem, 3.5vw, 3rem);
  scrollbar-width: thin;
  scrollbar-color: oklch(0.5 0.095 70 / 0.5) transparent;
}

.bio-step {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-family: "Cinzel", Georgia, serif;
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1;
  color: var(--gold-deep);
}

.bio-step::before {
  content: "";
  width: 10px;
  height: 10px;
  margin-left: 2px;
  transform: rotate(45deg);
  background: var(--gold-deep);
  box-shadow: 0 0 0 3px var(--paper-hi), 0 0 0 4px oklch(0.5 0.095 70 / 0.45);
}

.bio-step::after {
  content: "";
  flex: 1;
  max-width: 7rem;
  height: 1.5px;
  background: linear-gradient(to right, oklch(0.5 0.095 70 / 0.85), transparent);
}

.bio-dialog .bio-name {
  margin-top: 1.1rem;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.5rem, 1.2vw + 1.1rem, 2.1rem);
  font-weight: 600;
  line-height: 1.15;
  color: var(--ink);
  text-wrap: balance;
}

.bio-dialog .bio-dates {
  margin-top: 0.45rem;
  font-family: var(--font-text);
  font-size: 1rem;
  color: var(--ink-3);
}

.bio-dialog .master-bio-text {
  margin-top: 1.6rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--ink-line);
  max-width: 38rem;
}

.bio-dialog .master-bio-text p {
  font-size: 1.04rem;
  line-height: 1.8;
}

/* Close: the menu's own "Close" + cross, in ink. */
.bio-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.6rem;
  border: 0;
  background: oklch(0.965 0.008 88 / 0.85);
  color: var(--ink);
  font-family: "Cinzel", Georgia, serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.35s ease, color 0.35s ease;
}

.bio-close::after {
  content: "";
  width: 14px;
  height: 14px;
  background:
    linear-gradient(45deg, transparent calc(50% - 0.75px), currentColor calc(50% - 0.75px) calc(50% + 0.75px), transparent calc(50% + 0.75px)),
    linear-gradient(-45deg, transparent calc(50% - 0.75px), currentColor calc(50% - 0.75px) calc(50% + 0.75px), transparent calc(50% + 0.75px));
}

/* Hover: the plaque fills with ink and the type turns light gold, like the
   page's buttons. No motion. */
.bio-close:hover,
.bio-close:focus-visible {
  background-color: var(--ink);
  color: oklch(0.86 0.07 84);
}

.bio-close:focus-visible {
  outline: 1px solid var(--gold-deep);
  outline-offset: 2px;
}

html.bio-open body {
  overflow: hidden;
}

/* Phones: a single column - a band of the photo, then the text, the whole
   card scrolling inside itself. */
@media (max-width: 760px) {
  .bio-dialog,
  .bio-card {
    max-height: 88svh;
  }

  .bio-card {
    grid-template-columns: minmax(0, 1fr);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .bio-photo {
    min-height: 0;
    height: 34svh;
  }

  .bio-body {
    max-height: none;
    overflow: visible;
  }
}

.lineage-foot {
  margin-top: calc(clamp(4rem, 7vw, 6rem) - var(--lift) / 2 - var(--foot-raise));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 3rem;
  flex-wrap: wrap;
}

/* The button sits in from the column edge, off the bottom-right branch. */
.lineage-foot .cta {
  margin-right: clamp(1rem, 3vw, 3.5rem);
}

.lineage .lineage-caption {
  max-width: 34rem;
  font-family: var(--font-text);
  font-size: 1rem;
  font-style: italic;
  line-height: 1.6;
  color: var(--ink-3);
  z-index: auto;
}

/* ==========================================================================
   THE GUARDIAN (ink; .hall supplies tokens, background and beams)
   ========================================================================== */

.guardian {
  --eyebrow: var(--hall-gold);
}

.guardian-inner {
  max-width: 1560px;
  margin: 0 auto;
  padding: clamp(4.5rem, 8vw, 7.5rem) var(--sec-inline);
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  column-gap: clamp(2.5rem, 6vw, 7rem);
  align-items: center;
}

.guardian-photo {
  margin: 0;
  aspect-ratio: 4 / 5;
  max-height: 46rem;
  overflow: hidden;
  background: var(--hall-band);
  box-shadow: 0 30px 60px -20px oklch(0.05 0.01 60 / 0.7);
}

.guardian-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%;
}

.guardian .guardian-title {
  margin-top: 1rem;
  max-width: none;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.9rem, 2.6vw, 3.1rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--hall-paper);
  text-wrap: balance;
  z-index: auto;
}

.guardian-text > p:not(.sec-eyebrow) {
  margin-top: 1.1rem;
  max-width: 38rem;
  font-family: var(--font-text);
  font-size: clamp(1.02rem, 0.3vw + 0.93rem, 1.15rem);
  line-height: 1.8;
  color: var(--hall-paper-2);
  text-wrap: pretty;
  z-index: auto;
}

.guardian-title + p {
  margin-top: 1.75rem !important;
}

.guardian .hall-cta {
  margin: 2.5rem 0 0;
}

/* ==========================================================================
   CONTACT ("visit")
   ========================================================================== */

.visit-inner {
  max-width: 1560px;
  margin: 0 auto;
  padding: clamp(5rem, 9vw, 8rem) var(--sec-inline);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(3rem, 7vw, 8rem);
  align-items: start;
}

/* The details sit centred against the (taller) hanging scroll, so the
   column reads as the middle of the section rather than hugging its top.
   The top margin matches the scroll's cord (--cord-h), so the centre is the
   scroll's own and not the cord's. Two columns only. */
@media (min-width: 961px) {
  .visit-info {
    align-self: center;
    margin-top: 64px;
  }
}

.visit .visit-zh {
  margin-top: 1.1rem;
  font-family: "Yuji Boku", "Noto Serif SC", serif;
  font-size: clamp(1.5rem, 1.4vw + 1rem, 2.3rem);
  line-height: 1.1;
  letter-spacing: 0.14em;
  color: var(--gold-deep);
  z-index: auto;
}

.visit .visit-title {
  margin-top: 0.6rem;
  max-width: none;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.9rem, 2.8vw, 3.2rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink);
  text-wrap: balance;
  z-index: auto;
}

.visit .visit-lead {
  margin-top: 1.5rem;
  max-width: 34rem;
  font-family: var(--font-text);
  font-size: clamp(1.02rem, 0.3vw + 0.93rem, 1.15rem);
  line-height: 1.8;
  color: var(--ink-2);
  text-wrap: pretty;
  z-index: auto;
}

.visit-details {
  margin: 2.75rem 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.75rem 2rem;
}

.visit-details dt {
  font-family: "Cinzel", Georgia, serif;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.visit-details dd {
  margin: 0.5rem 0 0;
  font-family: var(--font-text);
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--ink);
}

.visit-details a {
  font-family: inherit;
  font-size: inherit;
  color: var(--ink);
  text-decoration: none;
  background: linear-gradient(currentColor, currentColor) left bottom / 0 1px no-repeat;
  transition: background-size 0.45s var(--ease-out);
  z-index: auto;
}

.visit-details a:hover,
.visit-details a:focus-visible {
  background-size: 100% 1px;
}

/* Form - a hanging scroll (立轴), pure CSS plus a small inline SVG cord.
   Top to bottom: braided cord on a brass nail (.scroll-cord), the flat top
   rod (.scroll-rod--top), the silk mount with its two hanging strips
   (.scroll-mount), the paper itself (the form, .scroll-paper), and the round
   bottom roller with bone knobs (.scroll-rod--bottom). Light comes from the
   upper left; the scroll hangs a little off the wall, so its shadow falls
   down and to the right. The silk tucks under both rods by half their
   height, which is what the negative margins are. */
.visit-form {
  --cord-h: 64px;
  --rod-h: 12px;
  --roller-h: 26px;
  --knob-w: 18px;
  --mount-x: clamp(10px, 1.3vw, 18px);
  --mount-top: clamp(44px, 4.8vw, 68px);
  --mount-bottom: clamp(24px, 2.6vw, 38px);
  --silk: oklch(0.42 0.04 62);
  --silk-hi: oklch(0.5 0.045 68);
  --gilt: oklch(0.72 0.09 80);
  --wood-grain: repeating-linear-gradient(90deg, oklch(0 0 0 / 0.07) 0 1px, transparent 1px 7px, oklch(1 0 0 / 0.03) 7px 8px, transparent 8px 13px);
  position: relative;
  margin-top: var(--cord-h);
}

/* Cord: a dark silk line with a lighter dashed twist over it, brass rings
   where it meets the rod and a brass nail at the apex. */
.scroll-cord {
  position: absolute;
  bottom: calc(100% - 2px);
  left: 50%;
  width: min(220px, 70%);
  height: var(--cord-h);
  transform: translateX(-50%);
  overflow: visible;
  pointer-events: none;
}

.scroll-cord path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.scroll-cord-shadow { stroke: oklch(0.2 0.02 50 / 0.18); stroke-width: 3; }
.scroll-cord-line { stroke: oklch(0.3 0.05 45); stroke-width: 2.6; }
.scroll-cord-twist { stroke: oklch(0.62 0.08 70); stroke-width: 1.2; stroke-dasharray: 1.6 2.4; }
.scroll-cord-ring { fill: none; stroke: oklch(0.66 0.1 78); stroke-width: 1.6; }

/* Rods: shared lacquered wood with grain and a specular stripe. */
.scroll-rod {
  position: relative;
  z-index: 2;
  display: block;
  pointer-events: none;
}

.scroll-rod--top {
  height: var(--rod-h);
  margin-inline: -6px;
  border-radius: 3px 3px 2px 2px;
  background:
    linear-gradient(180deg, transparent 12%, oklch(1 0 0 / 0.22) 22%, transparent 38%),
    var(--wood-grain),
    linear-gradient(180deg, oklch(0.46 0.06 48), oklch(0.32 0.05 42) 45%, oklch(0.18 0.03 40));
  box-shadow:
    0 4px 5px -2px oklch(0.15 0.02 50 / 0.55),
    6px 10px 14px -8px oklch(0.15 0.02 50 / 0.35);
}

.scroll-rod--bottom {
  height: var(--roller-h);
  margin-inline: -4px;
  border-radius: calc(var(--roller-h) / 2) / 4px;
  background:
    linear-gradient(180deg, transparent 14%, oklch(1 0 0 / 0.26) 21%, transparent 30%),
    var(--wood-grain),
    linear-gradient(180deg,
      oklch(0.3 0.05 40) 0%,
      oklch(0.52 0.065 50) 20%,
      oklch(0.4 0.06 45) 36%,
      oklch(0.25 0.045 40) 70%,
      oklch(0.13 0.025 40) 100%);
  box-shadow:
    0 8px 10px -4px oklch(0.15 0.02 50 / 0.5),
    10px 22px 26px -14px oklch(0.15 0.02 50 / 0.4);
}

/* Knobs (轴头): bone, turned, with a gilt collar where they meet the roller. */
.scroll-rod--bottom::before,
.scroll-rod--bottom::after {
  content: "";
  position: absolute;
  top: -4px;
  bottom: -4px;
  width: var(--knob-w);
  background:
    linear-gradient(180deg, transparent 10%, oklch(1 0 0 / 0.5) 20%, transparent 32%),
    linear-gradient(180deg,
      oklch(0.8 0.03 80) 0%,
      oklch(0.95 0.02 90) 22%,
      oklch(0.86 0.03 82) 45%,
      oklch(0.68 0.04 72) 80%,
      oklch(0.52 0.04 65) 100%);
  box-shadow: 0 6px 8px -4px oklch(0.15 0.02 50 / 0.55);
}

.scroll-rod--bottom::before {
  right: 100%;
  border-radius: 8px 3px 3px 8px / 50% 3px 3px 50%;
  border-right: 3px solid var(--gilt);
}

.scroll-rod--bottom::after {
  left: 100%;
  border-radius: 3px 8px 8px 3px / 3px 50% 50% 3px;
  border-left: 3px solid var(--gilt);
}

/* Silk mount: woven twill, a longer "heaven" above the paper than "earth"
   below, and darker where it curls round each rod. */
.scroll-mount {
  position: relative;
  z-index: 1;
  margin-block: calc(var(--rod-h) / -2) calc(var(--roller-h) / -2);
  padding:
    calc(var(--mount-top) + var(--rod-h) / 2)
    var(--mount-x)
    calc(var(--mount-bottom) + var(--roller-h) / 2);
  background:
    linear-gradient(180deg, oklch(0.12 0.02 45 / 0.55), transparent 18px),
    linear-gradient(0deg, oklch(0.12 0.02 45 / 0.5), transparent 22px),
    linear-gradient(90deg, oklch(1 0 0 / 0.06), transparent 30%, transparent 75%, oklch(0 0 0 / 0.12)),
    repeating-linear-gradient(45deg, oklch(1 0 0 / 0.05) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.07) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, var(--silk-hi), var(--silk) 40%);
  box-shadow:
    0 2px 3px oklch(0.2 0.02 50 / 0.12),
    14px 30px 44px -22px oklch(0.15 0.02 50 / 0.55);
}

/* The two hanging strips (惊燕) on the heaven panel, edged in gilt thread. */
.scroll-mount::before {
  content: "";
  position: absolute;
  top: calc(var(--rod-h) / 2);
  left: var(--mount-x);
  right: var(--mount-x);
  height: calc(var(--mount-top) - 2px);
  pointer-events: none;
  --strip: linear-gradient(90deg,
    var(--gilt) 0 1px,
    oklch(0.36 0.035 60) 1px calc(100% - 1px),
    var(--gilt) calc(100% - 1px));
  background:
    var(--strip) 32% 0 / clamp(14px, 1.6vw, 22px) 100% no-repeat,
    var(--strip) 68% 0 / clamp(14px, 1.6vw, 22px) 100% no-repeat;
  filter: drop-shadow(1px 2px 1px oklch(0.1 0.02 45 / 0.35));
}

/* Paper: aged sheet on the site's textures, framed by a gilt thread and a
   narrow darker silk border, with the faint horizontal creases a scroll
   picks up from being rolled: soft bands, not lines, so they never read as
   field underlines, and two periods so they never look ruled. */
.visit-form .scroll-paper {
  position: relative;
  padding: clamp(2rem, 3.6vw, 3.5rem);
  background:
    repeating-linear-gradient(180deg, transparent 0 100px, oklch(0.35 0.04 60 / 0.035) 106px, oklch(1 0 0 / 0.07) 109px, transparent 116px),
    repeating-linear-gradient(180deg, transparent 0 160px, oklch(0.35 0.04 60 / 0.03) 166px, transparent 174px),
    radial-gradient(ellipse at 50% 45%, transparent 55%, oklch(0.55 0.07 65 / 0.28) 100%),
    linear-gradient(90deg, oklch(0.45 0.06 60 / 0.14), transparent 6%, transparent 94%, oklch(0.45 0.06 60 / 0.14)),
    url("Images/old-wall.png"),
    url("Images/asfalt-dark.png"),
    oklch(0.93 0.035 85);
  background-blend-mode: normal, normal, normal, normal, multiply, multiply, normal;
  box-shadow:
    0 0 0 1px var(--gilt),
    0 0 0 4px oklch(0.3 0.03 55),
    0 0 0 5px oklch(0.72 0.09 80 / 0.6),
    inset 0 0 0 1px oklch(0.55 0.06 65 / 0.2);
}

.visit .visit-form-title {
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.35rem, 0.8vw + 1.05rem, 1.75rem);
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  z-index: auto;
}

.visit .visit-form-hint {
  margin-top: 0.6rem;
  /* The title face, not the body face - the hint heads the form. */
  font-family: "Cinzel", Georgia, serif;
  font-size: 1rem;
  line-height: 1.6;
  color: #000;
  font-weight: 600;
  text-align: center;
}

/* Two phrases, one per line, so the heading never strands "touch." on a line
   of its own. On a phone a phrase may wrap again; balance keeps its lines even. */
.visit .visit-form-hint span {
  display: block;
  text-wrap: balance;
  z-index: auto;
}

.field {
  position: relative;
  margin-top: 1.4rem;
}

.field input,
.field select,
.field textarea {
  display: block;
  width: 100%;
  padding: 1.45rem 0 0.6rem;
  border: 0;
  border-bottom: 1px solid var(--ink-line);
  border-radius: 0;
  background: transparent;
  font-family: var(--font-text);
  font-size: 1.05rem;
  line-height: 1.4;
  color: var(--ink);
  outline: none;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.field textarea {
  min-height: 7.5rem;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-bottom-color: var(--gold-deep);
  box-shadow: 0 1px 0 var(--gold-deep);
}

.field label {
  position: absolute;
  left: 0;
  top: 1.45rem;
  font-family: var(--font-text);
  font-size: 1.05rem;
  line-height: 1.4;
  color: var(--ink-3);
  transform-origin: left top;
  pointer-events: none;
  transition: transform 0.35s var(--ease-out), color 0.3s ease;
}

/* Label floats up once the field has focus or a value. */
.field input:focus + label,
.field input:not(:placeholder-shown) + label,
.field textarea:focus + label,
.field textarea:not(:placeholder-shown) + label,
.field select:focus + label,
.field select:valid + label {
  transform: translateY(-1.25rem) scale(0.78);
  color: var(--gold-deep);
}

.field--select select {
  appearance: none;
  padding-right: 2rem;
  cursor: pointer;
  background:
    linear-gradient(45deg, transparent 50%, var(--ink-3) 50%) calc(100% - 10px) 62% / 6px 6px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--ink-3) 50%) calc(100% - 4px) 62% / 6px 6px no-repeat;
}

/* Invalid select reads as empty (transparent text) until a choice is made. */
.field--select select:invalid {
  color: transparent;
}

.field--select option {
  color: var(--ink);
}

.visit-form .btn-ink--wide {
  width: 100%;
  margin-top: 2.25rem;
}

/* Error message from contactinfo.js. */
.contact-error {
  margin-top: 1rem;
  padding: 0.85rem 1.1rem;
  background: oklch(0.55 0.15 28 / 0.09);
  color: oklch(0.42 0.14 28);
  font-family: var(--font-text);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* ==========================================================================
   SMALL SCREENS
   ========================================================================== */

@media (max-width: 960px) {
  .lineage-head,
  .visit-inner {
    grid-template-columns: 1fr;
  }

  .lineage .lineage-lead {
    margin-top: 1.75rem;
  }

  .visit-form {
    margin-top: calc(3.5rem + var(--cord-h));
  }

  .guardian-inner {
    grid-template-columns: 1fr;
    row-gap: 3rem;
  }

  .guardian-photo {
    max-height: 34rem;
  }
}

@media (max-width: 760px) {
  .lineage-thread {
    display: none;
  }

  .master .master-step::after {
    content: "";
    flex: 1;
    height: var(--line);
    margin-left: 0.35rem;
    background: linear-gradient(to right, oklch(0.5 0.095 70 / 0.4), var(--line-c) 2.5rem);
  }

  .master:last-of-type .master-step::after {
    background: linear-gradient(to right, oklch(0.5 0.095 70 / 0.4), var(--line-c) 2.5rem, transparent);
  }

  .lineage-masters {
    grid-template-columns: 1fr;
    row-gap: 3.5rem;
    max-width: 30rem;
    margin-inline: auto;
  }

  .master:nth-of-type(2),
  .master:nth-of-type(3) {
    margin-top: 0;
  }

  .lineage-foot {
    flex-direction: column;
    align-items: flex-start;
  }

  .lineage-foot .cta {
    margin-right: 0;
  }
}

@media (max-width: 480px) {
  .visit-details {
    grid-template-columns: 1fr;
  }

  /* Let the long email wrap so the column (and the roller knobs) fit the gutter. */
  .visit-inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .visit-details dd {
    overflow-wrap: anywhere;
  }

  .visit-form {
    --mount-x: 7px;
  }

  .visit-form .scroll-paper {
    padding: 1.75rem 1.25rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .master-photo img,
  .master-bio summary::after,
  .master-bio-btn::after,
  .bio-dialog::backdrop,
  .bio-card,
  .bio-close,
  .field label {
    transition: none;
  }
}

/* Contact form honeypot: off-screen, out of the tab order and hidden from
   assistive tech. People never reach it; bots fill it (utils/formGuard.js). */
.form-hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Form heads (the contact form here, the MasterClass registration on
   /events/masterclass): a short Cinzel title centred over the form with a
   fine gold rule beneath it, so the scroll reads title -> fields rather than
   starting straight on an input. The MasterClass head adds the gold eyebrow
   its own thank-you state already uses. */
.form-head-group {
  margin-bottom: 1.75rem;
  text-align: center;
}

.form-head-group .mcp-form-eyebrow {
  margin-bottom: 0.5rem;
}

.visit-form-title.form-head {
  margin: 0;
  text-align: center;
  text-wrap: balance;
}

.visit-form-title.form-head::after {
  content: "";
  display: block;
  width: 2.75rem;
  height: 1px;
  margin: 0.8rem auto 0;
  background: linear-gradient(to right, transparent, var(--gold-deep, oklch(0.6 0.1 74)), transparent);
}

.visit .form-head + .visit-form-hint {
  margin-top: 1rem;
}
