/* =============================================================
   Mantle - Tarot Instrument
   Stylesheet for both Night (dark) and Parchment (light) modes.
   ============================================================= */

/* --- Fonts ---
   Mantle is set in Fraunces (variable, with the WONK axis turned on).
   The Google Fonts <link> in base.html serves the variable file with
   all axes, but local() comes first so a system-installed Fraunces is
   preferred when present. */

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: local("Fraunces");
}

@font-face {
  font-family: "Fraunces";
  font-weight: 100 900;
  font-display: swap;
  src: local("Fraunces Italic");
}

/* --- Tokens --- */

:root {
  --serif: "Fraunces", "Cormorant Garamond", "EB Garamond", Georgia,
           "Times New Roman", serif;
  --mono:  ui-monospace, "JetBrains Mono", "Söhne Mono",
           "SF Mono", Consolas, monospace;
  /* The subheader voice — tracked Spectral caps, sitting between the
     Fraunces display and the DM Mono chrome. It names readings and
     sections; it never takes over the mono's apparatus role. */
  --subhead: "Spectral", "Fraunces", Georgia, serif;

  --red: #a13434;
  --red-soft: #b85959;
  --red-deep: #843333;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 72px;
  --space-9: 112px;

  /* The warm "table" paper the Read together sheet is cut from. Sits
     outside the themes on purpose: that sheet keeps this palette over
     parchment and night alike, so anything matching it must too. */
  --paper-warm: #f1ebdd;
}

body.theme-night {
  --bg:        #0c0c0c;
  --fg:        #e9deca;
  --fg-muted:  #8a8270;
  --fg-faint:  #4a4538;
  --rule:      #25241f;
  --rule-soft: #1a1a16;
  --card-bg:   #14130f;
}

body.theme-parchment {
  --bg:        #f1e8d0;
  --fg:        #1a1815;
  --fg-muted:  #6c6655;
  --fg-faint:  #b9ad8c;
  --rule:      #d4c8a4;
  --rule-soft: #e2d8b6;
  --card-bg:   #ece2c4;
}

/* --- Reset --- */

*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

/* Nothing in Mantle is set in italic (2026-07-17). The templates still
   use <em> for emphasis — it carries the meaning, and screen readers
   announce it — but the browser's default slant is off everywhere;
   emphasis is expressed with colour, weight and spacing instead. <i>
   is used here only as a decorative/structural element (corner marks,
   hexagram bars, list markers), so this simply keeps it neutral. */
em, i { font-style: normal; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* WONK is OFF at body sizes — it reads as bold below ~24px.
     Optical sizing tracks font-size automatically. */
  font-optical-sizing: auto;
}

/* Wonk on for display-scale text only, where its character reads as
   character rather than weight. Applied to the largest serif elements. */
.display,
.card-panel .headline,
.wheel .center-name,
.question-text {
  font-variation-settings: "WONK" 1;
}

a { color: inherit; }

/* --- Type --- */

.label,
.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.eyebrow-red {
  color: var(--red);
}

.display {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(40px, 6vw, 78px);
  line-height: 1.05;
  letter-spacing: -0.01em;
}

.display em {
  font-weight: 400;
}

/* --- Subheaders (Spectral, tracked caps) ---
   The two subheader layers the type system was missing: `.subhead-title`
   names a reading ("I · The Brief Consult"), `.subhead-section` names a
   section inside one ("The Cards Drawn"). Tracking opens as the size
   drops, to keep the caps legible small. */

.subhead-title {
  font-family: var(--subhead);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin: 0;
}

.subhead-section {
  font-family: var(--subhead);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin: 0;
}

.subhead-title.red,
.subhead-section.red { color: var(--red); }

.muted { color: var(--fg-muted); }

/* Inline astrological glyphs — used in sig lines, panel meta, chain
   rows, wheel labels.  We deliberately avoid the colour-emoji fonts
   ("Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji") so the
   browser substitutes a monochrome symbol font and the glyph inherits
   `currentColor`. The U+FE0E variation selector appended to each
   character in app.py is the second half of the same guarantee.

   `font-variant-emoji: text` is the modern, explicit way to say the
   same thing — supported in Chrome 121+, Firefox 132+, Safari 17.4+. */
.astro-sym {
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "Arial Unicode MS", serif;
  font-style: normal !important;
  font-weight: inherit;
  font-variation-settings: normal;
  font-feature-settings: normal;
  font-variant-emoji: text;
  letter-spacing: 0;
  text-transform: none;
  color: inherit;
}

/* --- Layout chrome --- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--rule-soft);
}

.site-header .brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: inherit;
}

.site-header .brand .sigil {
  width: 26px;
  height: 26px;
}

.site-header .brand-name {
  font-family: var(--serif);
  font-size: 22px;
  letter-spacing: 0;
}

.site-header .brand-name em {
  font-weight: 400;
}

.site-nav {
  display: flex;
  gap: var(--space-6);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.site-nav a {
  text-decoration: none;
  color: var(--fg-muted);
  padding-bottom: 4px;
}

.site-nav a.active {
  color: var(--fg);
  border-bottom: 1px solid var(--red);
}

.site-nav a:hover {
  color: var(--red);
}

/* Username + sign-out, slotted into the same mono-caps nav strip. */
.site-nav-user {
  color: var(--fg-faint);
}

.site-nav-user-active {
  color: var(--fg);
  border-bottom: 1px solid var(--red);
}

/* `display: contents` makes the form box disappear from layout so the
   button below participates directly in `.site-nav`'s flex container —
   keeps its baseline aligned with the other nav items. */
.site-nav-logout {
  display: contents;
  margin: 0;
  padding: 0;
}

/* Explicit fonts (not `font: inherit`) because browsers apply their own
   `font-family: button` UA default to <button> that beats inheritance. */
.site-nav-link {
  background: transparent;
  border: 0;
  margin: 0;
  padding: 0 0 4px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: normal;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.site-nav-link:hover {
  color: var(--red);
}

/* Hamburger — hidden on desktop, shown on phones (see the media query
   below). Two bars; the negative margin gives a 36px+ tap target while
   the visible icon stays small. */
.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: 0;
  padding: 8px;
  margin: -8px;
  cursor: pointer;
}

.nav-toggle-bar {
  display: block;
  width: 20px;
  height: 1.5px;
  background: var(--fg);
}

/* Drawer chrome — hidden on desktop. `.nav-links` is display:contents so
   the links sit directly in the inline nav strip; the drawer head and
   backdrop don't exist there. */
.nav-backdrop,
.nav-drawer-head { display: none; }
.nav-links { display: contents; }

/* Phones: the inline nav strip is wider than the screen, so the
   hamburger opens a slide-in drawer from the right (backdrop dims the
   page; the drawer holds the nav as full-width rows with Sign out
   pinned to the foot). Shown when the header carries `.nav-open`. */
@media (max-width: 720px) {
  /* Pinned so the hamburger is always reachable — on a long reading the
     header used to scroll away and strand the only way to navigate.
     z-index 50 clears the reading's fixed footer (40) and Read-together
     sheet (30) but stays under the drawer + backdrop (61 / 60), which
     must cover it when open. The grain matches the body's so the pinned
     strip doesn't read as a flat patch sliding over textured content. */
  .site-header {
    padding: var(--space-4) var(--space-5);
    position: sticky;
    top: 0;
    z-index: 50;
    background-color: var(--bg);
    background-image: var(--grain-parchment);
  }
  body.theme-night .site-header {
    background-image: var(--grain-night);
  }
  .nav-toggle {
    display: flex;
  }

  .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(20, 19, 15, 0.4);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.28s ease;
  }
  .site-header.nav-open .nav-backdrop {
    opacity: 1;
    pointer-events: auto;
  }

  .site-nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 61;
    width: 74%;
    max-width: 300px;
    flex-direction: column;
    gap: 0;
    padding: 0;
    background: var(--bg);
    border-left: 1px solid var(--rule);
    box-shadow: -10px 0 28px rgba(92, 22, 15, 0.16);
    transform: translateX(100%);
    transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
    overflow-y: auto;
  }
  .site-header.nav-open .site-nav {
    transform: translateX(0);
  }

  .nav-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--rule);
  }
  .nav-drawer-title {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--fg-muted);
  }
  .nav-drawer-close {
    background: none;
    border: 0;
    padding: 4px;
    margin: -4px;
    cursor: pointer;
    font-family: var(--serif);
    font-size: 20px;
    line-height: 1;
    color: var(--fg);
  }

  .nav-links {
    display: flex;
    flex-direction: column;
  }
  .nav-links a {
    padding: 16px 20px;
    border-bottom: 1px solid var(--rule);
  }
  .nav-links a.active {
    border-bottom: 1px solid var(--rule);
  }

  .site-nav-logout {
    display: block;
    margin-top: auto;
    border-top: 1px solid var(--rule);
    padding: 0;
  }
  .nav-signout {
    width: 100%;
    padding: 18px 20px;
    text-align: left;
    color: var(--red);
  }
}

/* --- Landing --- */

/* Ranged left, like a page. The same edge lines the hero up with the
   contents rows below (both inset var(--space-6)). */
.landing-hero {
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  text-align: left;
  padding: var(--space-9) var(--space-6);
}

.landing-hero .sigil {
  width: 52px;
  height: 52px;
  margin-bottom: var(--space-5);
  opacity: 0.92;
}

/* No max-width cap here: an 18ch cap was what folded the sentence onto
   three lines. At the clamped display size it fits on one line at every
   desktop width (the line is ~12.4x the font-size wide, and 6vw of that
   is ~0.74 of the viewport — always inside the hero's padding). */
.landing-hero .display {
  font-size: clamp(40px, 5.5vw, 72px);
  margin: var(--space-2) 0 var(--space-4);
}

/* "internal matter." is one phrase — never break it. On a phone the
   sentence still wraps, but that half drops underneath intact rather
   than splitting mid-thought. */
.landing-hero .display em {
  white-space: nowrap;
}

.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* At narrow phone widths, 40px leaves the short word "an" stranded on
   its own line before the protected phrase. A small optical step down lets
   "an internal matter." travel together as the second line. */
@media (max-width: 420px) {
  .landing-hero .display {
    font-size: 35px;
    line-height: 1.08;
  }
}

/* Desktop: the whole sentence reads as a single line. */
@media (min-width: 721px) {
  .landing-hero .display {
    white-space: nowrap;
  }
}

.landing-hero .lede {
  max-width: 58ch;
  margin: 0;
  color: var(--fg);
  opacity: 0.78;
  font-size: clamp(19px, 1.3vw, 22px);
  line-height: 1.55;
}

.landing-hero-call {
  margin: var(--space-5) 0 0;
  color: var(--fg);
  font-family: var(--serif);
  font-size: clamp(18px, 1.15vw, 20px);
  font-weight: 600;
  line-height: 1.4;
}

/* --- The instruments: a table of contents, not a grid of tiles ---
   The landing reads as a book — frontispiece, then a numbered contents
   of the readings. (Handoff "5a".) */

.landing {
  max-width: 1180px;
  margin: 0 auto;
}

.landing-ornament {
  padding: var(--space-3) var(--space-6) var(--space-2);
}

.instruments-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: var(--space-5) var(--space-6) 0;
}

.instruments-count {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0;
}

/* The readings behave as an expanding table of contents. Three-card is
   the resting selection; pointer and keyboard focus move the same matted
   treatment to another instrument instead of flashing a separate hover
   colour. The numeric dimensions let the whole exchange interpolate. */
.instrument-list {
  display: block;
  padding: var(--space-4) var(--space-6) var(--space-2);
}

.instrument-choice {
  --instrument-ease: cubic-bezier(.22, 1, .36, 1);
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) max-content;
  gap: var(--space-6);
  align-items: center;
  min-height: 78px;
  margin: 0;
  padding: var(--space-5) var(--space-2);
  border-top: 1px solid var(--rule);
  color: inherit;
  text-decoration: none;
  transition:
    grid-template-columns .46s var(--instrument-ease),
    gap .46s var(--instrument-ease),
    min-height .46s var(--instrument-ease),
    margin .46s var(--instrument-ease),
    padding .46s var(--instrument-ease),
    background-color .32s ease,
    border-color .32s ease,
    box-shadow .46s var(--instrument-ease);
}

.instrument-choice:last-child:not(.is-active) {
  border-bottom: 1px solid var(--rule);
}

.instrument-choice.is-active {
  grid-template-columns: 132px minmax(0, 1fr) max-content;
  min-height: 256px;
  margin: var(--space-2) 0;
  padding: 22px 26px;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  box-shadow: inset 0 0 0 var(--panel-keyline) var(--bg);
}

.instrument-choice.is-active:hover { background: var(--rule-soft); }

.instrument-choice:focus-visible {
  outline: 1px solid var(--red);
  outline-offset: 4px;
}

.instrument-visual {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 34px;
  transition: height .46s var(--instrument-ease);
}

.instrument-choice.is-active .instrument-visual { height: 211px; }

.instrument-numeral {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center start;
  font-family: var(--serif);
  font-weight: 500;
  font-variation-settings: "WONK" 1;
  font-size: 26px;
  color: var(--fg-muted);
  opacity: 1;
  transform: translateY(0);
  transition: opacity .2s ease, transform .38s var(--instrument-ease);
}

.instrument-numeral.red { color: var(--red); }

.instrument-choice.is-active .instrument-numeral {
  opacity: 0;
  transform: translateY(-8px);
}

.instrument-art {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1.5px solid var(--red);
  background: var(--bg);
  opacity: 0;
  transform: translate(-50%, calc(-50% + 10px)) scale(.94);
  transition: opacity .28s ease .08s, transform .46s var(--instrument-ease);
}

.instrument-choice.is-active .instrument-art {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* The outer visual column remains identical for every instrument, but the
   bordered inner frame follows the source deck. A universal 132:211 frame
   sits between these two ratios: it either hides the Tarot title band or
   leaves gutters inside Lenormand. Letting the frame hug the JPEG preserves
   both decks without making the surrounding panel jump. */
.instrument-art-tarot,
.instrument-art-table {
  width: auto;
  height: 100%;
  aspect-ratio: 293 / 567;
}

.instrument-art-lenormand {
  width: 100%;
  height: auto;
  aspect-ratio: 404 / 616;
}

.instrument-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.instrument-art-iching > span,
.instrument-art-rune > span {
  color: var(--fg);
  font-size: 72px;
  line-height: 1;
  text-shadow: 0 0 28px color-mix(in srgb, var(--red) 30%, transparent);
}

.instrument-art-iching > span { font-family: var(--serif); }
.instrument-art-rune > span { font-family: "Noto Sans Runic", var(--serif); }

.instrument-body {
  display: block;
  min-width: 0;
}

.instrument-kicker {
  display: block;
  overflow: hidden;
  max-height: 0;
  margin-bottom: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--red);
  opacity: 0;
  transform: translateY(6px);
  transition:
    max-height .38s var(--instrument-ease),
    margin .38s var(--instrument-ease),
    opacity .22s ease,
    transform .38s var(--instrument-ease);
}

.instrument-choice.is-active .instrument-kicker {
  max-height: 20px;
  margin-bottom: var(--space-2);
  opacity: 1;
  transform: translateY(0);
}

.instrument-title-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-1);
  transition: margin .38s var(--instrument-ease);
}

.instrument-title {
  font-size: 15px;
  transition: font-size .38s var(--instrument-ease), letter-spacing .38s ease;
}

.instrument-choice.is-active .instrument-title-row { margin-bottom: var(--space-3); }

.instrument-choice.is-active .instrument-title {
  font-size: 20px;
  letter-spacing: .14em;
}

.toc-badge {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  border: 1px solid var(--red);
  padding: 2px 6px;
}

.instrument-desc,
.instrument-detail {
  display: block;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.5;
  color: var(--fg-muted);
}

.instrument-desc {
  max-width: 58ch;
  transition: font-size .38s var(--instrument-ease);
}

.instrument-choice.is-active .instrument-desc { font-size: 17px; }

.instrument-detail {
  display: grid;
  grid-template-rows: 0fr;
  max-width: 58ch;
  margin-top: 0;
  opacity: 0;
  transition:
    grid-template-rows .46s var(--instrument-ease),
    margin .38s var(--instrument-ease),
    opacity .24s ease;
}

.instrument-detail > span {
  display: block;
  min-height: 0;
  overflow: hidden;
}

.instrument-choice.is-active .instrument-detail {
  grid-template-rows: 1fr;
  margin-top: var(--space-2);
  opacity: 1;
}

.instrument-enter {
  position: relative;
  min-width: 96px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .16em;
  text-align: right;
  text-transform: uppercase;
  white-space: nowrap;
}

.instrument-tag,
.instrument-action {
  display: block;
  transition: opacity .24s ease, transform .38s var(--instrument-ease);
}

.instrument-tag {
  color: var(--fg-muted);
  opacity: 1;
}

.instrument-action {
  position: absolute;
  top: 50%;
  right: 0;
  color: var(--fg);
  opacity: 0;
  transform: translateY(calc(-50% + 6px));
}

.instrument-choice.is-active .instrument-tag {
  opacity: 0;
  transform: translateY(-6px);
}

.instrument-choice.is-active .instrument-action {
  opacity: 1;
  transform: translateY(-50%);
}

.instrument-choice.corner-marks > i {
  opacity: 0;
  transition: opacity .24s ease .08s;
}

.instrument-choice.is-active.corner-marks > i { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .instrument-choice,
  .instrument-visual,
  .instrument-numeral,
  .instrument-art,
  .instrument-kicker,
  .instrument-title-row,
  .instrument-title,
  .instrument-desc,
  .instrument-detail,
  .instrument-tag,
  .instrument-action,
  .instrument-choice.corner-marks > i {
    transition-duration: .001ms !important;
  }
}

.landing-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  margin-top: var(--space-5);
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.landing-folio { color: var(--fg-faint); }

/* Phones have no hover journey. Three-card remains the stable featured
   choice and every other instrument keeps the compact contents shape. */
@media (max-width: 720px) {
  .instrument-choice {
    grid-template-columns: 40px minmax(0, 1fr);
    gap: var(--space-3);
    align-items: center;
  }

  .instrument-choice.is-active {
    grid-template-columns: 96px minmax(0, 1fr);
    min-height: 204px;
    gap: var(--space-4);
  }

  .instrument-choice.is-active .instrument-visual { height: 154px; }

  .instrument-enter {
    grid-column: 2;
    justify-self: start;
    min-width: 96px;
    margin-top: var(--space-3);
    text-align: left;
  }

  .landing-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
  }
}

/* Small CTA under the contents pointing logged-in users at their
   journal. Editorial-aside register: serif, muted, the link itself in
   brand red. Inset to the same left edge as the hero and the
   contents rows; border-box means that padding would eat the measure,
   so the max-width adds it back to keep the lede's 56ch. */
.landing-journal-cta {
  margin: var(--space-6) 0 0;
  padding: 0 var(--space-6);
  max-width: calc(56ch + var(--space-6) * 2);
  font-family: var(--serif);
  font-size: 18px;
  color: var(--fg-muted);
}

.landing-journal-cta a {
  color: var(--red);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: border-color .15s ease;
}

.landing-journal-cta a:hover {
  border-bottom-color: var(--red);
}

/* --- Reading shell --- */

/* Caps content width on wide displays so readings stay readable. */
.reading-shell {
  max-width: 1440px;
  margin: 0 auto;
}

/* --- Reading top bar --- */

.reading-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-4) var(--space-5) var(--space-2);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.reading-topbar .left, .reading-topbar .right {
  display: flex;
  gap: var(--space-5);
  color: var(--fg-muted);
}

.reading-topbar .reading-no {
  color: var(--fg);
}

.reading-topbar .saved {
  color: var(--red);
}

/* --- Question bar (three-card) --- */

.question-bar {
  display: grid;
  grid-template-columns: max-content 1fr max-content;
  gap: var(--space-5);
  align-items: center;
  padding: var(--space-2) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--rule);
}

.question-bar .question-text {
  font-family: var(--serif);
  font-size: 26px;
  line-height: 1.3;
  color: var(--fg);
}

.question-bar .actions {
  display: flex;
  gap: var(--space-5);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.question-bar .actions a,
.question-bar .actions button {
  color: var(--fg-muted);
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-decoration: none;
  cursor: pointer;
}

.question-bar .actions a:hover,
.question-bar .actions button:hover { color: var(--red); }

/* Phones: the three-column bar can't fit question + actions side by
   side; stack them, let the action strip wrap, and give the links
   enough height to hit with a thumb. */
@media (max-width: 720px) {
  .question-bar {
    grid-template-columns: 1fr;
  }
  .question-bar .question-text {
    font-size: 22px;
  }
  .question-bar .actions {
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-5);
  }
  .question-bar .actions a,
  .question-bar .actions button {
    padding: 8px 0;
  }
}

/* --- Three card grid --- */

/* Three-card field wrap: holds the grid + a sibling SVG overlay
   that draws the elemental-dignity sigils and pair links on hover.
   The overlay is `pointer-events:none` so the cards themselves still
   receive hover.  The hint below is muted away once the user is
   actively reading. */
.tc-wrap {
  position: relative;
  padding: var(--space-3) 0 var(--space-5);
}

.three-card {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  border-bottom: 1px solid var(--rule);
  position: relative;
  z-index: 2;
}

.three-card .card-panel {
  padding: var(--space-4);
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  transition: opacity .2s ease, transform .2s ease;
}

/* Dim every card that isn't part of the active hover pair. */
.three-card.focusing .card-panel:not(.involved) {
  opacity: 0.4;
}

/* The actively-hovered card lifts and gets a red frame; involved
   neighbours retain normal opacity but no border emphasis. */
.three-card .card-panel.hovered .card-frame {
  border-color: var(--red);
  transform: translateY(-3px);
  box-shadow:
    0 0 0 3px rgba(161, 52, 52, 0.13),
    0 10px 24px rgba(92, 22, 15, 0.20);
}

/* The dignity overlay: absolute over the card row.  Drawn into
   from JS using getBoundingClientRect-measured card centres so the
   geometry follows any responsive reflow. */
.tc-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  overflow: visible;
}

.tc-hint {
  position: absolute;
  left: 50%;
  bottom: -2px;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-faint);
  transition: opacity .2s ease;
}
.tc-wrap.focusing .tc-hint { opacity: 0; }

.three-card .card-panel:last-child { border-right: 0; }

.card-panel .card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.card-panel .position {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.card-panel .position-num { color: var(--red); }
.card-panel .position-glyph { width: 18px; height: 18px; opacity: 0.7; }

.card-panel .badge {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* Card image placeholder area: aspect-ratio frame, name centred.
   Width is clamped against viewport height so the whole three-card
   reading (cards + read-together + actions) fits in the viewport
   without scrolling.  Math: each panel's non-frame chrome ≈ 250px
   (head, headline + subtitle, the quote, drawn label, gaps);
   above the field ≈ 200px (header / topbar / question-bar / wrap
   padding); below ≈ 240px (read-together + actions).  So the
   frame's height budget is roughly `100vh - 690px`; its width is
   that * 5/8 = 0.625.  Clamped to [140, 320] for legibility on
   small monitors and to keep cards in scale on large ones. */
.card-frame {
  aspect-ratio: 5 / 8;
  width: 100%;
  max-width: clamp(140px, calc((100vh - 690px) * 0.625), 320px);
  align-self: center;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-3);
  color: var(--fg-muted);
  font-family: var(--serif);
  font-size: 15px;
  letter-spacing: 0;
}

.card-panel .headline {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 36px;
  line-height: 1.04;
  letter-spacing: -0.01em;
  margin: 0;
  text-wrap: balance;
}

.card-panel .subtitle {
  font-family: var(--serif);
  font-size: 20px;
  color: var(--fg);
  margin: 0;
}

.card-panel .glyph {
  /* The element badge in the card-head already names the element
     plainly; the small glyph here is decorative and costs vertical
     space.  Hide it so the layout stays in the viewport. */
  display: none;
}

/* Phones: the height-fit formula above chases a "no scroll" goal that
   only makes sense on a monitor with vertical room to spare — on a
   ~700-800px-tall phone viewport it always bottoms out at the 140px
   floor, so the card art shrinks to a thumbnail while the 36px
   headline stays full-size next to it. Below 900px the grid is
   already a single stacked column (see the .three-card rule), so
   size the frame off width instead, let the reading scroll like any
   other page, and bring the headline down a step to match. */
@media (max-width: 900px) {
  .card-frame {
    max-width: min(280px, 62vw);
  }
  .card-panel .headline {
    font-size: 28px;
  }
  .card-panel .subtitle {
    font-size: 17px;
  }
}

.card-panel .pull-quote {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.45;
  color: var(--fg);
  margin: 0;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--rule);
}

.card-panel .drawn {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-top: auto;
}

.read-together {
  border-top: 0;
  padding: var(--space-4) var(--space-5);
}

.read-together .label { color: var(--red); margin-bottom: var(--space-3); }

.read-together .copy {
  font-size: 16px;
  line-height: 1.55;
}

.read-together .copy em {
  color: var(--fg-muted);
}

/* Multi-paragraph syntheses (currently the Grand Tableau) — each
   paragraph is its own <p class="copy">; this gives them visible
   breathing room and trims the outer margins so the body still
   sits flush inside `.read-together`. */
.gt-synthesis-body .copy {
  margin: 0 0 var(--space-4);
}
.gt-synthesis-body .copy:last-child {
  margin-bottom: 0;
}

@media (max-width: 900px) {
  .three-card { grid-template-columns: 1fr; }
  .three-card .card-panel { border-right: 0; border-bottom: 1px solid var(--rule); }
}

/* --- Forms --- */

.form-shell {
  max-width: 640px;
  margin: 0 auto;
  padding: var(--space-9) var(--space-6);
  text-align: center;
}

.form-shell .display { margin: var(--space-2) 0 var(--space-7); }

.form-shell .lede {
  color: var(--fg-muted);
  margin-bottom: var(--space-7);
  max-width: 52ch;
  margin-left: auto;
  margin-right: auto;
}

.form-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  text-align: left;
}

.form-row { display: flex; flex-direction: column; gap: var(--space-2); }

.form-row label {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.form-row input,
.form-row select,
.form-row textarea {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  color: var(--fg);
  font-family: var(--serif);
  font-size: 22px;
  padding: var(--space-3) 0;
  outline: none;
  border-radius: 0;
}

.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus { border-bottom-color: var(--red); }

.form-row textarea { resize: vertical; min-height: 80px; }

.form-row select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
                    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 8px) 50%;
  background-size: 6px 6px;
  background-repeat: no-repeat;
  padding-right: var(--space-6);
}

.form-row .radio-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  font-family: var(--serif);
  font-size: 22px;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--rule);
}

.form-row .radio-row label {
  font-family: var(--serif);
  font-size: 22px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fg);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}

.form-row .radio-row input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  /* The generic `.form-row input` rule above applies padding+font sizing
     to every input; we have to zero that out here or the radio inherits
     vertical padding (12px top/bottom) and renders as a tall oval. */
  width: 14px;
  height: 14px;
  min-width: 14px;
  min-height: 14px;
  flex: 0 0 14px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--fg-muted);
  border-radius: 50%;
  display: inline-block;
  position: relative;
}

.form-row .radio-row input[type="radio"]:checked {
  border-color: var(--red);
}

.form-row .radio-row input[type="radio"]:checked::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: var(--red);
  border-radius: 50%;
}

.form-error {
  color: var(--red);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Flash messages (success / error). Share the eyebrow-ish look so they
   sit comfortably above forms without dominating the layout. */
.form-flash {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: var(--space-3) var(--space-4);
  border-left: 2px solid var(--rule);
  margin: var(--space-3) 0;
  background: var(--rule-soft);
}
.form-flash-success { border-left-color: var(--fg); color: var(--fg); }
.form-flash-error   { border-left-color: var(--red); color: var(--red); }

.btn-cast {
  margin-top: var(--space-6);
  padding: var(--space-4) var(--space-6);
  background: var(--red);
  color: #f5ecd6;
  border: 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .2s ease;
}

.btn-cast:hover { background: #843333; }

/* Destructive variant (delete account, etc.) + a few account-page bits. */
.btn-danger { background: #6b1414; }
.btn-danger:hover { background: #531010; }
.form-optional {
  color: var(--fg-faint);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.85em;
}
.account-settings + .account-settings { margin-top: var(--space-7); }
.account-danger {
  border-top: 1px solid var(--rule);
  margin-top: var(--space-7);
  padding-top: var(--space-5);
}

/* --- Account page (/account) ----------------------------------------
   The user's own area: identity at top, stats row, list of every
   reading they own. Shares the editorial cream/parchment palette and
   serif/mono mix with the rest of the app. */

.account-shell {
  max-width: 980px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-6) var(--space-7);
  text-align: left;
}

.account-shell .display {
  margin: var(--space-2) 0 var(--space-5);
}

.account-shell .lede {
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.5;
  color: var(--fg-muted);
  margin-bottom: var(--space-6);
  max-width: 60ch;
}

.account-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
  padding: var(--space-5) 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--space-6);
}

/* Account page: identity facts table. Definition-list pattern,
   styled as two columns — small mono-caps label, serif body value. */
.account-facts {
  margin: 0 0 var(--space-7);
  padding: var(--space-5) 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  display: grid;
  gap: var(--space-4);
}

.account-facts .fact {
  display: grid;
  grid-template-columns: 180px 1fr;
  align-items: baseline;
  gap: var(--space-5);
}

.account-facts dt {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0;
}

.account-facts dd {
  font-family: var(--serif);
  font-size: 20px;
  color: var(--fg);
  margin: 0;
}

.account-settings .eyebrow {
  margin-bottom: var(--space-3);
}

.settings-placeholder {
  font-family: var(--serif);
  font-size: 16px;
  color: var(--fg-muted);
  margin: 0;
  max-width: 60ch;
}

/* Dashboard: "most recurring" tiles — four cards under the type stats
   showing the user's most-frequent card / house / sign / sephira and
   the count, or an empty-state line if a metric has no underlying
   readings. */

.recurrences {
  margin-bottom: var(--space-7);
}

.recurrences .eyebrow {
  margin-bottom: var(--space-3);
}

.recurrence-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
}

.recurrence {
  border: 1px solid var(--rule);
  padding: var(--space-4) var(--space-4) var(--space-5);
  background: transparent;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.recurrence-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0;
}

.recurrence-name {
  font-family: var(--serif);
  font-size: 22px;
  line-height: 1.15;
  color: var(--fg);
  margin: 0;
  font-variation-settings: "WONK" 1;
}

.recurrence-count {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0;
}

/* Visual slot — image or large glyph above the name. Fixed min-height
   so the four tiles align even when one shows a card image and
   another shows a Roman numeral or a zodiac symbol. */
.recurrence-visual {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 140px;
  margin: var(--space-2) 0 var(--space-3);
}

.recurrence-card-art-wrap {
  width: 88px;
  aspect-ratio: 5 / 8;
  background: var(--card-bg);
  border: 1px solid var(--rule);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.recurrence-card-art {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.recurrence-roman {
  font-family: var(--serif);
  font-size: 72px;
  font-weight: 400;
  line-height: 1;
  color: var(--red);
  margin: 0;
  font-variation-settings: "WONK" 1;
}

.recurrence-symbol {
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "Arial Unicode MS", serif;
  font-size: 64px;
  line-height: 1;
  color: var(--red);
  font-style: normal;
  font-variation-settings: normal;
  font-variant-emoji: text;
}

.recurrence-sephira-mark {
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1.1;
  color: var(--red);
  margin: 0;
  text-align: center;
  font-variation-settings: "WONK" 1;
}

.recurrence-empty {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.35;
  color: var(--fg-faint);
  margin: 0;
}

.account-stats .stat-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 var(--space-2);
}

.account-stats .stat-value {
  font-family: var(--serif);
  font-size: 40px;
  line-height: 1;
  color: var(--fg);
  margin: 0;
  font-variation-settings: "WONK" 1;
}

/* The journal's stat tiles are links that filter the reading list. */
a.stat {
  text-decoration: none;
  color: inherit;
  padding: var(--space-2);
  margin: calc(-1 * var(--space-2));
  border-bottom: 2px solid transparent;
}

a.stat:hover .stat-label { color: var(--red); }

a.stat.stat-active { border-bottom-color: var(--red); }

a.stat.stat-active .stat-label { color: var(--red); }

.journal-search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: var(--space-4);
}

.journal-search input[type="search"] {
  flex: 1;
  max-width: 340px;
  min-width: 0;
  border: 1px solid var(--rule);
  background: transparent;
  font-family: var(--serif);
  font-size: 15px;
  color: var(--fg);
  padding: 7px 11px;
}

.journal-search button {
  border: 1px solid var(--rule);
  background: transparent;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
  padding: 8px 12px;
  cursor: pointer;
}

.journal-search button:hover { color: var(--red); border-color: var(--red); }

.journal-search-clear {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
  text-decoration: none;
}

.journal-search-clear:hover { color: var(--red); }

.readings-list .eyebrow {
  margin-bottom: var(--space-3);
}

.reading-rows {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--rule);
}

.reading-row {
  border-bottom: 1px solid var(--rule-soft);
}

.reading-row-link {
  display: block;
  padding: var(--space-4) 0;
  color: inherit;
  text-decoration: none;
  transition: background-color .15s ease;
}

.reading-row-link:hover {
  background: var(--rule-soft);
  padding-left: var(--space-3);
  padding-right: var(--space-3);
}

.row-meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 var(--space-2);
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.row-meta .row-type { color: var(--red); }
.row-meta .row-sep  { color: var(--fg-faint); }
.row-meta .row-date { color: var(--fg-muted); }

.row-meta .row-id {
  margin-left: auto;
  color: var(--fg-faint);
  font-size: 10px;
}

.row-question {
  font-family: var(--serif);
  font-size: 20px;
  line-height: 1.35;
  color: var(--fg);
  margin: 0;
  font-variation-settings: "WONK" 1;
}

.row-quote {
  color: var(--red);
  font-style: normal;
}

.row-tags {
  display: flex;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
}

.row-tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  border: 1px solid var(--rule);
  padding: 2px 6px;
}

.row-tag-synth {
  color: var(--red);
  border-color: var(--red);
}

.readings-empty {
  padding: var(--space-5) 0;
  font-family: var(--serif);
  font-size: 17px;
  color: var(--fg-muted);
}

.readings-empty a {
  color: var(--red);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}

@media (max-width: 700px) {
  .account-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .recurrence-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .account-facts .fact { grid-template-columns: 1fr; gap: var(--space-1); }
  .row-meta .row-id { margin-left: 0; }
  .row-question { font-size: 18px; }
}

/* --- Admin: /admin/users page ----------------------------------------
   Editorial reuse of the form-shell layout for the user-management
   page. Single-column page with a table at the top and an "add user"
   form below; per-row reset/delete actions inline. */

.admin-shell {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-6) var(--space-7);
  text-align: left;
}

.admin-shell .display { margin: var(--space-2) 0 var(--space-7); }
.admin-shell .lede {
  font-size: 18px;
  line-height: 1.5;
  color: var(--fg-muted);
  font-family: var(--serif);
  margin-bottom: var(--space-7);
}

.user-list { margin-bottom: var(--space-7); }

.user-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--serif);
  font-size: 17px;
  border-top: 1px solid var(--rule);
}

.user-table thead th {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  font-weight: normal;
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--rule);
}

.user-table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
}

.user-table .user-name {
  font-family: var(--serif);
  font-size: 18px;
  color: var(--fg);
}

.user-table .self-tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-left: var(--space-2);
}

.user-table .user-meta {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
  white-space: nowrap;
}

.role-badge {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--red);
  border: 1px solid var(--red);
  padding: 2px 6px;
}

/* Per-row role controls: inline select + Set button.  Reused for
   the User / Elite / Admin tier dropdown on the admin users page. */
.user-table .user-role {
  white-space: nowrap;
}

.role-form {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

.role-select {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg);
  background: var(--card-bg);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 4px 8px;
  cursor: pointer;
}
.role-select:focus {
  outline: 0;
  border-color: var(--red);
}

.role-set-btn {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 4px 10px;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.role-set-btn:hover {
  color: var(--red);
  border-color: var(--red);
}

.user-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-end;
}

.row-action {
  background: none;
  border: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  cursor: pointer;
  text-decoration: none;
}
.row-action:hover { color: var(--red); }
.row-action-danger { color: var(--red); opacity: 0.85; }
.row-action-danger:hover { color: var(--red); opacity: 1; }

.row-disclosure {
  display: inline-block;
}
.row-disclosure > summary {
  list-style: none;
  cursor: pointer;
}
.row-disclosure > summary::-webkit-details-marker { display: none; }

.reset-form {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.reset-form input[type="text"] {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--serif);
  font-size: 15px;
  padding: var(--space-2) 0;
  color: var(--fg);
  outline: none;
  min-width: 220px;
}
.reset-form input[type="text"]:focus { border-bottom-color: var(--red); }
.reset-btn {
  background: var(--fg);
  color: var(--bg);
  border: 0;
  padding: 0 var(--space-3);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
}

.delete-form { margin: 0; }

.invite-admin {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: var(--space-6) 0;
  margin-bottom: var(--space-7);
}
.invite-create-form { max-width: 520px; }
.invite-caption { margin: var(--space-4) 0 var(--space-6); }
.new-invite-link {
  background: var(--card-bg);
  border: 1px solid var(--rule);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
}
.new-invite-link > label {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: var(--space-2);
}
.invite-copy-row { display: flex; gap: var(--space-2); }
.invite-copy-row input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  border-bottom: 1px solid var(--rule);
  background: transparent;
  color: var(--fg);
  font-family: var(--mono);
  font-size: 12px;
  padding: var(--space-2) 0;
}
.invite-table { margin-top: var(--space-4); }

.user-create {
  border-top: 1px solid var(--rule);
  padding-top: var(--space-6);
}

.form-invite-ready {
  border-left: 2px solid var(--red);
  padding: var(--space-3) var(--space-4);
  margin: 0;
  color: var(--fg);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .08em;
}
.signup-mail-help { margin: var(--space-5) 0; }
.signup-start-over { margin-top: var(--space-5); }

@media (max-width: 700px) {
  .user-table .col-created { display: none; }
  .user-table .user-meta { display: none; }
  .user-actions { align-items: stretch; }
  .reset-form { flex-direction: column; }
  .reset-form input[type="text"] { min-width: 0; }
  .invite-copy-row { flex-direction: column; align-items: stretch; }
  /* Even with columns hidden the role/actions cells can outgrow a
     phone; scroll the table inside its own strip, not the page. */
  .user-table {
    display: block;
    overflow-x: auto;
  }
}

/* --- Opening of the Key reading --- */

.ootk-section {
  border-bottom: 1px solid var(--rule);
}

.ootk-section .section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--space-4) var(--space-5) var(--space-2);
}

.ootk-section .sig-line {
  padding: 0 var(--space-5) var(--space-4);
  font-family: var(--serif);
  font-size: 20px;
}

.ootk-section .sig-line .red { color: var(--red); }

.ootk-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--space-5);
  padding: var(--space-3) var(--space-5) var(--space-5);
  align-items: start;
}

@media (max-width: 1080px) {
  .ootk-grid { grid-template-columns: 1fr; }
}

/* --- Wheel SVG --- */

.wheel {
  width: 100%;
  height: auto;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  /* Cap the wheel so it doesn't dominate on wide screens, and give it
     a centred resting place inside whatever column it sits in. */
  max-width: 560px;
  max-height: 560px;
  display: block;
  margin: 0 auto;
}

.wheel .ring-outer {
  fill: none;
  stroke: var(--fg);
  stroke-width: 0.6;
}

.wheel .ring-inner {
  fill: none;
  stroke: var(--rule);
  stroke-width: 0.4;
  stroke-dasharray: 1 3;
}

/* Pile-as-wheel: small card-shaped placeholder at each position. */
.wheel .placeholder {
  fill: var(--card-bg);
  stroke: var(--rule);
  stroke-width: 0.6;
}

.wheel .placeholder.chain {
  stroke: var(--fg-muted);
  stroke-width: 1.2;
}

.wheel .placeholder.sig {
  fill: var(--red);
  stroke: var(--red);
  stroke-width: 1.4;
}

/* Dots are still used by the house wheel (12 markers around the rim). */
.wheel .dot {
  fill: var(--fg);
  r: 2.5;
}

.wheel .dot.muted { fill: var(--fg-muted); r: 1.8; }
.wheel .dot.sig   { fill: var(--red); r: 6; }

.wheel .label {
  fill: var(--fg-muted);
}

.wheel .label.sig    { fill: var(--fg); font-weight: 600; }
.wheel .label.chain  { fill: var(--fg); }

.wheel .chain-line {
  stroke: var(--red);
  stroke-width: 0.6;
  stroke-dasharray: 2 3;
  fill: none;
}

/* --- House windmill (Second Operation) --- */

.wheel.house-windmill .ring-outer { display: none; }

.wheel .spoke {
  fill: var(--rule-soft);
  stroke: var(--rule);
  stroke-width: 0.6;
  stroke-linejoin: round;
}

.wheel .spoke.sig {
  fill: var(--red);
  stroke: var(--red);
  stroke-width: 0.6;
}

.wheel .spoke-roman {
  fill: var(--fg);
  font-family: var(--serif);
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
}

.wheel .spoke-keyword {
  fill: var(--fg-muted);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.wheel .spoke-label.sig .spoke-roman,
.wheel .spoke-label.sig .spoke-keyword {
  fill: var(--red);
}

/* Zodiac symbol seated inside each sector — dark on the soft sectors,
   light on the significator's red sector. */
.wheel .spoke-sym {
  fill: var(--fg);
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "Arial Unicode MS", serif;
  font-size: 30px;
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  font-variation-settings: normal;
  font-variant-emoji: text;
}

.wheel .spoke-sym.sig {
  fill: var(--bg);
}

.wheel .you-dot {
  fill: var(--fg);
}

.wheel .you-label {
  fill: var(--fg-muted);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* --- Trine wheel (Third Operation) --- */

.wheel.trine-wheel .ring-outer { stroke-width: 0.6; }

.wheel .trine-tick {
  stroke: var(--fg-muted);
  stroke-width: 0.6;
  opacity: 0.5;
}

.wheel .trine-poly {
  fill: var(--red);
  fill-opacity: 0.08;
  stroke: var(--fg-muted);
  stroke-width: 0.5;
  stroke-dasharray: 1 3;
}

.wheel .trine-poly.muted {
  fill: none;
  stroke: var(--rule);
  stroke-opacity: 0.7;
}

.wheel .trine-poly.sig {
  fill: var(--red);
  fill-opacity: 0.12;
  stroke: var(--red);
  stroke-width: 1.2;
  stroke-dasharray: none;
}

.wheel .trine-label {
  fill: var(--fg-muted);
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "Arial Unicode MS", serif;
  font-size: 22px;
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  font-variation-settings: normal;
  font-variant-emoji: text;
}

.wheel .trine-label.sig {
  fill: var(--red);
  font-weight: 500;
}

.wheel .trine-vertex.sig {
  fill: var(--red);
  stroke: var(--bg);
  stroke-width: 1;
}

.wheel .center-elem-glyph {
  fill: none;
  stroke: var(--red);
  stroke-width: 1;
  stroke-linejoin: round;
}

.wheel .center-name.trine-center {
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "Arial Unicode MS", serif;
  font-style: normal;
  font-size: 22px;
  letter-spacing: 0.1em;
  font-variation-settings: normal;
  font-variant-emoji: text;
}

/* --- Decan wheel (Fourth Operation) --- */
.wheel.decan-wheel .ring-outer { stroke-width: 0.5; }

/* Solid red chain lines on the decan wheel (the First-Op wheel keeps
   its dotted default). */
.wheel.decan-wheel .chain-line {
  stroke-dasharray: none;
  stroke-width: 0.9;
}

.wheel .decan-tick {
  stroke: var(--fg-muted);
  stroke-width: 0.6;
  opacity: 0.55;
}

.wheel .sign-abbr {
  fill: var(--fg-muted);
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "Arial Unicode MS", serif;
  font-size: 18px;
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  font-variation-settings: normal;
  font-variant-emoji: text;
}

.wheel .chain-station .station-dot {
  fill: var(--red);
  stroke: var(--bg);
  stroke-width: 1;
}

.wheel .chain-station .station-num {
  fill: var(--bg);
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

.wheel .center-pile-of {
  fill: var(--fg-muted);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
}

.wheel .center-name {
  fill: var(--fg);
  font-family: var(--serif);
  font-size: 30px;
  letter-spacing: 0;
  text-transform: none;
}

.wheel .center-meta {
  fill: var(--red);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.22em;
}

/* House wheel additions */
.wheel .sig-sector {
  fill: var(--red);
  fill-opacity: 0.10;
  stroke: var(--red);
  stroke-width: 0.6;
}

.wheel .divider {
  stroke: var(--rule);
  stroke-width: 0.4;
}

.wheel .label.house {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
}

/* --- Four-pile preview (First Operation opener) --- */

.four-piles-block {
  border-top: 1px solid var(--rule);
  padding: var(--space-4) var(--space-5) var(--space-5);
}

.four-piles-block .label { display: block; margin-bottom: var(--space-4); }

.four-piles-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-5);
}

.pile-preview {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.pile-preview .pile-suit {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.pile-preview.contains-sig .pile-suit .suit-name { color: var(--red); }

.pile-preview .pile-keywords {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.4;
  color: var(--fg-muted);
  margin: 0;
}

.pile-preview .pile-meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.pile-preview .preview-frame {
  aspect-ratio: 5 / 8;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-3);
  font-family: var(--serif);
  font-size: 15px;
  color: var(--fg);
  line-height: 1.25;
  position: relative;
}

.pile-preview.contains-sig .preview-frame {
  border-color: var(--red);
  border-width: 1.5px;
}

.pile-preview .top-of {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  position: absolute;
  top: var(--space-2);
  left: 0; right: 0;
}

@media (max-width: 900px) {
  .four-piles-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- The Twelve Houses panel --- */

.houses-block {
  border-top: 1px solid var(--rule);
  padding: var(--space-6);
}

.houses-block .eyebrow { margin-bottom: var(--space-4); }

.houses-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-7);
}

@media (max-width: 900px) {
  .houses-row { grid-template-columns: 1fr; gap: var(--space-5); }
}

.houses-rubric {
  font-family: var(--serif);
  color: var(--fg-muted);
  margin: 0 0 var(--space-3);
  font-size: 15px;
}

.house-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--rule-soft);
}

.house-list li {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--rule-soft);
}

.house-list .roman {
  font-family: var(--serif);
  font-size: 28px;
  line-height: 1;
  color: var(--fg-muted);
  align-self: start;
}

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

.house-list .house-head {
  margin: 0;
  font-family: var(--serif);
  font-size: 16px;
}

.house-list .house-head .sign {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.house-list .house-body {
  margin: 0;
  font-family: var(--serif);
  color: var(--fg-muted);
  font-size: 14px;
  line-height: 1.4;
}

.house-list li.is-sig .roman      { color: var(--red); }
.house-list li.is-sig .house-head { color: var(--fg); }
.house-list li.is-sig .house-head .sign { color: var(--red); }
.house-list li.is-sig .house-body { color: var(--fg); }

/* Single-house panel: the significator's house / sign / decan /
   sephira / pile card in the right column of each operation page. */
.single-house {
  display: grid;
  /* Auto-size the Roman column so wide numerals like VIII don't crash
     into the text. minmax keeps a sensible minimum so narrow ones (I,
     V, X) still feel like a column rather than crowding the text. */
  grid-template-columns: minmax(64px, auto) 1fr;
  gap: var(--space-5);
  align-items: start;
  margin-top: var(--space-3);
  padding: var(--space-4) 0 0;
  border-top: 1px solid var(--rule);
}

.single-house .roman {
  font-family: var(--serif);
  font-size: 56px;
  font-weight: 400;
  line-height: 0.9;
  color: var(--red);
  font-variation-settings: "WONK" 1;
}

/* Variant: a Hebrew letter (with its pronunciation underneath) in
   place of the Roman numeral.  Used by the "Your pile" panel on the
   First Operation (Expanded Pile).  The browser substitutes a system
   Hebrew font for the letter because Fraunces doesn't ship Hebrew
   glyphs; the pronunciation underneath uses the same mono-caps style
   as the meta lines elsewhere in the panel. */
.single-house .roman.roman-hebrew {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  font-variation-settings: normal;
  line-height: 1;
}

.single-house .roman-hebrew .hebrew-char {
  font-family: var(--serif), "SBL Hebrew", "Frank Ruhl Libre",
               "Times New Roman", serif;
  font-size: 60px;
  font-weight: 400;
  line-height: 0.95;
  color: var(--red);
}

.single-house .roman-hebrew .hebrew-name {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* Variant: an elemental glyph in place of the Roman numeral.
   Used by the "Your sign" panel on the Third Operation. */
.single-house .roman-glyph {
  font-family: inherit;          /* not text — drop the WONK setting */
  font-variation-settings: normal;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  color: var(--red);
}

.single-house .roman-glyph img {
  width: 100%;
  height: 100%;
  display: block;
}

.single-house .text { display: flex; flex-direction: column; gap: var(--space-2); }

.single-house .head {
  margin: 0;
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 500;
  line-height: 1.1;
  font-variation-settings: "WONK" 1;
}

.single-house .head .sign {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin-left: var(--space-2);
  font-variation-settings: normal;
}

.single-house .body {
  margin: 0;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.45;
  color: var(--fg);
}

.single-house .rubric {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* --- Horizontal pile strip --- */

.pile-strip-wrap {
  border-top: 1px solid var(--rule);
  padding: var(--space-5) var(--space-6) var(--space-6);
}

.pile-strip-wrap .label {
  margin-bottom: var(--space-3);
  display: block;
}

.pile-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.pile-card {
  flex: 0 0 124px;
  aspect-ratio: 5 / 8;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  position: relative;
  text-align: center;
}

.pile-card .pile-pos {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
  text-transform: uppercase;
}

.pile-card .pile-name {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: 13.5px;
  line-height: 1.25;
  color: var(--fg-muted);
  padding: var(--space-2) 0;
  hyphens: auto;
}

/* Foot row of a placeholder card: small element/major glyph centred,
   with an optional "You" / "#N" label sitting next to it.  Used by
   both .pile-card (pile-strip) and .chain-card (chain-strip), so the
   rule is intentionally not scoped to a parent. */
.pile-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 18px;
  margin-top: var(--space-2);
}

.pile-glyph {
  width: 14px;
  height: 14px;
  opacity: 0.65;
  display: block;
}

.pile-foot-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--red);
  text-transform: uppercase;
}

.pile-card.sig .pile-glyph,
.pile-card.chain .pile-glyph,
.chain-card.sig .pile-glyph { opacity: 0.9; }

.pile-card.sig {
  border-color: var(--red);
  border-width: 1.5px;
}

.pile-card.sig .pile-name {
  color: var(--fg);
  font-weight: 500;
}

.pile-card.chain {
  border-color: var(--fg-muted);
}

.pile-card.chain .pile-name {
  color: var(--fg);
}

/* --- Chain as a strip of placeholder cards ---
   Visually identical in shape to the pile-strip cards so card art
   added later will read the same on both. */

.chain-strip-wrap {
  margin-top: var(--space-3);
}

.chain-strip-wrap > .label {
  display: block;
  margin-bottom: var(--space-3);
}

.chain-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Chain card mirrors .pile-card exactly so future card art reads the
   same on both.  The only extra elements are the count (top-right
   of the head row) and, on page 5, the decan label above the foot. */
.chain-card {
  flex: 0 0 124px;          /* same fixed width as .pile-card */
  aspect-ratio: 5 / 8;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  position: relative;
  text-align: center;
}

.chain-card.sig {
  border-color: var(--red);
  border-width: 1.5px;
}

/* Tooltip-bearing cards (the OOTK strips and Page 1 previews) lift
   slightly on hover — the three-card / Celtic Cross treatment — so
   the card whose keywords are showing reads as picked up.  Transform
   doesn't disturb flex flow, so neighbours hold their places. */
.pile-card[data-tip-body],
.chain-card[data-tip-body],
.pile-preview .preview-frame[data-tip-body] {
  transition: transform .18s ease, box-shadow .18s ease;
}
.pile-card[data-tip-body]:hover,
.chain-card[data-tip-body]:hover,
.pile-preview .preview-frame[data-tip-body]:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 18px rgba(92, 22, 15, 0.18);
}

.chain-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.chain-card .chain-pos {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
  text-transform: uppercase;
}

.chain-card .chain-count {
  font-family: var(--serif);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  color: var(--red);
  font-variation-settings: normal;
}

.chain-card .chain-name {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: 13.5px;
  line-height: 1.25;
  color: var(--fg-muted);
  padding: var(--space-2) 0;
  hyphens: auto;
}

.chain-card.sig .chain-name { color: var(--fg); }

.chain-card .chain-decan {
  margin: 0;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* --- Marseille card art ----------------------------------------------
   When a placeholder has the actual artwork available (`.has-art`),
   `.card-art` is absolute-positioned to fill the card. The artwork's
   ~1:2 ratio sits inside a 5:8 placeholder via `object-fit: contain`,
   leaving thin parchment matting at the sides. The card's text content
   is hidden; functional markers (pile position, chain order/count,
   decan label, sig/partner tags) turn into small dark-pill overlays at
   the corners. */

.card-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--card-bg);
  display: block;
  z-index: 0;
}

.pile-card.has-art,
.chain-card.has-art {
  padding: 0;
  overflow: hidden;
}

.gt-card.has-art .gt-frame,
.pile-preview .preview-frame.has-art,
.card-frame.has-art {
  padding: 0;
  overflow: hidden;
  position: relative;
}

/* Hide the now-redundant text — the artwork carries it. */
.pile-card.has-art .pile-name,
.chain-card.has-art .chain-name,
.gt-card.has-art .gt-frame .gt-headline,
.gt-card.has-art .gt-frame .gt-subtitle,
.pile-preview .preview-frame.has-art .preview-name,
.has-art .pile-glyph {
  display: none;
}

/* Common pill style for overlay labels. */
.pile-card.has-art .pile-pos,
.pile-card.has-art .pile-foot-label,
.chain-card.has-art .chain-pos,
.chain-card.has-art .chain-count,
.chain-card.has-art .chain-decan,
.pile-preview .preview-frame.has-art .top-of {
  background: rgba(20, 19, 15, 0.78);
  color: #f1e8d0;
  padding: 2px 5px;
  border-radius: 2px;
  line-height: 1.2;
}

/* Pile-card overlays: position number top-left, sig/chain badge top-right. */
.pile-card.has-art .pile-pos {
  position: absolute;
  top: 4px;
  left: 4px;
  z-index: 2;
}

.pile-card.has-art .pile-foot {
  position: absolute;
  top: 4px;
  right: 4px;
  z-index: 2;
  margin-top: 0;
  min-height: 0;
  gap: 0;
}

.pile-card.has-art .pile-foot-label {
  font-size: 9px;
  letter-spacing: 0.18em;
}

/* Chain-card overlays: #N + count across the top, decan label centred
   at the bottom (Fourth Op only). */
.chain-card.has-art .chain-card-head {
  position: absolute;
  top: 4px;
  left: 4px;
  right: 4px;
  z-index: 2;
  margin: 0;
}

.chain-card.has-art .chain-decan {
  position: absolute;
  bottom: 4px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  white-space: nowrap;
}

/* The glyph foot is already hidden via display:none on .pile-glyph;
   the empty .pile-foot would otherwise reserve a row — collapse it. */
.chain-card.has-art .pile-foot {
  display: none;
}

/* Page-1 preview frame: "Top of pile" label stays as a tiny banner up top. */
.pile-preview .preview-frame.has-art .top-of {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  z-index: 2;
}

/* GT card-art and knight handling moved into the Grand Tableau block
   below (the new overlay-first design treats the frame mat as a key
   surface, so its has-art behaviour diverges from other surfaces). */

/* --- Chain side panel (legacy chain-list — kept for reference) --- */

.chain-list {
  border: 1px solid var(--rule);
  background: var(--card-bg);
  margin-top: var(--space-4);
}

.chain-row {
  display: grid;
  grid-template-columns: 56px 70px 1fr;
  align-items: baseline;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--rule);
}
.chain-row:last-child { border-bottom: 0; }

.chain-row .num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--fg-muted);
  text-transform: uppercase;
}

.chain-row .count {
  font-family: var(--serif);
  font-size: 28px;
  color: var(--red);
}

.chain-row .name {
  font-family: var(--serif);
  font-size: 19px;
}

.chain-row .name em {
  color: var(--fg-muted);
}

.closure-callout {
  background: #1a1916;
  color: var(--fg);
  padding: var(--space-4) var(--space-5);
  margin-top: var(--space-3);
}

body.theme-parchment .closure-callout {
  background: #1a1815;
  color: #f1e8d0;
}

.closure-callout .label { color: var(--fg-muted); margin-bottom: var(--space-2); display: block; }
.closure-callout .copy { font-family: var(--serif); font-size: 16px; }

/* --- Pair ledger --- */

.pair-ledger {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  /* stretch (not baseline) so every cell in a row fills the row
     height — keeps the bottom rules continuous when text wraps. */
  align-items: stretch;
  font-family: var(--serif);
  font-size: 17px;
  border-top: 1px solid var(--rule);
}

.pair-ledger .pair-row,
.pair-ledger .lone-row {
  display: contents;
}

.pair-ledger .pair-row > *,
.pair-ledger .lone-row > * {
  padding: var(--space-3) var(--space-4);
}

.pair-ledger .pair-row > * {
  border-bottom: 1px solid var(--rule-soft);
}

.pair-ledger .left  { text-align: right; color: var(--fg-muted); }
.pair-ledger .sep   {
  color: var(--red);
  text-align: center;
  border-left: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
}
.pair-ledger .right { text-align: left;  color: var(--fg); }

/* The lone card spans the full ledger width, so its (often long) text
   does not inflate the narrow centre divider column. */
.pair-ledger .lone-row .center {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--fg);
}

/* Pairs ledger tucked under an operation's figure (left column, not
   full-width) — tightened so it fits the narrower measure. */
.figure-pairs { margin-top: var(--space-4); }

.figure-pairs .pair-ledger { font-size: 15px; }

.figure-pairs .pair-ledger .pair-row > *,
.figure-pairs .pair-ledger .lone-row > * {
  padding: var(--space-2) var(--space-3);
}

/* =============================================================
   Grand Tableau — Lenormand 9×4 field with overlay-rendered
   relationships.
   ─────────────────────────────────────────────────────────────
   Three stacked layers inside `.field-wrap`:
     z:1  `.gt-wash`     — 3×3 wash region (positioned by JS)
     z:2  `.grand-tableau` — the 9-col card grid
     z:3  `.gt-overlay`  — SVG: row / column / diagonal hairlines,
                            knight L-paths, sig origin node
   The overlay's geometry is measured from the cards at runtime so
   it stays correct across responsive reflow.  The only per-card
   relationship emphases kept on the cards themselves are the sig
   frame (solid red), the partner frame (dashed red), and the small
   knight elbow SVG embedded in each knighted card's frame.
   ============================================================= */

/* Overlay knobs — exposed as custom properties so tweaks dock in
   the prototype could drive them live.  Final values baked here. */
.gt-lenormand {
  --gt-line-w:  1.4px;
  --gt-line-op: 0.62;
  --gt-wash:    rgba(161, 52, 52, 0.07);
  --gt-blood:   var(--red);
  --gt-card-mat: rgba(241, 232, 208, 1);
}

.field-wrap {
  position: relative;
  padding: var(--space-3) var(--space-4) var(--space-4);
}

.grand-tableau {
  /* Fit the whole 9 × 4 field in the viewport — the user must be
     able to take the field in at a glance, not scroll it.
     Card width is the smaller of:
       (a) what fits 4 rows vertically in (100vh - chrome budget),
           given each card's full height is its frame (W × 86/62)
           plus ~50px of label rows and ~14px of inter-row gap;
           total per row ≈ 1.387W + 64, four rows ≈ 5.55W + 256.
       (b) what fits 9 columns horizontally in the available width
           (with column gaps subtracted).
     Clamped to a 44 px floor (below this cards stop being legible
     and we fall through to the 720 px mobile rule) and a 108 px
     ceiling (so the field doesn't bloat on huge displays). */
  --gt-card-w: clamp(
    44px,
    min(
      calc((100vh - 400px) / 5.55),
      calc((100vw - 140px) / 9 - 14px)
    ),
    108px
  );
  display: grid;
  grid-template-columns: repeat(9, var(--gt-card-w));
  justify-content: center;
  gap: 14px 14px;
  position: relative;
  z-index: 2;
}

.gt-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 7px;
  cursor: default;
}

.gt-pos {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  height: 22px;
}

.gt-pos-num {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--fg-faint);
}

.gt-pos-house {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.gt-frame {
  position: relative;
  aspect-ratio: 62 / 86;
  border-radius: 2px;
  background: var(--gt-card-mat, var(--card-bg));
  padding: 6px;
  border: 1px solid var(--rule-soft);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.5) inset,
    0 2px 7px rgba(42, 32, 23, 0.10);
  transition:
    box-shadow .18s ease,
    border-color .18s ease,
    transform .18s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
}

/* Card text (shown when no art). */
.gt-frame .gt-headline {
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.1;
  margin: 0;
  color: var(--fg);
  font-variation-settings: "WONK" 1;
}

.gt-frame .gt-subtitle {
  font-family: var(--serif);
  font-size: 11px;
  line-height: 1.2;
  margin: 0;
  color: var(--fg-muted);
}

/* Art card override — preserve the 6px mat (the prototype's choice:
   a small parchment border around the art reads more "instrument"
   than edge-to-edge image).  This overrides the global
   `.gt-card.has-art .gt-frame { padding: 0 }` rule above. */
.gt-card.has-art .gt-frame {
  padding: 6px;
  overflow: hidden;
}
.gt-card.has-art .gt-frame .card-art {
  position: absolute;
  inset: 6px;
  width: calc(100% - 12px);
  height: calc(100% - 12px);
  object-fit: cover;
  border-radius: 1px;
  background: var(--card-bg);
  z-index: 0;
}
/* Text already hidden under art by the global has-art rule. */

/* The only per-card relationship emphases kept on the cards. */
.gt-card.sig .gt-frame {
  border: 2px solid var(--red);
  box-shadow:
    0 0 0 4px rgba(161, 52, 52, 0.08),
    0 3px 12px rgba(92, 22, 15, 0.22);
}
.gt-card.partner .gt-frame {
  border: 1.5px dashed var(--red);
}

/* "You" / "Partner" mono caption below the frame.  Empty slot for
   the rest of the cards keeps the column rhythm even. */
.gt-card .gt-mark {
  text-align: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--red);
  margin: 1px 0 0;
  height: 14px;
}

/* Hover affordance on any non-sig non-partner card. */
.gt-card:not(.sig):not(.partner):hover .gt-frame {
  border-color: var(--fg-faint);
  box-shadow: 0 3px 12px rgba(42, 32, 23, 0.18);
  transform: translateY(-1px);
}

/* Knight elbow — the L of the leap, drawn in the same hairline as
   the overlay lines.  Lives inside the frame so it sits on top of
   the card art and the global border. */
.gt-knight {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 4;
  width: 18px;
  height: 18px;
  display: block;
  transform-origin: 80% 30%;
  opacity: 0.92;
  filter:
    drop-shadow(0 0 2px var(--gt-card-mat))
    drop-shadow(0 0 2px var(--gt-card-mat));
  transition: opacity .18s ease, transform .18s ease;
  pointer-events: none;
}
.gt-knight path { stroke: var(--red); }
.gt-knight circle { fill: var(--red); }

/* ── Overlay layer ────────────────────────────────────────── */

.gt-wash {
  position: absolute;
  z-index: 1;
  border-radius: 5px;
  background: var(--gt-wash);
  border: 1px solid rgba(161, 52, 52, 0.22);
  box-shadow: 0 0 0 1px rgba(246, 240, 224, 0.4) inset;
  pointer-events: none;
  opacity: 1;
  transition: opacity .22s ease;
}

.gt-overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  overflow: visible;
}
.gt-overlay path,
.gt-overlay line,
.gt-overlay circle {
  transition: opacity .22s ease, stroke-width .22s ease;
}

.ln {
  stroke: var(--red);
  fill: none;
  stroke-linecap: round;
}
.ln-row,
.ln-col {
  stroke-width: var(--gt-line-w);
  opacity: var(--gt-line-op);
}
.ln-diag {
  stroke-width: var(--gt-line-w);
  opacity: var(--gt-line-op);
  stroke-dasharray: 1.5 6;
}
/* Knight L-paths are hidden until isolated. */
.ln-knight {
  stroke-width: 1.1px;
  opacity: 0;
  stroke-dasharray: 2 5;
}

.node-ring {
  fill: none;
  stroke: var(--red);
  stroke-width: 1.3px;
}
.sig-node { fill: var(--red); }
.sig-halo {
  fill: none;
  stroke: var(--red);
  stroke-width: 1.2px;
  opacity: 0.5;
}

/* ── Isolation states ─────────────────────────────────────── */

.field-wrap.isolating .ln-row,
.field-wrap.isolating .ln-col,
.field-wrap.isolating .ln-diag,
.field-wrap.isolating .term { opacity: 0.08; }
.field-wrap.isolating .gt-wash { opacity: 0.18; }
.field-wrap.isolating .gt-knight { opacity: 0.18; }

.ln.active { opacity: 0.95 !important; stroke-width: 2px; }
.ln-diag.active {
  opacity: 0.95 !important;
  stroke-width: 1.8px;
  stroke-dasharray: none;
}
.ln-knight.active { opacity: 0.85 !important; }
.term.active { opacity: 1 !important; }
.gt-knight.active { opacity: 1 !important; transform: scale(1.18); }
.gt-wash.active { opacity: 1 !important; }

/* Layer toggles from the legend. */
.field-wrap.layer-off-row .ln-row,
.field-wrap.layer-off-col .ln-col,
.field-wrap.layer-off-diag .ln-diag,
.field-wrap.layer-off-knight .ln-knight,
.field-wrap.layer-off-knight .gt-knight,
.field-wrap.layer-off-r3 .gt-wash { display: none; }

/* ── Tooltip (follows the cursor on card hover) ─────────────
   Shared shell: .gt-tooltip carries house meanings on the Grand
   Tableau, .card-tooltip carries card keywords on the OOTK pages. */

.gt-tooltip,
.card-tooltip {
  position: fixed;
  z-index: 50;
  pointer-events: none;
  opacity: 0;
  background: var(--fg);
  color: var(--card-bg);
  font-family: var(--serif);
  font-size: 13px;
  padding: 7px 12px;
  border-radius: 3px;
  max-width: 280px;
  line-height: 1.4;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
  transition: opacity .14s ease;
  transform: translate(-50%, -115%);
}
.gt-tooltip .tt-name,
.card-tooltip .tt-name {
  font-family: var(--mono);
  font-style: normal;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(246, 240, 224, 0.6);
  display: block;
  margin-bottom: 2px;
}

/* ── Legend (real geometry samples + on/off toggle pills) ── */

.gt-legend {
  margin: 46px var(--space-5) 0;
}
.gt-legend > .eyebrow {
  display: block;
  margin: 0 0 16px;
}

.gt-legend .legend-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  align-items: stretch;
}

.gt-legend .leg-item {
  display: flex;
  align-items: center;
  gap: 11px;
  border: 1px solid var(--rule-soft);
  background: rgba(246, 240, 224, 0.45);
  border-radius: 3px;
  padding: 9px 14px 9px 11px;
  cursor: pointer;
  user-select: none;
  transition:
    border-color .16s ease,
    background .16s ease,
    opacity .16s ease;
}
.gt-legend .leg-item:hover {
  border-color: var(--fg-faint);
  background: rgba(246, 240, 224, 0.85);
}
.gt-legend .leg-item.off { opacity: 0.4; }

.gt-legend .leg-item .swatch {
  width: 34px;
  height: 24px;
  flex: none;
}

.gt-legend .leg-item .lab {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--fg-muted);
  white-space: nowrap;
}

.gt-legend .leg-item .toggle {
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: 0.14em;
  color: var(--fg-faint);
  text-transform: uppercase;
  border: 1px solid var(--rule);
  border-radius: 20px;
  padding: 2px 7px;
}
.gt-legend .leg-item.off .toggle {
  color: var(--red);
  border-color: rgba(161, 52, 52, 0.4);
}

.gt-legend .legend-hint {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin: 13px 0 0;
}

.gt-legend .gt-legend-note {
  font-family: var(--serif);
  font-size: 14.5px;
  color: var(--fg-muted);
  margin: 18px 0 0;
  max-width: 760px;
  line-height: 1.45;
}

/* Form hint (used on the GT input form). */
.form-hint {
  font-family: var(--serif);
  font-size: 13px;
  margin: var(--space-2) 0 0;
  line-height: 1.4;
}

/* ── Responsive fallback ──────────────────────────────────── */

/* On phones the viewport-aware sizing would clamp to 44 px and
   overflow horizontally (9 × 44 + gaps > narrow viewport).  Drop
   to 4 columns with scroll — readable cards, scrolled field is an
   acceptable trade at this size.  Overlay geometry recomputes from
   the DOM so the redraw is automatic. */
@media (max-width: 720px) {
  .grand-tableau {
    --gt-card-w: minmax(0, 1fr);
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-3);
  }
  .gt-frame .gt-headline { font-size: 18px; }
  .gt-frame .gt-subtitle { font-size: 12px; }
}

.gt-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: center;
}

.gt-card .gt-pos {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.gt-card .gt-frame {
  aspect-ratio: 5 / 8;
  width: 100%;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-3) var(--space-2);
  gap: var(--space-2);
  transition: border-color .15s ease;
}

.gt-card .gt-frame .gt-headline {
  font-family: var(--serif);
  font-size: 22px;
  font-weight: 500;
  line-height: 1;
  margin: 0;
  color: var(--fg);
  font-variation-settings: "WONK" 1;
}

.gt-card .gt-frame .gt-subtitle {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.2;
  margin: 0;
  color: var(--fg-muted);
}

.gt-card.sig .gt-frame {
  border-color: var(--red);
  border-width: 2px;
}
.gt-card.sig .gt-frame .gt-headline,
.gt-card.sig .gt-frame .gt-subtitle { color: var(--red); }

.gt-card.partner .gt-frame {
  border-color: var(--red);
  border-width: 1.5px;
  border-style: dashed;
}
.gt-card.partner .gt-frame .gt-headline { color: var(--red); }

/* Relationship highlights to the significator (mutually exclusive
   borders; closest relationship wins).  Sig / partner styles above
   take precedence over these. */

.gt-card.in-3x3 .gt-frame {
  border-color: var(--red);
  border-width: 1px;
  border-style: solid;
}

.gt-card.on-diagonal .gt-frame {
  border-color: var(--red);
  border-width: 1.5px;
  border-style: dotted;
}

.gt-card.on-row .gt-frame {
  border-top-color: var(--red);
  border-top-width: 2px;
  border-top-style: solid;
}

.gt-card.on-col .gt-frame {
  border-left-color: var(--red);
  border-left-width: 2px;
  border-left-style: solid;
}

/* Knight's-move glyph (additive, can combine with any border). */
.gt-card .gt-frame { position: relative; }

.gt-knight {
  position: absolute;
  top: 4px;
  right: 6px;
  font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols",
               "DejaVu Sans", serif;
  font-size: 16px;
  line-height: 1;
  color: var(--red);
  font-variation-settings: normal;
  pointer-events: none;
}

.gt-card .gt-mark {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0;
}

/* --- Form checkbox row (Grand Tableau) --- */

.form-row .checkbox-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--serif);
  font-size: 18px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fg);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--rule);
  cursor: pointer;
}

.form-row .checkbox-row input[type="checkbox"] {
  appearance: none;
  width: 16px;
  height: 16px;
  border: 1px solid var(--fg-muted);
  position: relative;
  cursor: pointer;
}

.form-row .checkbox-row input[type="checkbox"]:checked {
  border-color: var(--red);
}

.form-row .checkbox-row input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: var(--red);
}

.form-row .form-aside {
  font-size: 13px;
  margin-top: var(--space-2);
  display: block;
}

/* --- Tree of Life (Fifth Operation) --- */

.tree-of-life {
  width: 100%;
  height: auto;
  display: block;
  margin: var(--space-3) auto 0;
  max-width: 500px;
}

.tree-of-life .tree-path {
  stroke: var(--rule);
  stroke-width: 0.8;
  fill: none;
}

.tree-of-life .sephira .seph-circle {
  fill: var(--card-bg);
  stroke: var(--fg);
  stroke-width: 0.8;
}

.tree-of-life .sephira .seph-num {
  font-family: var(--serif);
  font-size: 28px;
  font-weight: 500;
  text-anchor: middle;
  dominant-baseline: central;
  fill: var(--fg);
  font-variation-settings: "WONK" 1;
}

.tree-of-life .sephira .seph-name {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-anchor: middle;
  text-transform: uppercase;
  fill: var(--fg-muted);
}

.tree-of-life .sephira.sig .seph-circle {
  fill: var(--red);
  stroke: var(--red);
  stroke-width: 2;
}

.tree-of-life .sephira.sig .seph-num {
  fill: var(--bg);
}

.tree-of-life .sephira.sig .seph-name {
  fill: var(--red);
}

/* --- Reflection page (Page 7) --- */

.reflection-section {
  padding-bottom: var(--space-5);
}

.reflection-title {
  font-family: var(--serif);
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.005em;
  margin: 0 var(--space-6) var(--space-6);
  max-width: 60ch;
  font-variation-settings: "WONK" 1;
}

.reflection-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  padding: 0 var(--space-6);
}

@media (max-width: 900px) {
  .reflection-grid { grid-template-columns: 1fr; }
}

.reflection-col {
  display: flex;
  flex-direction: column;
}

.reflection-line,
.reflection-notes {
  font-family: var(--serif);
  background: transparent;
  border: 1px solid var(--rule);
  padding: var(--space-4) var(--space-5);
  color: var(--fg);
  resize: vertical;
  width: 100%;
  margin-top: var(--space-3);
  outline: none;
  transition: border-color .15s ease;
}

.reflection-line:focus,
.reflection-notes:focus,
.stopper-picker:focus { border-color: var(--red); }

.reflection-line {
  font-size: 22px;
  line-height: 1.35;
  min-height: 110px;
  font-variation-settings: "WONK" 1;
}

.reflection-line::placeholder {
  color: var(--fg-faint);
}

.reflection-notes {
  font-size: 16px;
  line-height: 1.55;
  min-height: 320px;
}

.reflection-notes::placeholder {
  color: var(--fg-faint);
}

.reflection-caption {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: var(--space-3) 0 0;
}

/* --- "The line that stayed" picker (Page 7) ---
   A scrollable radio-list of sentences pulled from the OOTK page
   reflections (1-6). Each option shows the sentence in serif
   with a small "page N" tag at the right; selecting one writes its
   text into reflection.line via the autosave form. */

.line-picker {
  margin-top: var(--space-3);
  border: 1px solid var(--rule);
  padding: 0 var(--space-4);
  max-height: 360px;
  overflow-y: auto;
}

.line-option {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--rule-soft);
  cursor: pointer;
}

.line-option:last-child { border-bottom: 0; }

.line-option input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  width: 14px;
  height: 14px;
  min-width: 14px;
  min-height: 14px;
  flex: 0 0 14px;
  margin: 0;
  padding: 0;
  border: 1px solid var(--fg-muted);
  border-radius: 50%;
  display: inline-block;
  position: relative;
  cursor: pointer;
}

.line-option input[type="radio"]:checked {
  border-color: var(--red);
}

.line-option input[type="radio"]:checked::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: var(--red);
  border-radius: 50%;
}

.line-option .line-text {
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.4;
  color: var(--fg-muted);
}

.line-option:has(input:checked) .line-text {
  color: var(--fg);
}

.line-option .line-page {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  white-space: nowrap;
}

.line-option-none .line-text {
  font-style: normal;
  color: var(--fg-faint);
}

.line-empty {
  margin-top: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: 1px dashed var(--rule);
  font-family: var(--serif);
  font-size: 16px;
  color: var(--fg-muted);
}

/* The "card that stopped you" panel. */
.reflection-stopper {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  border: 1px solid var(--rule);
  padding: var(--space-4) var(--space-5);
  margin-top: var(--space-3);
  background: var(--card-bg);
  position: relative;
}

.stopper-glyph {
  width: 28px;
  height: 28px;
  opacity: 0.85;
  flex-shrink: 0;
}

.stopper-text {
  flex: 1;
  min-width: 0;
}

.stopper-text .stopper-headline {
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  margin: 0;
  font-variation-settings: "WONK" 1;
}

.stopper-text .stopper-subtitle {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--fg-muted);
  margin: var(--space-2) 0 0;
}

.stopper-empty {
  flex: 1;
  font-family: var(--serif);
  color: var(--fg-muted);
  font-size: 16px;
}

.stopper-actions {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

.stopper-pick-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  pointer-events: none;
}

/* The native <select> sits invisibly over the label so a click on
   "Choose" opens the dropdown. */
.stopper-picker {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  width: 100%;
  height: 100%;
  font-family: inherit;
  font-size: inherit;
}

/* --- Reflection footer (filed status + actions) --- */

.reflection-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-6);
  margin-top: var(--space-6);
  border-top: 1px solid var(--rule);
  gap: var(--space-4);
  flex-wrap: wrap;
}

.filed-status {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0;
}

.filed-status .reading-no { color: var(--fg); }
.filed-status .filed-sep  { margin: 0 var(--space-2); }
.filed-status .save-status { color: var(--fg-muted); }

.reflection-actions {
  display: flex;
  gap: var(--space-3);
}

.btn {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: var(--space-3) var(--space-5);
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
  border: 1px solid var(--rule);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.btn.btn-outline {
  color: var(--fg);
  background: transparent;
}
.btn.btn-outline:hover {
  border-color: var(--red);
  color: var(--red);
}

.btn.btn-filled {
  color: var(--bg);
  background: #1a1816;
  border-color: #1a1816;
}
.btn.btn-filled:hover {
  background: var(--red);
  border-color: var(--red);
}

/* --- Paginated page navigation (OOTK reading pages) --- */

.page-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.page-nav-cell.start  { justify-self: start; }
.page-nav-cell.center { justify-self: center; }
.page-nav-cell.end    { justify-self: end; }

.page-nav a {
  text-decoration: none;
  color: var(--fg-muted);
  transition: color .15s ease;
}

.page-nav a:hover { color: var(--red); }

.page-nav .page-nav-next { color: var(--fg); }
.page-nav .page-nav-next:hover { color: var(--red); }

.page-nav-indicator {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--fg-faint);
}

/* --- Footer-ish actions --- */

.actions-row {
  padding: var(--space-4) var(--space-5);
  display: flex;
  justify-content: center;
  gap: var(--space-6);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.actions-row a {
  color: var(--fg-muted);
  text-decoration: none;
}

.actions-row a:hover { color: var(--red); }

@media (max-width: 720px) {
  .actions-row {
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-6);
  }
  .actions-row a {
    padding: 8px 0;
  }
}

/* --- Notes panel (owner-only, non-OOTK reading pages) --- */

.notes-panel {
  max-width: 560px;
  margin: var(--space-4) auto 0;
  padding: var(--space-4) var(--space-5) 0;
  border-top: 1px solid var(--rule);
}

.notes-panel textarea {
  display: block;
  width: 100%;
  min-height: 120px;
  margin-top: var(--space-3);
  border: 1px solid var(--rule);
  background: transparent;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.55;
  color: var(--fg);
  padding: 10px 12px;
  resize: vertical;
}

.notes-panel textarea:focus { outline: none; border-color: var(--red); }

.notes-panel .save-status { margin-top: 6px; }

/* --- Share panel (owner-only foot of every reading page) --- */

.share-panel {
  max-width: 560px;
  margin: var(--space-4) auto var(--space-6);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--rule);
  text-align: center;
}

.share-lede {
  margin: var(--space-2) auto 0;
  font-family: var(--serif);
  font-size: 15px;
  color: var(--fg-muted);
}

.share-row {
  display: flex;
  gap: 8px;
  margin-top: var(--space-3);
}

.share-url {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--rule);
  background: transparent;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--fg-muted);
  padding: 7px 9px;
}

.share-copy {
  flex: 0 0 auto;
  border: 1px solid var(--rule);
  background: transparent;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
  padding: 7px 12px;
  cursor: pointer;
}

.share-copy:hover { color: var(--red); border-color: var(--red); }

.share-form { margin-top: var(--space-3); }

.share-mint,
.share-withdraw {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 0 0 2px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  cursor: pointer;
}

.share-mint:hover,
.share-withdraw:hover { color: var(--red); border-color: var(--red); }

/* Phones: these underlined text buttons are ~16px tall — pad the top
   to a tappable height without moving the underline off the text. */
@media (max-width: 720px) {
  .share-mint,
  .share-withdraw {
    padding-top: 14px;
  }
  .share-copy {
    padding-top: 10px;
    padding-bottom: 10px;
  }
}

.reading-delete {
  text-align: center;
  margin: 0 auto var(--space-6);
}

.reading-delete-btn {
  font-size: 10px;
  color: var(--fg-faint);
  border-color: transparent;
}

/* --- Misc --- */

.divider-eyebrow {
  padding: var(--space-5) var(--space-6) 0;
}

.section-pad { padding: var(--space-3) var(--space-5); }


/* =============================================================
   I-Ching — two-column stage: a figure plate (left), a reading
   panel (right).  The plate shows ONE of four figures at a time:
   the cast, the tending (when there are changing lines), and the
   mutual gua (互卦) of either.  Lines morph by CSS width transition
   when the figure changes; the mutual-gua transition plays a
   construction animation (inner lines slide down/up; outer lines
   fade).  The right panel is sticky and updates on line hover to
   show that line's Three Powers (三才) and text.
   ============================================================= */

.iching-reflection {
  --ich-han: "Noto Serif SC", "Songti SC", serif;
}

.ich-stage {
  --ich-move:      0.92s;
  --ich-ease-open: cubic-bezier(.34, 1.5, .5, 1);
  --ich-han:       "Noto Serif SC", "Songti SC", serif;
  display: grid;
  grid-template-columns: minmax(340px, 420px) minmax(400px, 540px);
  gap: 72px;
  justify-content: center;
  align-items: start;
  padding: 50px var(--space-5) 0;
}

/* ── Plate (left column) ────────────────────────────────────── */

.plate {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.fig-label-wrap {
  position: relative;
  height: 15px;
  width: 100%;
}
.fig-label {
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  transition: opacity .28s ease;
}

.fig-head-wrap {
  position: relative;
  height: 92px;
  width: 100%;
  margin-top: 18px;
}
.fig-head {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  transition: opacity .28s ease;
}
.fig-idline {
  display: flex;
  align-items: center;
  gap: 12px;
}
.fig-num {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.fig-pinyin {
  font-family: var(--serif);
  font-size: 20px;
  color: var(--fg);
}
.fig-han {
  font-family: var(--ich-han);
  font-size: 21px;
  color: var(--red);
  line-height: 1;
}
.fig-name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 34px;
  margin: 0;
  letter-spacing: -0.01em;
  line-height: 1.05;
}
.fig-rule {
  width: 100%;
  max-width: 300px;
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 8px 0 0;
}

/* Trigram captions — hidden by default; revealed when the user
   hovers the corresponding trigram block in the stack. */
.trig-label {
  height: 15px;
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 13px 0;
  padding-left: 26px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  opacity: 0;
  transition: opacity .2s ease;
  pointer-events: none;
}
.trig-label .sym {
  font-size: 17px;
  letter-spacing: 0;
  color: var(--fg-muted);
  line-height: 1;
  position: relative;
  top: 1px;
}
.trig-label .attr { color: var(--fg-faint); }
.plate:has(#ichStack .trigram.upper:hover) .trig-top { opacity: 1; }
.plate:has(#ichStack .trigram.lower:hover) .trig-bottom { opacity: 1; }

/* The six-line stack. */
.stack {
  display: flex;
  flex-direction: column;
  align-self: stretch;
}
.trigram {
  display: flex;
  flex-direction: column;
  gap: 17px;
  padding: 9px 14px;
  margin: 0 -14px;
  border-radius: 5px;
  transition: background .18s ease;
}
.trig-divider {
  height: 11px;
  position: relative;
}
.trig-divider::after {
  content: "";
  position: absolute;
  left: 26px;
  top: 50%;
  transform: translateY(-50%);
  width: 236px;
  border-top: 1px dashed var(--rule);
}

.ich-line {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  cursor: pointer;
}
.ich-line::before {
  content: "";
  position: absolute;
  left: -4px;
  top: 50%;
  transform: translateY(-50%) scaleY(0);
  width: 2px;
  height: 20px;
  background: var(--red);
  transition: transform .16s ease;
  transform-origin: center;
}
.ich-line:hover::before,
.ich-line.lit::before { transform: translateY(-50%) scaleY(1); }
.ich-line .ln-no {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--fg-faint);
  width: 10px;
  text-align: right;
  transition: color .16s ease;
}
.ich-line:hover .ln-no,
.ich-line.lit .ln-no { color: var(--red); }
.ich-line .track {
  position: relative;
  width: 236px;
  height: 17px;
}
/* The .seg selectors are intentionally UN-scoped (not nested under
   .ich-line) — the mutual-gua construction animation clones bare
   .seg divs into a transient overlay outside the stack lines, so
   those clones need the same position/dimension grammar without
   inheriting it from an .ich-line parent. */
.seg {
  position: absolute;
  top: 0;
  height: 100%;
  background: var(--fg);
  transition:
    width var(--ich-move, .92s) var(--ich-ease-open, ease),
    background-color calc(var(--ich-move, .92s) * 0.8) ease;
}
.seg.l { left: 0; }
.seg.r { right: 0; }
.ich-line.lit .track .seg {
  box-shadow: 0 0 0 1px rgba(161, 52, 52, 0.25);
}
.plate.no-anim .seg { transition: none !important; }

/* Marks on the cast's changing lines (only visible while the plate
   shows the cast primary): ○ ring for old yang, × for old yin. */
.ich-line .mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s ease;
}
.plate.cast-primary .ich-line.changing .mark { opacity: 1; }
.ich-line .mark.ring {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--bg);
  border: 2.2px solid var(--red);
}
.ich-line .mark.ex {
  width: 16px;
  height: 16px;
}
.ich-line .mark.ex::before,
.ich-line .mark.ex::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 2px;
  background: var(--red);
}
.ich-line .mark.ex::before { transform: translate(-50%, -50%) rotate(45deg); }
.ich-line .mark.ex::after { transform: translate(-50%, -50%) rotate(-45deg); }

/* Plate controls — change toggle is hidden when there are no
   changing lines; mutual gua toggle is hidden until first use of
   the change toggle (or immediately available with no changes). */
.changebar {
  margin: 38px 0 0;
  padding-left: 26px;
  display: flex;
  gap: 13px;
  flex-wrap: wrap;
  align-items: center;
}
.change-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--card-bg);
  background: var(--red);
  border: 1px solid var(--red);
  border-radius: 22px;
  padding: 11px 22px;
  transition: all .18s ease;
}
.change-btn:hover {
  background: var(--fg);
  border-color: var(--fg);
}
.change-btn.reverted {
  background: transparent;
  color: var(--fg-muted);
  border-color: var(--rule);
}
.change-btn.reverted:hover {
  border-color: var(--red);
  color: var(--red);
}
.mutual-btn {
  background: transparent;
  color: var(--fg-muted);
  border-color: var(--rule);
  opacity: 0;
  pointer-events: none;
  transform: translateY(2px);
}
.mutual-btn .glyph {
  font-family: var(--ich-han);
  font-size: 14px;
  line-height: 1;
}
.mutual-btn:hover {
  background: transparent;
  color: var(--red);
  border-color: var(--red);
}
.mutual-btn.avail {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}
.mutual-btn.on {
  background: var(--red);
  color: var(--card-bg);
  border-color: var(--red);
}
.mutual-btn.on .glyph { color: var(--card-bg); }

/* ── Reading panel (right column) ───────────────────────────── */

.panel-col {
  position: sticky;
  top: 34px;
}
.reading-panel { max-width: 540px; }
.reading-panel .pp-tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin: 0 0 22px;
}
.reading-panel .pp-tag .han {
  font-family: var(--ich-han);
  color: var(--red);
  font-size: 13px;
  letter-spacing: 0;
  margin-left: 4px;
}
.reading-panel h3 {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 11px;
}
.reading-panel .pp-body {
  font-family: var(--serif);
  font-size: 19.5px;
  line-height: 1.6;
  color: var(--fg-muted);
  margin: 0 0 30px;
  text-wrap: pretty;
}
.reading-panel .pp-hint {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin: 34px 0 0;
  display: flex;
  align-items: center;
  gap: 9px;
}
.reading-panel .pp-hint::before {
  content: "";
  width: 22px;
  border-top: 1px solid var(--rule);
}
.reading-panel .pp-powers {
  display: flex;
  align-items: center;
  gap: 13px;
  margin: 0 0 22px;
}
.powers-triad {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.powers-triad .tier {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 21px;
  height: 13px;
  border: 1px solid var(--rule);
  border-radius: 2px;
  font-family: var(--ich-han);
  font-size: 9.5px;
  color: var(--fg-faint);
  line-height: 1;
}
.powers-triad .tier.on {
  background: var(--red);
  border-color: var(--red);
  color: var(--card-bg);
}
.reading-panel .pwr-text {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.reading-panel .pwr-text .han {
  font-family: var(--ich-han);
  font-size: 14px;
  letter-spacing: 0;
  color: var(--red);
  margin-left: 9px;
  text-transform: none;
}
.reading-panel .pp-linehead {
  display: flex;
  align-items: baseline;
  gap: 13px;
  margin: 0 0 16px;
}
.reading-panel .pp-lineno {
  font-family: var(--serif);
  font-size: 23px;
  color: var(--red);
}
.reading-panel .pp-linelabel {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  display: flex;
  align-items: center;
  gap: 10px;
}
.reading-panel .pp-linetext {
  font-family: var(--serif);
  font-size: 25px;
  line-height: 1.45;
  color: var(--fg);
  margin: 0;
  font-weight: 400;
  text-wrap: pretty;
}
.reading-panel .pp-note {
  font-family: var(--serif);
  font-size: 15.5px;
  color: var(--fg-muted);
  margin: 22px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--rule-soft);
  text-wrap: pretty;
}
.reading-panel .pp-note em {
  color: var(--red);
}
@keyframes ich-panel-in {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}
.reading-panel.enter { animation: ich-panel-in .34s ease; }

/* ── Responsive collapse ──────────────────────────────────── */

@media (max-width: 1000px) {
  .ich-stage {
    grid-template-columns: 1fr;
    gap: 48px;
    justify-content: start;
  }
  .panel-col { position: static; }
}

@media print {
  .changebar { display: none; }
}



/* =============================================================
   Celtic Cross (admin) — drawn figure + ledger two-column.
   ─────────────────────────────────────────────────────────────
   Two columns: a left-hand ledger that fills the old dead space
   (positions read in order), and a right-hand figure built from
   absolutely-positioned slots in fixed pixel geometry — the
   cross (01 / 03 / 04 / 05 / 06) with the Crossing card (02)
   laid over 01 rotated 90°, and the staff (07/08/09/10) to its
   right.  A faint skeleton SVG draws the cross axes + the dashed
   staff spine; a separate path SVG lights up the 1 → 10 reading
   order when toggled.

   Hovering a ledger row lights its figure card and vice versa.
   Card 02 has pointer-events:none so a single hit-zone matching
   its rotated visible footprint receives hover — the bands of
   card 01 above and below the crossing remain hover-active.
   ============================================================= */

.cc-body {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 40px;
  padding: var(--space-5) 0 0;
}

/* ── Ledger (left column) ─────────────────────────────────── */

.cc-ledger {
  position: relative;
}

.cc-ledger .lhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 0 6px;
}

.cc-ledger-list {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
}

.cc-ledger-list li {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 0 14px;
  align-items: baseline;
  padding: 13px 12px 13px 10px;
  margin: 0 -12px;
  border-top: 1px solid var(--rule-soft);
  cursor: pointer;
  border-radius: 3px;
  transition: background .15s ease;
}

.cc-ledger-list li:last-child {
  border-bottom: 1px solid var(--rule-soft);
}

/* Phones: no parent padding to absorb the full-bleed negative margin,
   so the rows would poke past both screen edges. */
@media (max-width: 720px) {
  .cc-ledger-list li {
    margin: 0;
  }
}

.cc-ledger-list li:hover,
.cc-ledger-list li.lit {
  background: rgba(161, 52, 52, 0.06);
}

.cc-ledger-list .l-num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--red);
  grid-row: span 2;
}

.cc-ledger-list .l-pos {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 16.5px;
  color: var(--fg);
}

.cc-ledger-list .l-card {
  font-family: var(--serif);
  font-size: 14.5px;
  color: var(--fg-muted);
  grid-column: 2;
}

.cc-ledger-list .l-desc {
  font-family: var(--serif);
  font-size: 13.5px;
  color: var(--fg-muted);
  grid-column: 2;
  margin-top: 4px;
  line-height: 1.45;
}

.cc-ledger-list li.lit .l-pos {
  color: var(--red);
}

/* ── Figure (right column) — controls + canvas ────────────── */

.cc-figure-wrap {
  position: relative;
}

.cc-controls {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 6px;
}

.path-toggle {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  user-select: none;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
  border: 1px solid var(--rule);
  border-radius: 20px;
  padding: 7px 14px;
  background: rgba(251, 248, 239, 0.5);
  transition:
    border-color .16s ease,
    background .16s ease,
    color .16s ease;
}
.path-toggle:hover { border-color: var(--fg-faint); }
.path-toggle .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid var(--red);
}
.path-toggle.on {
  background: var(--red);
  color: var(--card-bg);
  border-color: var(--red);
}
.path-toggle.on .dot {
  background: var(--card-bg);
  border-color: var(--card-bg);
}

.cc-figure {
  position: relative;
  margin: 18px auto 0;
}

/* Narrow screens: the figure's geometry is fixed-pixel (built in JS,
   ~732px wide), so it can't shrink — let it pan inside its own strip
   instead of dragging the whole page sideways. 820px covers the shell
   padding around it. A real small-screen layout is a design decision,
   parked for the Claude Design pass. */
@media (max-width: 820px) {
  .cc-figure-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

.cc-skeleton {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: visible;
}

.cc-path {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  overflow: visible;
  opacity: 0;
  transition: opacity .3s ease;
}

.cc-figure.show-path .cc-path { opacity: 1; }
.cc-figure.show-path .cc-frame {
  opacity: 0.42;
  filter: saturate(0.5);
}
.cc-figure.show-path .cc-pos,
.cc-figure.show-path .cc-name {
  opacity: 0.4;
}

/* ── Slots / cards in the figure ──────────────────────────── */

.cc-slot {
  position: absolute;
  z-index: 2;
  transform: translate(-50%, -50%);
  transition: opacity .18s ease;
}

.cc-slot .cc-frame {
  position: relative;
  background: var(--card-bg);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 6px;
  box-shadow: 0 2px 8px rgba(42, 32, 23, 0.12);
  transition:
    box-shadow .18s ease,
    border-color .18s ease,
    transform .18s ease;
}

.cc-art {
  position: relative;
  border-radius: 1px;
  overflow: hidden;
  /* Solid parchment background — when card art is present, the
     image lives in this surface with `object-fit: contain`, so any
     aspect-ratio mismatch between the Marseille image (≈ 1:2) and
     the slot (5:8-ish) shows as small matting that blends with
     the surrounding card paper rather than as cropping. */
  background: var(--card-bg);
  border: 1px solid var(--rule-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.cc-art .emblem {
  font-family: var(--serif);
  font-size: 12px;
  color: var(--fg-faint);
  padding: 0 6px;
}

.cc-art .card-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--card-bg);
}

.cc-pos {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(100% + 7px);
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
  text-align: center;
  line-height: 1.3;
  margin: 0;
}
.cc-pos .pn { color: var(--red); }

.cc-name {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: calc(100% + 7px);
  white-space: nowrap;
  font-family: var(--serif);
  font-size: 12.5px;
  color: var(--fg-muted);
  text-align: center;
  margin: 0;
}
.cc-name .sub {
  color: var(--fg-faint);
}

/* Crossing card: rotated 90°.  Its slot is pointer-events:none so
   hover falls through onto card 01 underneath above and below the
   crossing band; a dedicated hit-zone re-enables hover precisely
   over the rotated card's visible footprint. */
.cc-slot.crossing {
  z-index: 4;
  pointer-events: none;
}
.cc-slot.crossing .cc-frame {
  transform: rotate(90deg);
  box-shadow: 0 6px 16px rgba(42, 32, 23, 0.22);
}
.cc-slot.crossing .cc-pos,
.cc-slot.crossing .cc-name {
  display: none;
}

.cc-cross-hit {
  position: absolute;
  pointer-events: auto;
  cursor: pointer;
  z-index: 7;
}

/* ── Highlight states ─────────────────────────────────────── */

.cc-figure.diming .cc-slot:not(.lit) {
  opacity: 0.32;
}
.cc-slot.lit { z-index: 3; }
.cc-slot.lit .cc-frame {
  border: 2px solid var(--red);
  box-shadow:
    0 0 0 4px rgba(161, 52, 52, 0.10),
    0 6px 18px rgba(92, 22, 15, 0.25);
}
.cc-slot.lit.crossing .cc-frame {
  border: 2px solid var(--red);
}
.cc-slot.lit .cc-pos,
.cc-slot.lit .cc-name {
  opacity: 1;
}
.cc-slot.lit .cc-pos .pn {
  color: var(--red);
}

/* ── Skeleton + path SVGs ─────────────────────────────────── */

.sk {
  stroke: var(--fg);
  fill: none;
  opacity: 0.16;
  stroke-width: 1.2;
}
.sk-staff {
  stroke-dasharray: 1.5 6;
}

.pth {
  stroke: var(--red);
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pnode { fill: var(--red); }
.pnum {
  fill: var(--card-bg);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  text-anchor: middle;
  dominant-baseline: central;
}

/* ── Timing block (unchanged from before) ─────────────────── */

.cc-timing {
  margin: 48px 0 0;
  padding: 26px 0 0;
  border-top: 1px solid var(--rule);
}

.cc-timing .eyebrow {
  margin: 0 0 12px;
}

.cc-timing-line {
  margin: 0;
  font-family: var(--serif);
  font-size: 26px;
  line-height: 1.4;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 16px;
}

.cc-timing-card {
  font-weight: 500;
}

.cc-timing-sep {
  color: var(--fg-faint);
}

.cc-timing-window {
  color: var(--fg-muted);
}
.cc-timing-window em {
  color: var(--red);
  font-weight: 500;
}

/* ── Responsive fallback ──────────────────────────────────── */

/* The figure has a fixed pixel geometry; on narrower viewports
   we collapse to a single column.  The figure overflows naturally
   if the viewport can't accommodate it — that's by design (it's
   a desktop reading). */
@media (max-width: 1100px) {
  .cc-body {
    grid-template-columns: 1fr;
    gap: var(--space-6);
  }
  .cc-figure-wrap {
    overflow-x: auto;
  }
}


/* =============================================================
   Print styles
   - Default to landscape (the OOTK 2-column grids and wheels need
     the horizontal room).
   - Drop the dark theme back to ink-on-paper; the night background
     would just waste toner.
   - Hide on-screen chrome: site header, page nav, action links.
   - Avoid breaking individual cards / chain rows / pair rows
     across pages.
   ============================================================= */

@media print {
  @page {
    size: landscape;
    margin: 1cm;
  }

  /* Override both themes to a print-safe ink-on-paper palette. */
  body,
  body.theme-night,
  body.theme-parchment {
    background: #fff !important;
    color: #111 !important;
    --bg:        #fff;
    --fg:        #111;
    --fg-muted:  #555;
    --fg-faint:  #888;
    --rule:      #bbb;
    --rule-soft: #ddd;
    --card-bg:   #fafafa;
    font-size: 10pt;
  }

  /* Strip on-screen-only chrome. */
  .site-header,
  .page-nav,
  .actions-row,
  .question-bar .actions,
  .reading-topbar .saved {
    display: none !important;
  }

  /* Make the main content stretch to the printable width. */
  .reading-shell,
  .form-shell,
  main {
    max-width: 100%;
    width: 100%;
    padding: 0;
    margin: 0;
  }

  /* Trim screen padding so we don't waste edge space. */
  .reading-topbar,
  .question-bar,
  .ootk-section .section-head,
  .ootk-section .sig-line,
  .four-piles-block,
  .ootk-grid,
  .section-pad,
  .three-card .card-panel {
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
  }

  /* SVG figures scale to whatever column they sit in. */
  .wheel,
  .tree-of-life {
    width: 100%;
    height: auto;
    max-height: 16cm;
  }

  /* Keep visual units intact across page breaks. */
  .card-panel,
  .chain-row,
  .pair-row,
  .lone-row,
  .gt-card,
  .pile-preview,
  .single-house,
  .pile-card {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .ootk-section,
  .three-card,
  .grand-tableau,
  .cc-spread {
    break-inside: auto;
  }

  /* Celtic Cross: keep individual slots together, and keep the rotated
     Crossing card visible (transforms are honoured in print). */
  .cc-slot,
  .cc-ledger-list li {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* The horizontal pile strip should never overflow the printable width. */
  .pile-strip {
    flex-wrap: wrap;
  }

  /* Wheel SVG strokes — switch to ink colour explicitly so a printer
     in greyscale mode still produces legible lines. */
  .wheel .ring-outer,
  .wheel .ring-inner,
  .wheel .divider {
    stroke: #111;
  }
  .wheel .chain-line,
  .wheel .placeholder.sig,
  .wheel .dot.sig,
  .wheel .sig-sector,
  .tree-of-life .sephira.sig .seph-circle {
    fill: #111 !important;
    stroke: #111 !important;
  }
  .wheel .placeholder.chain {
    stroke: #444 !important;
  }

  /* Sig/partner highlight on the grand tableau: use a heavier black
     border instead of red so a B&W printer reads it. */
  .gt-card.sig .gt-frame,
  .gt-card.partner .gt-frame {
    border-color: #111 !important;
  }

  /* Force hyperlinks not to grow underlines & blue colour. */
  a, a:visited {
    color: inherit !important;
    text-decoration: none !important;
  }

  /* Suppress any element marked as print-hidden (escape hatch). */
  .no-print {
    display: none !important;
  }
}

/* =============================================================
   Rune Cast — Elder Futhark on Thorsson's Nine-Worlds cloth.
   Folded in from the design handoff (cast.css). The cloth, the
   "flat carved wood" staves, the reading panel, and the ættir
   legend. The engine + data live in static/js/{cast-engine,
   runes-data}.js; this only styles what they render.

   The handoff's tokens are aliased onto the existing parchment
   palette so the cast uses the same ink greys + brand red as the
   rest of the instrument (the prototype's #8a261a blood becomes
   the project's --red #a13434; its #2a2017 ink becomes --fg).
   ============================================================= */

body.theme-parchment {
  --ink:      var(--fg);
  --ink70:    rgba(26, 24, 21, 0.70);
  --ink50:    rgba(26, 24, 21, 0.50);
  --ink35:    rgba(26, 24, 21, 0.35);
  --ink20:    rgba(26, 24, 21, 0.20);
  --ink12:    rgba(26, 24, 21, 0.12);
  --blood:    var(--red);
  --blood-dk: #7a2222;
  --display:  var(--serif);
  --field:    var(--bg);
  --panel:    #ded2b6;   /* a deeper parchment than --card-bg for the lens block */
  --card:     #fbf8ef;   /* near-white glyph-chip paper */
}

/* Rune-cast eyebrows carry their own "— " dash in the rendered text, so
   they use `.eyebrow.red` rather than `.eyebrow-red`. */
.rune-cast .eyebrow.red,
.rc-panel .eyebrow.red { color: var(--red); }

/* ── The stage ───────────────────────────────────────────────── */
.rc-stage {
  display: grid;
  grid-template-columns: 800px minmax(380px, 440px);
  gap: 64px;
  justify-content: center;
  align-items: start;
  padding: 44px 0 0;
}

.rc-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 10px;
  min-height: 32px;
}
.rc-controls .eyebrow.red { margin: 0; }
.rc-toggle {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  user-select: none;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink70);
  border: 1px solid var(--ink20);
  border-radius: 20px;
  padding: 7px 14px;
  background: rgba(251, 248, 239, 0.5);
  transition: all .16s ease;
}
.rc-toggle:hover { border-color: var(--ink35); }
.rc-toggle .dot { width: 9px; height: 9px; border-radius: 50%; border: 1px solid var(--blood); }
.rc-toggle.on { background: var(--blood); color: #f3ead7; border-color: var(--blood); }
.rc-toggle.on .dot { background: #f3ead7; border-color: #f3ead7; }

/* ── The field & cloth ───────────────────────────────────────── */
.field { position: relative; width: 800px; height: 810px; }
.field svg.mat { position: absolute; inset: 0; display: block; width: 100%; height: 100%; pointer-events: none; }
.mat .cloth { fill: #f1ead7; }
.mat .clothshade { fill: url(#clothG); }
.mat .frame { fill: none; stroke: var(--ink); stroke-width: 1.6; opacity: 0.78; }
.mat .ring { fill: none; stroke: var(--ink); stroke-width: 1.3; opacity: 0.7; }
.mat .grid { stroke: var(--ink); stroke-width: 1.2; opacity: 0.6; }
.mat .grid.diag { opacity: 0.5; }
.mat .north { fill: none; stroke: var(--ink); stroke-width: 1.4; opacity: 0.8; stroke-linecap: round; stroke-linejoin: round; }
.mat .north-l { font-family: var(--mono); font-size: 11px; letter-spacing: 0.28em; fill: var(--ink70); text-anchor: middle; }
/* region fills, lit on hover */
.mat .stead { fill: rgba(161, 52, 52, 0.085); stroke: rgba(161, 52, 52, 0.5); stroke-width: 1.2; opacity: 0; transition: opacity .22s ease; }
.mat .stead.on { opacity: 1; }
/* world-stead names */
.mat .wlabel {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  fill: var(--ink70); text-anchor: middle; dominant-baseline: middle; pointer-events: auto; cursor: pointer;
  transition: fill .18s ease;
}
.mat .wlabel.core { fill: var(--ink); letter-spacing: 0.16em; }
.mat .wlabel:hover, .mat .wlabel.lit { fill: var(--blood); }

.staves, .tags { position: absolute; inset: 0; }
.staves { pointer-events: none; }
.tags { pointer-events: none; transition: opacity .3s ease; }
.field.nolabels .tags { opacity: 0; }
.tags span {
  position: absolute; transform: translate(-50%, 0); font-family: var(--mono); font-size: 8.5px;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink50); white-space: nowrap;
}
.tags span i { font-style: normal; color: var(--blood); }
.tags span.dim { color: var(--ink35); opacity: 0.7; }

/* ── Staves — "flat carved wood" ─────────────────────────────── */
.stave {
  position: absolute; left: 0; top: 0; width: 40px; height: 66px; margin-left: -20px; margin-top: -33px;
  cursor: pointer; z-index: 2; pointer-events: auto; transition: opacity .3s ease, filter .3s ease;
}
.stave .wood {
  position: absolute; inset: 0; border-radius: 7px; border: 1px solid rgba(42, 32, 23, 0.32);
  background: #ccb588;
  background-image: repeating-linear-gradient(90deg, rgba(42, 32, 23, 0.05) 0 1px, transparent 1px 8px);
  box-shadow: none;
  transition: box-shadow .18s ease, border-color .18s ease;
}
.stave .glyph {
  position: absolute; left: 50%; top: 50%; width: 30px; height: 44px; transform: translate(-50%, -50%);
  color: #42301c; opacity: 0.95; transition: color .18s ease;
}
.stave.facedown .glyph { opacity: 0; }
.stave.faceup .glyph { transition: opacity .28s ease, color .18s ease; }
@keyframes rc-staveflip { 0% { transform: scaleX(1); } 45% { transform: scaleX(0.22); } 100% { transform: scaleX(1); } }
.stave.reveal .wood { animation: rc-staveflip .34s ease; }
.stave.facedown .wood {
  background: #bda978;
  background-image: repeating-linear-gradient(90deg, rgba(42, 32, 23, 0.06) 0 1px, transparent 1px 8px);
}

.stave.hot { z-index: 6; }
.stave.hot .wood {
  border-color: var(--blood);
  box-shadow: 0 0 0 3px rgba(161, 52, 52, 0.13), 0 3px 11px rgba(122, 34, 34, 0.35);
}
.stave.hot .glyph { color: var(--blood); }
.field.diming .stave:not(.hot) { opacity: 0.55; }
.stave.silent { opacity: 0.4; filter: grayscale(0.55); }
.field.diming .stave.silent:not(.hot) { opacity: 0.22; }
.stave.silent.hot { opacity: 0.85; filter: grayscale(0.2); }

.silent-line {
  margin: 12px 0 0; font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink35);
}

/* ── Reading panel ───────────────────────────────────────────── */
.rc-panel-col { position: sticky; top: 34px; }
.rc-panel { min-height: 480px; max-width: 540px; }
@keyframes rc-panel-in { from { transform: translateY(6px); } to { transform: none; } }
.rc-panel.enter { animation: rc-panel-in .3s ease; }

.rc-panel .pp-castline {
 font-family: var(--display); font-size: 22px; line-height: 1.4;
  color: var(--ink70); margin: 14px 0 20px; text-wrap: pretty;
}
.rc-panel .pp-castline em { color: var(--blood); }
.rc-panel .zr-group {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink35); margin: 20px 0 2px;
}
.rc-panel .zr-group:first-of-type { margin-top: 8px; }
.rc-panel .zrow { border-top: 1px solid var(--ink12); padding: 9px 0 8px; border-radius: 3px; transition: background .15s ease; }
.rc-panel .zrow.lit { background: rgba(161, 52, 52, 0.06); }
.rc-panel .zr-head { display: flex; align-items: baseline; gap: 12px; margin: 0; }
.rc-panel .zr-name { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink); flex: 1; cursor: pointer; transition: color .15s ease; }
.rc-panel .zr-name:hover, .rc-panel .zrow.lit .zr-name { color: var(--blood); }
.rc-panel .zr-sense { font-family: var(--display); font-size: 13px; color: var(--ink50); flex: 1; }
.rc-panel .zr-count { font-family: var(--mono); font-size: 10.5px; color: var(--blood); }
.rc-panel .zr-list { font-family: var(--display); font-size: 15px; color: var(--ink70); margin: 5px 0 0; line-height: 1.55; text-wrap: pretty; }
.rc-panel .zr-list i { font-style: normal; font-family: var(--mono); font-size: 9px; letter-spacing: 0.08em; color: var(--blood); }
.rc-panel .zr-list .none { color: var(--ink35); }
.rc-panel .pp-hint {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink35); margin: 30px 0 0; display: flex; align-items: center; gap: 9px;
}
.rc-panel .pp-hint::before { content: ""; width: 22px; border-top: 1px solid var(--ink20); flex: none; }

.rc-panel .pp-runehead { display: flex; align-items: center; gap: 20px; margin: 18px 0 16px; }
.rc-panel .pp-glyph {
  width: 54px; height: 84px; display: flex; align-items: center; justify-content: center; flex: none;
  background: var(--card); border: 1px solid var(--ink20); border-radius: 3px; box-shadow: 0 2px 8px rgba(42, 32, 23, 0.12);
}
.rc-panel .pp-glyph svg { width: 30px; height: 48px; color: var(--ink); display: block; }
.rc-panel .pp-glyph.rev svg { transform: rotate(180deg); color: var(--blood); }
.rc-panel .pp-glyph.mute { opacity: 0.5; }
.rc-panel .pp-rname { font-family: var(--display); font-weight: 500; font-size: 34px; margin: 0; line-height: 1.05; letter-spacing: -0.01em; }
.rc-panel .pp-meta { font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink50); margin: 7px 0 0; }
.rc-panel .pp-orient {
  display: inline-flex; font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  margin: 4px 0 16px; padding: 5px 12px; border: 1px solid var(--ink20); border-radius: 14px; color: var(--ink70);
}
.rc-panel .pp-orient.rev { color: #f3ead7; background: var(--blood); border-color: var(--blood); }
.rc-panel .pp-orient.fast { color: var(--ink50); border-style: dashed; }
.rc-panel .pp-kw { font-family: var(--display); font-size: 15.5px; color: var(--ink50); margin: 0 0 14px; }
.rc-panel .pp-body { font-family: var(--display); font-size: 19.5px; line-height: 1.6; color: var(--ink70); margin: 0 0 18px; text-wrap: pretty; }
.rc-panel .pp-body.muted { color: var(--ink50); }
.rc-panel .pp-note {
 font-family: var(--display); font-size: 15.5px; color: var(--ink50); margin: 18px 0 0;
  padding-top: 16px; border-top: 1px solid var(--ink12); text-wrap: pretty;
}
.rc-panel .pp-worldrealm { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink35); margin: 14px 0 16px; }
.rc-panel .pp-lens { margin: 18px 0 0; padding: 16px 18px; background: var(--panel); border-radius: 4px; }
.rc-panel .pp-lens-head { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--blood); margin: 0 0 8px; }
.rc-panel .pp-lens-body { font-family: var(--display); font-size: 15.5px; line-height: 1.56; color: var(--ink70); margin: 0; text-wrap: pretty; }

/* ── Hover tooltip — floats by the pointer (Grand-Tableau style) ── */
.rc-tip {
  position: fixed; z-index: 50; pointer-events: none; opacity: 0;
  background: var(--ink); color: #f3ead7;
  padding: 11px 15px 13px; border-radius: 4px; max-width: 320px;
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.32);
  transition: opacity .14s ease; transform: translate(-50%, -114%);
  font-family: var(--display);
}
.rc-tip .tt-loc {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: 0.18em;
  text-transform: uppercase; color: rgba(243, 234, 215, 0.55); margin: 0 0 6px;
}
.rc-tip .tt-rune { display: block; font-size: 20px; font-weight: 500; line-height: 1.1; margin: 0 0 4px; }
.rc-tip .tt-rune i {
  font-style: normal; font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: rgba(243, 234, 215, 0.5); margin-left: 6px; vertical-align: middle;
}
.rc-tip .tt-rune i.rev { color: var(--red-soft); }
.rc-tip .tt-realm {
  display: block; font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.18em;
  text-transform: uppercase; color: rgba(243, 234, 215, 0.45); margin: 0 0 7px;
}
.rc-tip .tt-kw { display: block; font-size: 13px; color: rgba(243, 234, 215, 0.6); margin: 0 0 7px; }
.rc-tip .tt-body { display: block; font-size: 14px; line-height: 1.5; color: rgba(243, 234, 215, 0.92); }
.rc-tip .tt-lens {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: 0.08em;
  color: rgba(243, 234, 215, 0.5); line-height: 1.5; margin: 9px 0 0; padding-top: 8px;
  border-top: 1px solid rgba(243, 234, 215, 0.18);
}

/* ── Live casting flow (rune_cast_flow.html) ─────────────────── */
.rc-steps {
  display: flex; gap: 26px; padding: 18px var(--space-5) 0;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink35);
}
.rc-steps span { transition: color .2s ease; }
.rc-flow[data-phase="q"]       .rc-steps span[data-s="q"],
.rc-flow[data-phase="gather"]  .rc-steps span[data-s="gather"],
.rc-flow[data-phase="casting"] .rc-steps span[data-s="casting"],
.rc-flow[data-phase="read"]    .rc-steps span[data-s="read"] { color: var(--blood); }

/* Phase visibility — only the flow page carries data-phase; the saved
   page (.rune-cast without .rc-flow) always shows everything. */
.rc-qstage { display: none; max-width: 780px; margin: 0 auto; padding: 90px var(--space-5) 60px; }
.rc-flow[data-phase="q"] .rc-qstage { display: block; }
.rc-flow[data-phase="q"] .rc-stage,
.rc-flow[data-phase="q"] .rc-qbar { display: none; }
.rc-flow:not([data-phase="read"]) .rc-controls .rc-toggle { visibility: hidden; }
.rc-flow:not([data-phase="read"]) .silent-line { visibility: hidden; }

.rc-qdisplay { margin: 18px 0 22px; }
.rc-qlede { max-width: 640px; margin: 0 0 52px; }
.rc-qinput {
  display: block; width: 100%; background: transparent; border: 0; border-bottom: 1px solid var(--ink20);
 font-family: var(--display); font-size: 25px; color: var(--ink); padding: 10px 2px 14px; outline: none;
  transition: border-color .18s ease;
}
.rc-qinput::placeholder { color: var(--ink35); }
.rc-qinput:focus { border-bottom-color: var(--blood); }
.rc-qfoot { display: flex; align-items: center; gap: 22px; margin: 40px 0 0; flex-wrap: wrap; }
.rc-qskip { font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink35); }

.rc-btn {
  display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: #f3ead7;
  background: var(--blood); border: 1px solid var(--blood); border-radius: 22px; padding: 11px 22px; transition: all .18s ease;
}
.rc-btn:hover { background: var(--blood-dk); border-color: var(--blood-dk); }
.rc-btn:disabled { opacity: 0.4; cursor: default; }

.rc-gatherbar { display: flex; gap: 13px; flex-wrap: wrap; align-items: center; margin: 34px 0 0; }

/* Single-column fallback for the cast stage on narrower viewports. */
@media (max-width: 1380px) {
  .rc-stage { grid-template-columns: 800px; justify-content: center; }
  .rc-panel-col { position: static; }
}
@media (max-width: 900px) {
  /* The stave positions are pixel coordinates in an 800px-wide space,
     so the cloth can't shrink below that — keep the stage column from
     forcing the page wider and pan the field in its own strip. A true
     scaled-down cast is parked for the Claude Design pass. */
  .rc-stage { grid-template-columns: minmax(0, 1fr); }
  .rc-field-col {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .field { width: 800px; height: auto; aspect-ratio: 800 / 810; }
}
@media print {
  .rc-controls, .rc-steps, .rc-gatherbar { display: none; }
}

/* ====================================================================
   Tarot Table — multi-oracle builder (ported from the design handoff).
   A full-screen authoring surface + the saved-view render. Every
   selector is namespaced .tt-*; the prototype's tokens are scoped to
   the builder roots so they don't leak into the rest of the app.
   ==================================================================== */

.tt-builder, .tt-saved-table {
  --field:#e9e1cd; --panel:#ded2b6; --card:#fbf8ef; --card-edge:#e7dcc1;
  --ink:#2a2017; --ink70:rgba(42,32,23,0.70); --ink50:rgba(42,32,23,0.50);
  --ink35:rgba(42,32,23,0.35); --ink20:rgba(42,32,23,0.20); --ink12:rgba(42,32,23,0.12);
  --blood:#8a261a; --blood-dk:#5c160f; --gold:#b08a3e;
  --ttd:"Fraunces","Times New Roman",serif;
  --ttm:"DM Mono",ui-monospace,monospace;
  --tt-card-w:90px; --tt-card-h:142px; --tt-grid:34px;
}

/* full-screen shell — its own top bar replaces the site header */
body.tt-fullscreen { overflow:hidden; height:100vh; }
.tt-builder {
  position:fixed; inset:0; z-index:1; display:flex; flex-direction:column;
  background:var(--field); color:var(--ink); font-family:var(--ttd);
  line-height:1.5; -webkit-font-smoothing:antialiased;
}
.tt-builder button { font-family:inherit; cursor:pointer; }
.tt-eyebrow { font-family:var(--ttm); font-size:10px; font-weight:500; letter-spacing:0.26em; text-transform:uppercase; }

/* ── Top bar ─────────────────────────────────────────────────────── */
.tt-topbar { flex:0 0 auto; display:flex; align-items:center; gap:26px; padding:0 26px; height:58px;
  border-bottom:1px solid var(--ink12); position:relative; z-index:30; }
.tt-brand { display:flex; align-items:center; gap:11px; white-space:nowrap; }
.tt-sigil-link { display:flex; line-height:0; }
.tt-sigil { width:22px; height:22px; border:1.5px solid var(--blood); transform:rotate(45deg); position:relative; flex:0 0 auto; }
.tt-sigil::after { content:""; position:absolute; inset:4px; border:1px solid var(--blood); }
.tt-brand-name { font-family:var(--ttd); font-size:19px; font-weight:500; }
.tt-brand-date { font-family:var(--ttm); font-size:11px; letter-spacing:0.14em; color:var(--ink35); }

.tt-qwrap { flex:1 1 auto; display:flex; align-items:baseline; gap:14px; min-width:0; }
.tt-qlabel { font-family:var(--ttm); font-size:10px; letter-spacing:0.24em; text-transform:uppercase; color:var(--ink50); white-space:nowrap; }
.tt-qinput { flex:1 1 auto; min-width:0; border:0; background:transparent; font-family:var(--ttd);
  font-size:20px; color:var(--ink); padding:4px 0; border-bottom:1px solid transparent; transition:border-color .18s ease; }
.tt-qinput::placeholder { color:var(--ink35); }
.tt-qinput:focus { outline:none; border-bottom-color:var(--ink20); }

.tt-topright { display:flex; align-items:center; gap:18px; white-space:nowrap; }
.tt-pile-caption { font-family:var(--ttm); font-size:11px; letter-spacing:0.12em; color:var(--ink50); }
.tt-read-btn { font-family:var(--ttm); font-size:11px; letter-spacing:0.16em; text-transform:uppercase; color:#f3ead7;
  background:var(--blood); border:1px solid var(--blood); border-radius:22px; padding:10px 20px; transition:background .18s ease,opacity .18s ease; }
.tt-read-btn:hover { background:var(--blood-dk); }
.tt-read-btn:disabled { opacity:.4; cursor:not-allowed; background:var(--blood); }

/* ── Canvas ──────────────────────────────────────────────────────── */
.tt-stage { flex:1 1 auto; position:relative; overflow:hidden; }
.tt-canvas { position:absolute; inset:0; }
.tt-canvas.tt-show-grid { background-image:radial-gradient(circle, var(--ink12) 1.1px, transparent 1.4px);
  background-size:var(--tt-grid) var(--tt-grid); background-position:center center; }
.tt-canvas-hint { position:absolute; left:50%; top:46%; transform:translate(-50%,-50%); text-align:center; color:var(--ink35); pointer-events:none; width:340px; }
.tt-ch-lede { font-family:var(--ttd); font-size:22px; color:var(--ink50); margin:0 0 6px; }
.tt-ch-sub { font-family:var(--ttm); font-size:11px; letter-spacing:0.12em; color:var(--ink35); margin:0; }
.tt-canvas.tt-has-cards .tt-canvas-hint { display:none; }

.tt-guides { position:absolute; inset:0; pointer-events:none; z-index:18; }
.tt-guide { position:absolute; background:var(--blood); opacity:.55; }
.tt-guide.tt-v { width:1px; top:0; bottom:0; }
.tt-guide.tt-h { height:1px; left:0; right:0; }

.tt-spread-hint { position:absolute; top:16px; left:50%; transform:translateX(-50%); z-index:20;
  font-family:var(--ttm); font-size:11px; letter-spacing:0.07em; color:var(--ink70);
  background:var(--card); border:1px solid var(--ink12); border-radius:20px; padding:7px 16px;
  box-shadow:0 4px 14px rgba(42,32,23,.12); white-space:nowrap; }
.tt-spread-hint[hidden] { display:none; }

/* ── A position on the table ─────────────────────────────────────── */
.tt-position { position:absolute; transform:translate(-50%,-50%); z-index:5;
  display:flex; flex-direction:column; align-items:center; gap:7px; touch-action:none; }
.tt-position.tt-selected { z-index:12; }
.tt-position.tt-dragging { z-index:14; }

.tt-cardstack { position:relative; display:flex; align-items:flex-start; cursor:grab; }
.tt-cardstack:active { cursor:grabbing; }
.tt-cardstack > .tt-tcard + .tt-tcard { margin-left:-50px; transition:margin-left .2s cubic-bezier(.22,1,.36,1), box-shadow .18s ease; }
.tt-position.tt-selected .tt-cardstack > .tt-tcard + .tt-tcard,
.tt-position.tt-faceup .tt-cardstack > .tt-tcard + .tt-tcard { margin-left:10px; }
.tt-position.tt-selected .tt-cardstack { outline:2px solid var(--blood); outline-offset:5px; border-radius:10px; }
.tt-cardstack.tt-drop-hot { outline:2px dashed var(--blood); outline-offset:6px; border-radius:10px; background:rgba(138,38,26,.05); }
.tt-cardstack.tt-group-hot { outline:2px solid var(--gold); outline-offset:6px; border-radius:10px; box-shadow:0 0 0 5px rgba(176,138,62,.18); }

.tt-position.tt-grouped .tt-label-wrap { display:none; }

/* group hull */
.tt-group-hull { position:absolute; z-index:2; border:1.5px solid var(--gold); border-radius:13px; background:rgba(176,138,62,.07); pointer-events:none; }
.tt-group-count { position:absolute; top:-10px; left:-10px; min-width:20px; height:20px; border-radius:10px; background:var(--gold); color:#fff;
  font-family:var(--ttm); font-size:10px; font-weight:500; display:flex; align-items:center; justify-content:center; padding:0 5px; box-shadow:0 1px 3px rgba(42,32,23,.4); pointer-events:none; }
.tt-group-del { position:absolute; top:-10px; right:-10px; width:22px; height:22px; border-radius:50%; border:1px solid var(--ink20); background:var(--card); color:var(--ink70);
  line-height:1; display:flex; align-items:center; justify-content:center; pointer-events:auto; cursor:pointer; transition:background .14s ease,color .14s ease,border-color .14s ease; }
.tt-group-del svg { width:12px; height:12px; display:block; }
.tt-group-del:hover { background:var(--blood); color:#f3ead7; border-color:var(--blood); }
.tt-group-split { position:absolute; bottom:-10px; left:-10px; width:22px; height:22px; border-radius:50%; border:1px solid var(--ink20); background:var(--card); color:var(--ink70);
  line-height:1; display:flex; align-items:center; justify-content:center; pointer-events:auto; cursor:pointer; transition:background .14s ease,color .14s ease,border-color .14s ease; }
.tt-group-split svg { width:12px; height:12px; display:block; }
.tt-group-split:hover { background:var(--gold); color:#fff; border-color:var(--gold); }
.tt-group-label { position:absolute; top:calc(100% + 7px); left:50%; transform:translateX(-50%); width:170px; text-align:center; border:0; background:transparent; pointer-events:auto;
  font-family:var(--ttm); font-size:10px; letter-spacing:0.08em; text-transform:uppercase; color:var(--ink); padding:3px 4px; border-bottom:1px solid var(--ink20); }
.tt-group-label::placeholder { color:var(--ink35); text-transform:none; letter-spacing:0.04em; }
.tt-group-label:focus { outline:none; border-bottom-color:var(--gold); }

.tt-count { position:absolute; top:-9px; left:-9px; z-index:8; min-width:19px; height:19px; border-radius:10px; background:var(--blood); color:#f3ead7;
  font-family:var(--ttm); font-size:10px; font-weight:500; display:flex; align-items:center; justify-content:center; padding:0 5px; box-shadow:0 1px 3px rgba(42,32,23,.4); pointer-events:none; }

.tt-tcard { position:relative; width:var(--tt-card-w); height:var(--tt-card-h); border-radius:7px; user-select:none; transition:box-shadow .18s ease; box-shadow:0 2px 6px rgba(42,32,23,.16); }
.tt-position.tt-dragging .tt-cardstack { transform:scale(1.04); }
.tt-position.tt-dragging .tt-tcard { box-shadow:0 10px 24px rgba(42,32,23,.32); }

/* card back — themed per oracle */
.tt-tcard.tt-back { --b1:#9a2c1d; --b2:#7d2016; --edge:#5c160f; --accent:rgba(201,162,74,.62);
  background: repeating-linear-gradient(45deg, rgba(0,0,0,.06) 0 6px, transparent 6px 12px), linear-gradient(160deg,var(--b1),var(--b2)); border:1px solid var(--edge); }
.tt-tcard.tt-back.tt-sys-lenormand { --b1:#33407a; --b2:#232c54; --edge:#1a2143; --accent:rgba(201,176,118,.6); }
.tt-tcard.tt-back.tt-sys-rune { --b1:#565d65; --b2:#3a3f46; --edge:#272b30; --accent:rgba(214,209,198,.5); }
.tt-tcard.tt-back.tt-sys-iching { --b1:#33313f; --b2:#1f1d28; --edge:#14121b; --accent:rgba(201,162,74,.55); }
.tt-tcard.tt-back::before { content:""; position:absolute; inset:5px; border:1px solid var(--accent); border-radius:4px; }
.tt-tcard.tt-back::after { content:""; position:absolute; left:50%; top:50%; width:26px; height:26px; transform:translate(-50%,-50%) rotate(45deg); border:1.5px solid var(--accent); }

/* card face */
.tt-tcard.tt-face { background:var(--card); border:1px solid var(--card-edge); display:flex; flex-direction:column; align-items:center; justify-content:space-between; padding:9px 7px; text-align:center; --face-accent:var(--blood); }
.tt-tcard.tt-face.tt-sys-lenormand { --face-accent:#3a4683; }
.tt-tcard.tt-face.tt-sys-rune { --face-accent:#5d5448; background:#f1ece1; }
.tt-tcard.tt-face.tt-sys-iching { --face-accent:#9a7b2e; }
.tt-tcard.tt-face::before { content:""; position:absolute; inset:4px; border:1px solid var(--ink12); border-radius:4px; pointer-events:none; }
.tt-tcard.tt-face.tt-has-art { padding:0; overflow:hidden; }
.tt-tcard.tt-face.tt-has-art::before { display:none; }
.tt-card-art { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; background:var(--card); display:block; border-radius:7px; }
.tt-f-top, .tt-f-bot { font-family:var(--ttm); font-size:9px; letter-spacing:0.1em; text-transform:uppercase; color:var(--face-accent); z-index:1; }
.tt-f-name { font-family:var(--ttd); font-size:14px; line-height:1.15; color:var(--ink); z-index:1; display:flex; align-items:center; flex:1; }
.tt-f-rule { width:24px; height:1px; background:var(--ink20); }

.tt-rune-glyph { flex:1; display:flex; align-items:center; justify-content:center; z-index:1; font-size:50px; line-height:1; color:var(--ink);
  font-family:"Noto Sans Runic","Segoe UI Historic","Apple Symbols",var(--ttd); }

.tt-hexfig { flex:1; display:flex; flex-direction:column; gap:3px; align-items:center; justify-content:center; z-index:1; }
.tt-hx { display:block; height:5px; width:44px; background:var(--ink); border-radius:1px; }
.tt-hx.tt-yin { background:linear-gradient(90deg,var(--ink) 0 40%, transparent 40% 60%, var(--ink) 60% 100%); }
.tt-hexfig.tt-hexbig { gap:4px; } .tt-hexfig.tt-hexbig .tt-hx { height:6px; width:50px; }
.tt-hexfig.tt-hexmini { flex:0 0 auto; gap:2px; } .tt-hexfig.tt-hexmini .tt-hx { height:3px; width:22px; }

.tt-tcard.tt-flipping { animation:tt-cardflip .26s ease; will-change:transform; backface-visibility:hidden; }
@keyframes tt-cardflip { 0%,100% { transform:scaleX(1); } 50% { transform:scaleX(.04); } }

/* empty / ghost slot from a loaded spread */
.tt-tcard.tt-ghost { background:transparent; border:1.5px dashed var(--ink20); box-shadow:none; display:flex; align-items:center; justify-content:center; color:var(--ink20); cursor:pointer; transition:border-color .14s ease,color .14s ease,background .14s ease; }
.tt-gmark { font-size:26px; font-weight:300; line-height:1; }
.tt-ghint { position:absolute; bottom:9px; font-family:var(--ttm); font-size:8px; letter-spacing:0.12em; text-transform:uppercase; color:var(--blood); opacity:0; transition:opacity .14s ease; }
.tt-tcard.tt-ghost:hover { border-color:var(--blood); color:var(--blood); background:rgba(138,38,26,.06); }
.tt-tcard.tt-ghost:hover .tt-ghint { opacity:1; }
.tt-tcard.tt-ghost.tt-drop-hot { border-color:var(--blood); color:var(--blood); background:rgba(138,38,26,.1); border-style:solid; box-shadow:0 0 0 2px rgba(138,38,26,.25); }

/* label under a card */
.tt-label-wrap { display:flex; flex-direction:column; align-items:center; gap:5px; width:150px; }
.tt-pos-label { width:100%; text-align:center; border:0; background:transparent; font-family:var(--ttm); font-size:10px; letter-spacing:0.06em; text-transform:uppercase; color:var(--ink70); padding:3px 4px; border-bottom:1px solid transparent; transition:border-color .15s ease; }
.tt-pos-label::placeholder { color:var(--ink35); text-transform:none; letter-spacing:0.04em; }
.tt-pos-label:focus { outline:none; border-bottom-color:var(--ink20); color:var(--ink); }
.tt-position.tt-selected .tt-pos-label { border-bottom-color:var(--ink12); }

.tt-chips { display:none; flex-wrap:wrap; gap:4px; justify-content:center; max-width:150px; }
.tt-position.tt-selected.tt-label-empty .tt-chips.on { display:flex; }
.tt-chip { font-family:var(--ttm); font-size:9px; letter-spacing:0.06em; color:var(--ink70); background:var(--panel); border:1px solid var(--ink12); border-radius:11px; padding:3px 8px; }
.tt-chip:hover { border-color:var(--blood); color:var(--blood); }

/* per-card hover controls */
.tt-cbtn { position:absolute; width:22px; height:22px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:13px; line-height:1; border:1px solid var(--ink20);
  background:var(--card); color:var(--ink70); opacity:0; transform:scale(.85); transition:opacity .14s ease,transform .14s ease,background .14s ease,color .14s ease; z-index:3; }
.tt-position:hover .tt-cbtn, .tt-position.tt-selected .tt-cbtn { opacity:1; transform:scale(1); }
.tt-cbtn svg { width:12px; height:12px; display:block; }
.tt-cbtn.tt-trash { top:-9px; right:-9px; }
.tt-cbtn.tt-trash:hover { background:var(--blood); color:#f3ead7; border-color:var(--blood); }
.tt-cbtn.tt-minus { top:-9px; right:20px; font-size:16px; }
.tt-cbtn.tt-minus:hover { background:var(--blood); color:#f3ead7; border-color:var(--blood); }
.tt-cbtn.tt-flip { bottom:-9px; right:-9px; }
.tt-cbtn.tt-flip:hover { background:var(--ink); color:var(--field); border-color:var(--ink); }
.tt-cbtn.tt-add { bottom:-9px; left:-9px; font-size:15px; }
.tt-cbtn.tt-add:hover { background:var(--gold); color:#fff; border-color:var(--gold); }
.tt-cbtn.tt-spin { animation:tt-spin .4s ease; }
@keyframes tt-spin { to { transform:rotate(360deg) scale(1); } }

/* ── Floating dock ───────────────────────────────────────────────── */
.tt-dock { position:absolute; left:50%; bottom:22px; transform:translateX(-50%); display:flex; align-items:stretch; gap:0; z-index:25; background:var(--ink); border-radius:16px; padding:9px; box-shadow:0 10px 30px rgba(42,32,23,.34); }
.tt-dock-group { display:flex; align-items:center; gap:4px; padding:0 9px; }
.tt-dock-div { width:1px; margin:6px 0; background:rgba(243,234,215,.16); }
.tt-dock-group.tt-sources { gap:5px; padding:0 8px; }
.tt-source { display:flex; align-items:center; gap:8px; padding:5px 10px 5px 5px; border-radius:11px; background:transparent; border:1px solid transparent; cursor:grab; user-select:none; touch-action:none; position:relative; transition:background .14s ease,border-color .14s ease; }
.tt-source:hover { background:rgba(243,234,215,.08); }
.tt-source:active { cursor:grabbing; }
.tt-source.tt-empty { opacity:.34; cursor:not-allowed; }
.tt-src-visual { position:relative; width:34px; height:48px; border-radius:6px; flex:0 0 auto; overflow:hidden; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(160deg,var(--b1),var(--b2)); border:1px solid var(--edge); box-shadow:0 1px 3px rgba(0,0,0,.32); }
.tt-source[data-system="tarot"] .tt-src-visual { --b1:#9a2c1d; --b2:#7d2016; --edge:#5c160f; }
.tt-source[data-system="lenormand"] .tt-src-visual { --b1:#33407a; --b2:#232c54; --edge:#1a2143; }
.tt-source[data-system="rune"] .tt-src-visual { --b1:#565d65; --b2:#3a3f46; --edge:#272b30; }
.tt-source[data-system="iching"] .tt-src-visual { --b1:#33313f; --b2:#1f1d28; --edge:#14121b; }
.tt-dock-diamond { width:15px; height:15px; border:1.5px solid rgba(201,162,74,.82); transform:rotate(45deg); }
.tt-dock-pip { font-family:var(--ttm); font-size:11px; font-weight:500; color:rgba(201,176,118,.95); }
.tt-dock-rune { font-size:20px; line-height:1; color:rgba(214,209,198,.92); font-family:"Noto Sans Runic","Segoe UI Historic","Apple Symbols",serif; }
.tt-src-visual .tt-hexfig.tt-hexmini { width:16px; gap:2px; }
.tt-src-visual .tt-hexfig.tt-hexmini .tt-hx { width:16px; background:rgba(201,162,74,.85); }
.tt-src-visual .tt-hexfig.tt-hexmini .tt-hx.tt-yin { background:linear-gradient(90deg,rgba(201,162,74,.85) 0 40%, transparent 40% 60%, rgba(201,162,74,.85) 60% 100%); }
.tt-src-meta { display:flex; flex-direction:column; gap:1px; line-height:1.2; align-items:flex-start; }
.tt-src-name { font-family:var(--ttm); font-size:10px; letter-spacing:0.08em; text-transform:uppercase; color:#f3ead7; white-space:nowrap; }
.tt-src-count { font-family:var(--ttm); font-size:10px; color:rgba(243,234,215,.5); }

.tt-tool { width:36px; height:36px; border-radius:9px; border:1px solid transparent; background:transparent; color:rgba(243,234,215,.66); display:flex; align-items:center; justify-content:center; transition:background .14s ease,color .14s ease,border-color .14s ease; position:relative; }
.tt-tool svg { width:18px; height:18px; display:block; }
.tt-tool:hover { background:rgba(243,234,215,.09); color:#f3ead7; }
.tt-tool.tt-active { background:var(--blood); color:#f3ead7; }
.tt-tool:disabled { opacity:.32; cursor:not-allowed; }
.tt-tool:disabled:hover { background:transparent; color:rgba(243,234,215,.66); }

.tt-tool[data-tip]:hover::after, .tt-source[data-tip]:hover::after {
  content:attr(data-tip); position:absolute; left:50%; bottom:calc(100% + 9px); transform:translateX(-50%);
  font-family:var(--ttm); font-size:10px; letter-spacing:0.06em; white-space:nowrap; background:var(--ink); color:#f3ead7;
  border:1px solid rgba(243,234,215,.18); padding:4px 8px; border-radius:5px; pointer-events:none; z-index:40; }

/* drag ghost — themed per system */
.tt-ghost-card { --b1:#9a2c1d; --b2:#7d2016; --edge:#5c160f; --accent:rgba(201,162,74,.55);
  position:fixed; width:var(--tt-card-w); height:var(--tt-card-h); border-radius:7px; pointer-events:none; z-index:60; transform:translate(-50%,-50%) rotate(-3deg);
  box-shadow:0 12px 28px rgba(42,32,23,.4); background:repeating-linear-gradient(45deg, rgba(0,0,0,.06) 0 6px, transparent 6px 12px), linear-gradient(160deg,var(--b1),var(--b2)); border:1px solid var(--edge); }
.tt-ghost-card.tt-sys-lenormand { --b1:#33407a; --b2:#232c54; --edge:#1a2143; --accent:rgba(201,176,118,.55); }
.tt-ghost-card.tt-sys-rune { --b1:#565d65; --b2:#3a3f46; --edge:#272b30; --accent:rgba(214,209,198,.45); }
.tt-ghost-card.tt-sys-iching { --b1:#33313f; --b2:#1f1d28; --edge:#14121b; --accent:rgba(201,162,74,.5); }
.tt-ghost-card::after { content:""; position:absolute; inset:5px; border:1px solid var(--accent); border-radius:4px; }

/* ── Spreads popover ─────────────────────────────────────────────── */
.tt-pop { position:absolute; bottom:84px; left:50%; transform:translateX(-50%); width:300px; background:var(--card); border:1px solid var(--ink20); border-radius:12px; box-shadow:0 16px 40px rgba(42,32,23,.3); padding:16px; z-index:35; display:none; }
.tt-pop.open { display:block; }
.tt-pop-head { display:flex; align-items:baseline; justify-content:space-between; margin-bottom:12px; }
.tt-pop-head .tt-eyebrow { color:var(--blood); }
.tt-pop-save { font-family:var(--ttm); font-size:10px; letter-spacing:0.1em; text-transform:uppercase; color:var(--ink70); background:none; border:0; padding:0; border-bottom:1px solid var(--ink20); }
.tt-pop-save:hover { color:var(--blood); border-color:var(--blood); }
.tt-pop-save:disabled { opacity:.4; cursor:not-allowed; }
.tt-spread-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; max-height:280px; overflow:auto; }
.tt-spread-card { display:flex; align-items:center; gap:12px; padding:9px; border:1px solid var(--ink12); border-radius:8px; background:var(--field); cursor:pointer; transition:border-color .14s ease,background .14s ease; position:relative; }
.tt-spread-card:hover { border-color:var(--blood); background:#efe7d3; }
.tt-mini { position:relative; width:52px; height:40px; flex:0 0 auto; background:var(--panel); border:1px solid var(--ink12); border-radius:4px; overflow:hidden; }
.tt-mini i { position:absolute; width:8px; height:12px; border-radius:1.5px; border:1px dashed var(--ink35); transform:translate(-50%,-50%); }
.tt-spread-meta { flex:1 1 auto; min-width:0; }
.tt-sm-name { font-family:var(--ttd); font-size:15px; color:var(--ink); }
.tt-sm-count { font-family:var(--ttm); font-size:9.5px; letter-spacing:0.08em; color:var(--ink50); text-transform:uppercase; }
.tt-spread-del { flex:0 0 auto; width:24px; height:24px; border-radius:6px; border:1px solid var(--ink12); background:var(--card); color:var(--ink50); display:flex; align-items:center; justify-content:center; cursor:pointer; transition:background .14s ease,color .14s ease,border-color .14s ease; }
.tt-spread-del svg { width:12px; height:12px; }
.tt-spread-del:hover { background:var(--blood); color:#f3ead7; border-color:var(--blood); }
.tt-spread-empty { font-family:var(--ttd); color:var(--ink50); font-size:14px; margin:4px 0 0; }
.tt-pop-saverow { display:none; gap:8px; margin-top:12px; }
.tt-pop-saverow.on { display:flex; }
.tt-pop-saverow input { flex:1; border:1px solid var(--ink20); border-radius:6px; background:var(--field); font-family:var(--ttm); font-size:12px; color:var(--ink); padding:7px 9px; }
.tt-pop-saverow input:focus { outline:none; border-color:var(--blood); }
.tt-pop-saverow button { font-family:var(--ttm); font-size:10px; letter-spacing:0.08em; text-transform:uppercase; color:#f3ead7; background:var(--blood); border:0; border-radius:6px; padding:0 12px; }

/* ── Display settings popover ────────────────────────────────────── */
.tt-pop.tt-settings { width:236px; }
.tt-setting { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:8px 0; }
.tt-setting + .tt-setting { border-top:1px solid var(--ink12); }
.tt-s-name { font-family:var(--ttd); font-size:14px; color:var(--ink); }
.tt-s-sub { font-family:var(--ttm); font-size:9px; letter-spacing:0.04em; color:var(--ink50); margin-top:1px; }
.tt-switch { width:38px; height:22px; border-radius:11px; background:var(--ink20); border:0; position:relative; flex:0 0 auto; transition:background .16s ease; }
.tt-switch::after { content:""; position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:50%; background:var(--card); box-shadow:0 1px 2px rgba(0,0,0,.25); transition:transform .16s ease; }
.tt-switch.on { background:var(--blood); }
.tt-switch.on::after { transform:translateX(16px); }

/* ── Read-together commit sheet ──────────────────────────────────── */
.tt-scrim { position:absolute; inset:0; background:rgba(42,32,23,.46); z-index:50; display:none; align-items:center; justify-content:center; }
.tt-scrim.open { display:flex; }
.tt-sheet { width:420px; max-width:90%; background:var(--card); border:1px solid var(--ink20); border-radius:14px; padding:30px 32px; box-shadow:0 24px 60px rgba(42,32,23,.4); }
.tt-sheet .tt-eyebrow { color:var(--blood); }
.tt-sheet h2 { font-family:var(--ttd); font-weight:500; font-size:27px; margin:10px 0 12px; letter-spacing:-0.01em; }
.tt-sheet p { font-family:var(--ttd); font-size:15.5px; color:var(--ink70); margin:0 0 22px; line-height:1.55; }
.tt-sheet-actions { display:flex; gap:12px; align-items:center; }
.tt-btn-primary { font-family:var(--ttm); font-size:11px; letter-spacing:0.14em; text-transform:uppercase; color:#f3ead7; background:var(--blood); border:0; border-radius:22px; padding:11px 22px; }
.tt-btn-primary:hover { background:var(--blood-dk); }
.tt-btn-primary:disabled { opacity:.5; cursor:default; }
.tt-btn-ghost { font-family:var(--ttm); font-size:11px; letter-spacing:0.12em; text-transform:uppercase; color:var(--ink70); background:none; border:0; padding:11px 6px; }
.tt-btn-ghost:hover { color:var(--blood); }

/* ── "+ add a draw" menu ─────────────────────────────────────────── */
.tt-add-menu { position:absolute; z-index:45; background:var(--ink); border-radius:12px; padding:10px; box-shadow:0 14px 34px rgba(42,32,23,.42); display:none; }
.tt-add-menu.open { display:block; }
.tt-am-head { font-family:var(--ttm); font-size:9px; letter-spacing:0.18em; text-transform:uppercase; color:rgba(243,234,215,.5); margin:2px 4px 8px; }
.tt-am-row { display:flex; gap:6px; }
.tt-am-opt { display:flex; flex-direction:column; align-items:center; gap:6px; width:58px; padding:8px 4px; border-radius:9px; background:rgba(243,234,215,.06); border:1px solid transparent; cursor:pointer; transition:background .14s ease,border-color .14s ease; }
.tt-am-opt:hover { background:rgba(243,234,215,.13); border-color:rgba(243,234,215,.22); }
.tt-am-vis { position:relative; width:26px; height:36px; border-radius:5px; display:flex; align-items:center; justify-content:center; background:linear-gradient(160deg,var(--b1),var(--b2)); border:1px solid var(--edge); }
.tt-am-opt.tt-sys-tarot .tt-am-vis { --b1:#9a2c1d; --b2:#7d2016; --edge:#5c160f; }
.tt-am-opt.tt-sys-lenormand .tt-am-vis { --b1:#33407a; --b2:#232c54; --edge:#1a2143; }
.tt-am-opt.tt-sys-rune .tt-am-vis { --b1:#565d65; --b2:#3a3f46; --edge:#272b30; }
.tt-am-opt.tt-sys-iching .tt-am-vis { --b1:#33313f; --b2:#1f1d28; --edge:#14121b; }
.tt-am-vis .tt-dock-diamond { width:13px; height:13px; }
.tt-am-vis .tt-dock-rune { font-size:16px; }
.tt-am-vis .tt-dock-pip { font-size:9px; }
.tt-am-vis .tt-hexfig.tt-hexmini .tt-hx { width:18px; height:2.5px; background:rgba(201,162,74,.85); }
.tt-am-vis .tt-hexfig.tt-hexmini .tt-hx.tt-yin { background:linear-gradient(90deg,rgba(201,162,74,.85) 0 40%, transparent 40% 60%, rgba(201,162,74,.85) 60% 100%); }
.tt-am-name { font-family:var(--ttm); font-size:8.5px; letter-spacing:0.03em; color:#f3ead7; text-transform:uppercase; }

/* ── Saved-reading view (read-only render of the bound table) ────── */
.tt-saved-table { background:var(--field); color:var(--ink); font-family:var(--ttd); border:1px solid var(--ink12); border-radius:6px; margin:var(--space-5); padding:0; }
.tt-saved-table .tt-canvas { position:relative; inset:auto; min-height:72vh; }
.tt-saved-table .tt-cardstack { cursor:default; }
.tt-saved-table .tt-pos-label-static { width:150px; text-align:center; font-family:var(--ttm); font-size:10px; letter-spacing:0.06em; text-transform:uppercase; color:var(--ink70); }
.tt-saved-table .tt-group-label-static { position:absolute; top:calc(100% + 7px); left:50%; transform:translateX(-50%); width:170px; text-align:center; font-family:var(--ttm); font-size:10px; letter-spacing:0.08em; text-transform:uppercase; color:var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .tt-builder *, .tt-saved-table * { transition-duration:.001ms !important; animation-duration:.001ms !important; }
}

/* ====================================================================
   "Read together" — the synthesis drafting loader (ported from the
   design handoff). The aperture sigil attends, then settles and streams
   the synthesis. Built into any `.rt-mount` by static/js/read-together.js.
   All selectors namespaced .rt-*; one warm "table" palette.
   ==================================================================== */

.rt-sheet {
  --rt-card:      var(--paper-warm);
  --rt-card-edge: #d4c8a4;
  --rt-ink:       #2a2017;
  --rt-ink70:     rgba(42,32,23,0.70);
  --rt-ink50:     rgba(42,32,23,0.50);
  --rt-ink20:     rgba(42,32,23,0.20);
  --rt-blood:     #8a261a;
  --rt-mono:      "DM Mono", ui-monospace, "JetBrains Mono", monospace;
  --rt-display:   var(--serif, "Fraunces", Georgia, serif);

  width: min(92%, 960px);
  margin: var(--space-3, 12px) auto 0;
  background: var(--rt-card);
  border: 1px solid var(--rt-card-edge);
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(42,32,23,.40);
  padding: 44px 52px 36px;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.rt-eyebrow {
  font-family: var(--rt-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--rt-blood);
}

/* ── the animated aperture ─────────────────────────────────────────── */
.rt-aperture { width: 108px; height: 108px; margin: 30px auto 8px; display: block; }
.rt-aperture * { transform-box: fill-box; transform-origin: center; }
.rt-inner  { animation: rt-breathe 3.4s ease-in-out infinite; }
.rt-gnomon { animation: rt-sweep 5.6s cubic-bezier(.45,0,.55,1) infinite; }
.rt-dot    { animation: rt-pulse 1.7s ease-in-out infinite; }
.rt-ripple { animation: rt-ripple 3s ease-out infinite; }
.rt-ripple.rt-two { animation-delay: 1.5s; }

@keyframes rt-breathe { 0%,100% { transform: scale(.88); opacity: .18; } 50% { transform: scale(1); opacity: .5; } }
@keyframes rt-pulse   { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.34); opacity: .8; } }
@keyframes rt-ripple  { 0% { transform: scale(.5); opacity: .45; } 100% { transform: scale(1.7); opacity: 0; } }
@keyframes rt-sweep   { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* drafting phase: the search settles, the heartbeat stays */
.rt-sheet.rt-drafting .rt-gnomon { animation-duration: 14s; opacity: .5; }
.rt-sheet.rt-drafting .rt-ripple { animation: none; opacity: 0; }
.rt-sheet.rt-drafting .rt-inner  { animation-duration: 5s; }

/* ── status line (phase 1) ─────────────────────────────────────────── */
.rt-status { height: 18px; margin-top: 14px; font-family: var(--rt-mono); font-size: 11px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--rt-ink50); position: relative; }
.rt-status span { position: absolute; left: 0; right: 0; opacity: 0; transition: opacity .5s ease; }
.rt-status span.rt-on { opacity: 1; }
.rt-dots::after { content: ""; animation: rt-dots 1.4s steps(4,end) infinite; }
@keyframes rt-dots { 0% { content: ""; } 25% { content: "·"; } 50% { content: "· ·"; } 75% { content: "· · ·"; } }

/* ── synthesis prose (phase 2) ─────────────────────────────────────── */
.rt-synth { margin-top: 22px; min-height: 96px; text-align: left; }
.rt-synth .rt-p { font-family: var(--rt-display); font-size: 18px; font-weight: 300;
  line-height: 1.6; color: var(--rt-ink70); margin: 0 0 0.7em; text-wrap: pretty; }
.rt-synth .rt-p:last-child { margin-bottom: 0; }
.rt-caret { display: inline-block; width: 2px; height: 1.05em; background: var(--rt-blood);
  margin-left: 1px; vertical-align: -2px; animation: rt-blink 1s steps(2,end) infinite; }
@keyframes rt-blink { 50% { opacity: 0; } }
.rt-synth.rt-done .rt-caret { display: none; }

/* ── drafting failed: say so, offer one deliberate retry ───────────── */
.rt-fail {
  margin-top: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}
.rt-fail-note {
  font-family: var(--rt-mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--rt-ink50);
}
.rt-retry {
  font-family: var(--rt-mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--rt-blood);
  background: none;
  border: 1px solid currentColor;
  padding: 8px 14px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.rt-retry:hover {
  background: var(--rt-blood);
  color: var(--rt-card);
}

/* Three Card's bounded answer: Read Together becomes a numbered ledger
   after the reader submits their one statement. It borrows the synthesis
   sheet's paper and blood-red rubric without turning the exchange into chat. */
.reading-dialogue {
  --rd-paper: var(--paper-warm);
  --rd-ink: #2a2017;
  --rd-muted: rgba(42, 32, 23, 0.66);
  --rd-faint: rgba(42, 32, 23, 0.38);
  --rd-rule: rgba(42, 32, 23, 0.18);
  --rd-red: #8a261a;
  max-width: 760px;
  margin: 28px auto 0;
  padding: 34px 42px 38px;
  background: var(--rd-paper);
  border: 1px solid #d4c8a4;
  border-radius: 14px;
  color: var(--rd-ink);
  text-align: left;
}
.reading-dialogue [hidden] { display: none !important; }
.rd-rule {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 25px;
}
.rd-rule::before,
.rd-rule::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--rd-rule);
}
.rd-rule span {
  width: 5px;
  height: 5px;
  border: 1px solid var(--rd-red);
  transform: rotate(45deg);
}
.rd-step {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rd-red);
}
.rd-number {
  display: inline-flex;
  width: 23px;
  height: 23px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rd-red);
  border-radius: 50%;
  font-size: 10px;
  letter-spacing: 0;
  background: var(--rd-paper);
}
.reading-dialogue h3 {
  margin: 0;
  font-family: var(--serif);
  font-size: 27px;
  font-weight: 450;
  line-height: 1.15;
  color: var(--rd-ink);
}
.rd-guidance {
  max-width: 58ch;
  margin: 10px 0 22px;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.55;
  color: var(--rd-muted);
}
.rd-answer,
.rd-consequence {
  display: block;
  width: 100%;
  min-height: 96px;
  padding: 13px 0;
  border: 0;
  border-top: 1px solid var(--rd-rule);
  border-bottom: 1px solid var(--rd-rule);
  border-radius: 0;
  background: transparent;
  resize: vertical;
  outline: none;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.5;
  color: var(--rd-ink);
}
.rd-answer:focus,
.rd-consequence:focus { border-color: var(--rd-red); }
.rd-answer::placeholder,
.rd-consequence::placeholder { color: var(--rd-faint); }
.rd-field-meta {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 8px;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rd-faint);
}
.rd-error {
  min-height: 17px;
  margin: 9px 0 0;
  font-family: var(--mono);
  font-size: 10px;
  line-height: 1.45;
  color: var(--rd-red);
}
.rd-submit-answer,
.rd-close {
  width: 100%;
  min-height: 48px;
  margin-top: 10px;
  border: 1px solid var(--rd-red);
  background: var(--rd-red);
  color: var(--rd-paper);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.rd-submit-answer:hover,
.rd-close:hover { background: #712016; }
.rd-submit-answer:disabled,
.rd-close:disabled { cursor: wait; opacity: 0.68; }
.rd-ledger {
  position: relative;
  padding-left: 16px;
  border-left: 1px solid rgba(138, 38, 26, 0.34);
}
.rd-ledger-section {
  position: relative;
  padding: 0 0 28px 18px;
}
.rd-ledger-section:last-child { padding-bottom: 4px; }
.rd-ledger-section .rd-number {
  position: absolute;
  left: -47px;
  top: -4px;
  background: var(--rd-red);
  color: var(--rd-paper);
}
.rd-answer-copy {
  margin: 0;
  padding: 0;
  border: 0;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.52;
  color: var(--rd-muted);
}
.rd-reply-copy p {
  margin: 0 0 0.85em;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.58;
  color: var(--rd-ink);
}
.rd-reply-copy p:last-child { margin-bottom: 0; }
.rd-reply-status {
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 28px;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--rd-faint);
}
.rd-reply-pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rd-red);
  animation: rd-pulse 1.5s ease-in-out infinite;
}
@keyframes rd-pulse { 50% { opacity: 0.28; transform: scale(0.72); } }
.rd-retry-reply {
  margin-top: 13px;
  padding: 7px 0;
  border: 0;
  background: none;
  color: var(--rd-red);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.rd-stems {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 18px;
  padding: 0;
  border: 0;
}
.rd-stems label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 39px;
  padding: 8px 10px;
  border: 1px solid var(--rd-rule);
  font-family: var(--serif);
  font-size: 14px;
  color: var(--rd-muted);
  cursor: pointer;
}
.rd-stems label:has(input:checked) {
  border-color: var(--rd-red);
  color: var(--rd-ink);
  background: rgba(138, 38, 26, 0.055);
}
.rd-stems input { accent-color: var(--rd-red); }
.rd-complete {
  padding-top: 4px;
}
.rd-conclusion {
  margin: 18px 0 0;
  padding: 18px 0;
  border-top: 1px solid var(--rd-rule);
  border-bottom: 1px solid var(--rd-rule);
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.5;
  color: var(--rd-ink);
}
.rd-conclusion-stem { color: var(--rd-red); }
.rd-saved-note {
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: 9px;
  line-height: 1.5;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--rd-faint);
}
.rd-complete-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin-top: 19px;
}
.rd-complete-actions a,
.rd-complete-actions button {
  padding: 7px 0;
  border: 0;
  background: none;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--rd-muted);
  cursor: pointer;
}
.rd-complete-actions a:hover,
.rd-complete-actions button:hover { color: var(--rd-red); }

@media (prefers-reduced-motion: reduce) {
  .rt-inner, .rt-gnomon, .rt-dot, .rt-ripple, .rt-dots::after, .rt-caret,
  .rd-reply-pulse { animation: none !important; }
  .rt-ripple { opacity: 0; }
}

/* ── Phones: text-entry floor ──────────────────────────────────────
   iOS Safari zooms the whole page when a focused control's font is
   under 16px. Hold every text-entry control at 16px on phones; the
   mono controls keep their tracking, just a step larger. */
@media (max-width: 720px) {
  input[type="text"],
  input[type="password"],
  input[type="search"],
  input[type="number"],
  input[type="email"],
  select,
  textarea {
    font-size: 16px;
  }
}

/* =====================================================================
   Mobile three-card reading — the "6a" fold/draw redesign.
   Structure server-rendered in three_card_reading.html; the
   overview->detail state machine and per-card transforms are driven by
   reading-mobile.js (it sets the dynamic inline styles; the base look
   and transitions live here). Parchment theme only (the reading page
   sets it), so the tokens below resolve to the handoff's exact hexes.
   ===================================================================== */

/* Hidden on desktop; the media query at the bottom flips desktop <->
   mobile. Kept out of the media query so the default is display:none. */
.tcm { display: none; }

.tcm-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
}
.tcm-readingno {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.tcm-saved {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
}
.tcm-meta-detail {
  padding: 0 18px 12px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--fg-muted);
}

.tcm-question {
  padding: 6px 18px 18px;
  border-bottom: 1px solid var(--rule);
}
.tcm-q-eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 6px;
}
.tcm-q-text {
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.32;
  margin: 0;
}

/* Back-link + position dots, revealed once settled in detail. */
.tcm-detail-header {
  padding: 0 18px;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.22s ease, max-height 0.24s ease, padding 0.24s ease;
}
.tcm-detail-header.is-open {
  max-height: 110px;
  padding: 14px 18px 0;
}
.tcm-detail-header.is-visible { opacity: 1; }
/* Ghost button — bordered, red on press (no hover on touch). Shared by
   the "‹ Overview" and "‹ Back to the reading" back buttons. */
.tcm-ghost {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  min-height: 40px;
  padding: 0 16px;
  background: transparent;
  border: 1px solid var(--fg-faint);
  color: var(--fg-muted);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.tcm-ghost:active {
  background: rgba(161, 52, 52, 0.08);
  border-color: var(--red);
  color: var(--red);
}
.tcm-back {
  margin-bottom: 8px;
}
.tcm-dots {
  display: flex;
  justify-content: center;
  gap: 7px;
  padding: 4px 0 2px;
}
.tcm-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: var(--rule);
}

.tcm-spread-eyebrow {
  text-align: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 18px 0 12px;
  max-height: 30px;
  overflow: hidden;
  opacity: 1;
  transition: opacity 0.2s ease, margin 0.24s ease, max-height 0.24s ease;
}
.tcm-spread-eyebrow.is-collapsed {
  margin: 0;
  max-height: 0;
  opacity: 0;
}

/* The fanned row: three cards held like a hand, one drawn into focus.
   `pan-y` lets the page still scroll vertically while reading-mobile.js
   claims horizontal drags for the swipe-between-cards gesture. */
.tcm-row {
  position: relative;
  display: flex;
  gap: 10px;
  justify-content: center;
  align-items: flex-end;
  padding: 10px 26px 0;
  touch-action: pan-y;
}

/* The neighbouring cards, waiting in shadow at the row's edges while one
   card is being read. Darkened rather than merely faded, so they read as
   cards lying just outside the light. Shown only in the detail view, and
   only where a neighbour actually exists (.has-card). */
.tcm-peek {
  position: absolute;
  bottom: 0;
  width: 22%;
  aspect-ratio: 293 / 567;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  opacity: 0;
  filter: brightness(0.4);
  transform: scale(0.82);
  pointer-events: none;
  transition: opacity 0.26s ease, transform 0.26s ease;
}
.tcm-peek-prev { left: 0; transform-origin: left bottom; }
.tcm-peek-next { right: 0; transform-origin: right bottom; }
.tcm-row.is-detail .tcm-peek.has-card { opacity: 0.55; }
.tcm-card-wrap {
  /* Size the fanned cards via flex-basis, not width: as flex items in
     the row, a definite flex-basis is what actually drives the main
     size (width is overridden by flex layout here), and it animates
     the fold cleanly. min-width:0 lets it collapse to 0 on fold. */
  flex: 0 0 31%;
  min-width: 0;
  opacity: 1;
  cursor: pointer;
  transition: flex-basis 0.32s cubic-bezier(.4, 0, .2, 1), opacity 0.24s ease;
}
.tcm-card {
  width: 100%;
  aspect-ratio: 293 / 567;
  transform-origin: bottom center;
  transition: transform 0.32s cubic-bezier(.4, 0, .2, 1), box-shadow 0.3s ease;
}
.tcm-art {
  width: 100%;
  height: 100%;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  transition: opacity 0.22s ease;
}
.tcm-caption {
  font-family: var(--serif);
  font-size: 13px;
  text-align: center;
  margin: 6px 0 0;
  line-height: 1.2;
  max-height: 32px;
  overflow: hidden;
  transition: opacity 0.2s ease, max-height 0.24s ease, margin 0.24s ease;
}
.tcm-caption.is-hidden {
  opacity: 0;
  max-height: 0;
  margin: 0;
}

/* Single-card detail text, fading in once the card settles. The deep
   bottom padding reserves clearance so the quote never sits under the
   fixed footer (which is genuinely fixed, so padding is the only way). */
.tcm-detail {
  padding: 10px 18px 260px;
  opacity: 0;
  transition: opacity 0.26s ease;
}
.tcm-detail.is-hidden { display: none; }
.tcm-detail-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.tcm-detail-elrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 220px;
}
.tcm-detail-glyph {
  width: 15px;
  height: 15px;
  opacity: 0.7;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
.tcm-detail-element {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.tcm-detail-name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 28px;
  line-height: 1.05;
  margin: 6px 0 0;
  text-align: center;
}
.tcm-detail-subtitle {
  font-family: var(--serif);
  font-size: 16px;
  margin: 0;
}
.tcm-detail-quote {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.5;
  color: var(--fg-muted);
  text-align: center;
  margin: 8px 0 4px;
  max-width: 300px;
}

/* Fixed footer — one control always a thumb-reach away, its label and
   job shifting with context. Buttons default to their engaged red state
   (no hover to lean on) and darken on press. */
.tcm-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  background: var(--bg);
  padding: 16px 20px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -6px 18px rgba(92, 22, 15, 0.14);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tcm-primary {
  width: 100%;
  min-height: 52px;
  background: var(--red);
  color: var(--bg);
  border: 0;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  transition: background-color 0.12s ease, transform 0.12s ease;
}
.tcm-primary:active {
  background: #843333;
  transform: translateX(1px);
}
.tcm-footer-dots { display: flex; gap: 5px; }
.tcm-fdot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(241, 232, 208, 0.4);
}
/* Read Together — a sheet that peeks above the footer; tap or drag the
   grip to expand. reading-mobile.js sets the transform during a drag and
   toggles .is-expanded / .is-dragging; the peeked base and snap
   transition live here. Sits below the footer (z 30 < footer 40). */
.tcm-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 84px;
  z-index: 30;
  /* Stop the expanded sheet below the site header rather than letting it
     run to the top, where it slid under the mobile browser's URL bar.
     dvh (where supported) measures the *visible* viewport, so the sheet
     doesn't hide behind browser chrome that vh happily ignores. */
  max-height: calc(100vh - 220px);
  max-height: calc(100dvh - 220px);
  background: var(--bg);
  border-top: 1px solid var(--rule);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -10px 28px rgba(0, 0, 0, 0.16);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateY(calc(100% - 58px));
  transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1),
              bottom 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}
.tcm-sheet.is-expanded { transform: translateY(0); }
.tcm-sheet--dialogue.is-expanded {
  bottom: 0;
  z-index: 45;
  max-height: calc(100vh - 180px);
  max-height: calc(100dvh - 180px);
}
.tcm-sheet.is-dragging { transition: none; }
.tcm-sheet-grip {
  flex-shrink: 0;
  padding: 10px 22px 12px;
  cursor: grab;
  touch-action: none;
  border-bottom: 1px solid var(--rule);
}
.tcm-sheet-grip:focus { outline: none; }
.tcm-sheet-grip:focus-visible {
  outline: 1px solid var(--red);
  outline-offset: -2px;
}
.tcm-sheet-handle {
  width: 36px;
  height: 4px;
  background: var(--fg-faint);
  border-radius: 2px;
  margin: 0 auto 12px;
}
.tcm-sheet-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
}
.tcm-sheet-chevron { color: var(--fg-muted); }
.tcm-sheet-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
}
.tcm-sheet-body {
  flex: 1;
  overflow: auto;
  padding: 18px 22px 26px;
}
.tcm-sheet-scroll .tcm-sheet-body {
  flex: none;
  overflow: visible;
}
.tcm-sheet-body .rt-sheet {
  width: 100%;
  margin: 0;
  padding: 12px 0 8px;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.tcm-sheet-body .rt-eyebrow { display: none; }
.tcm-sheet-body .rt-aperture {
  width: 82px;
  height: 82px;
  margin: 12px auto 4px;
}
.tcm-sheet-body .rt-synth { margin-top: 12px; }
.tcm-sheet-body .rt-synth .rt-p {
  font-size: 16px;
  line-height: 1.55;
}
.tcm-sheet-body .rt-sheet:has(.rt-synth.rt-done) .rt-aperture { display: none; }
.tcm-sheet--dialogue.rd-ledger-mode .tcm-sheet-body { display: none; }
.tcm-sheet--dialogue .reading-dialogue {
  width: 100%;
  margin: 0;
  padding: 22px 22px 30px;
  border: 0;
  border-radius: 0;
  background: transparent;
}
.tcm-sheet--dialogue .reading-dialogue h3 { font-size: 23px; }
.tcm-sheet--dialogue .rd-guidance {
  margin-bottom: 17px;
  font-size: 14px;
}
.tcm-sheet--dialogue .rd-rule { margin-bottom: 20px; }
.tcm-sheet--dialogue .rd-field-meta { font-size: 8px; }
.tcm-sheet--dialogue .rd-ledger { padding-left: 12px; }
.tcm-sheet--dialogue .rd-ledger-section { padding-left: 15px; }
.tcm-sheet--dialogue .rd-ledger-section .rd-number { left: -25px; }
.tcm-sheet--dialogue .rd-answer-copy,
.tcm-sheet--dialogue .rd-reply-copy p { font-size: 15px; }
.tcm-sheet--dialogue .rd-stems { grid-template-columns: 1fr; }
.tcm-sheet--dialogue .rd-stems label { min-height: 36px; }
.tcm-sheet--dialogue .rd-submit-answer,
.tcm-sheet--dialogue .rd-close {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin-left: -22px;
  width: calc(100% + 44px);
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
}

/* Reflection page — the closing surface (last card → "Reflect ▸"). Covers
   the reading above the footer; reading-mobile.js toggles .is-open. */
.tcm-reflect {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 84px;
  z-index: 32;
  background: var(--bg);
  overflow: auto;
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(.4, 0, .2, 1);
}
.tcm-reflect.is-open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.tcm-reflect-inner {
  display: flex;
  flex-direction: column;
  padding: 74px 22px 40px;
}
.tcm-reflect-eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin: 30px 0 0;
}
.tcm-reflect-title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 30px;
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 12px 0 0;
}
.tcm-reflect-lede {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.55;
  color: var(--fg-muted);
  margin: 16px 0 0;
  max-width: 42ch;
}
.tcm-reflect-field { margin-top: 30px; }
.tcm-reflect-label {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 8px;
}
.tcm-reflect-textarea {
  width: 100%;
  min-height: 96px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--fg-faint);
  padding: 4px 0 10px;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.5;
  color: var(--fg);
  resize: none;
  outline: none;
}
.tcm-reflect-status {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin: 8px 0 0;
  min-height: 12px;
}
.tcm-reflect-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  margin-top: 32px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.tcm-sheet-share,
.tcm-reflect-new,
.tcm-reflect-delete {
  background: none;
  border: 0;
  padding: 8px 0;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-decoration: none;
  color: var(--fg-muted);
}
.tcm-sheet-share:active,
.tcm-reflect-new:active,
.tcm-reflect-delete:active { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .tcm-card-wrap,
  .tcm-card,
  .tcm-art,
  .tcm-detail,
  .tcm-detail-header,
  .tcm-spread-eyebrow,
  .tcm-caption,
  .tcm-sheet,
  .tcm-reflect {
    transition-duration: 0.001ms !important;
  }
}

/* The switch: phones get the .tcm layout, desktop keeps .tc-desktop.
   (The Cross's .cc-desktop / .ccm pair rides the same switch — .ccm
   carries the .tcm class, so `.tcm { display:block }` covers it.) */
@media (max-width: 720px) {
  main.reading-shell {
    max-width: 100%;
    margin: 0;
  }
  .tc-desktop { display: none; }
  .cc-desktop { display: none; }
  .tcm { display: block; }
}

/* =====================================================================
   Figure-overview readings (shared): a reading whose overview is its
   own element — the Cross's laid figure, the I-Ching's hexagram —
   marks that element .rm-overview and its root .has-overview. The
   machine (reading-mobile.js) drives the phase classes: rm-leaving
   while a card is being drawn (the overview dims and settles away),
   rm-detail once the stage row has taken its place.
   ===================================================================== */

.tcm .rm-overview {
  transition: opacity 0.28s ease, transform 0.28s ease;
}
.tcm.rm-leaving .rm-overview {
  opacity: 0;
  transform: scale(0.96);
}
.tcm.rm-detail .rm-overview { display: none; }

/* The stage row exists only in the detail view; its single stage card
   takes the three-card detail width so the peeks line up identically. */
.tcm.has-overview .tcm-row { display: none; }
.tcm.has-overview.rm-detail .tcm-row { display: flex; }
.tcm.has-overview .tcm-card-wrap { flex-basis: 36%; }

/* =====================================================================
   The Cross, mobile (.ccm) — the shared .tcm chrome plus the Cross's
   own overview: the drawn figure adopted from the desktop builder and
   scaled to the phone's width (reading-mobile.js sets the transform
   and the box height). Tap a card to draw it onto the stage.
   ===================================================================== */

.ccm .ccm-figure-wrap {
  padding: 12px 16px 4px;
}

/* The figure keeps its fixed 732px geometry; the scale transform maps
   it onto the box, whose height JS sets to the scaled figure height.
   Absolute, so the unscaled layout size never stretches the page. */
.ccm .ccm-figure-box { position: relative; }
.ccm .ccm-figure-box .cc-figure {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
}

/* At ~0.45 scale the slot labels are unreadable noise — hide them.
   Names and positions live one tap away on the detail card. */
.ccm .cc-pos,
.ccm .cc-name { display: none; }
.ccm .cc-slot { cursor: pointer; }

/* Position fields on the detail card: the numbered position above the
   card name, its meaning in the ledger's muted voice below. */
.ccm-detail-pos {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 6px;
}
.ccm-detail-posdesc {
  font-family: var(--serif);
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--fg-muted);
  margin: 0 0 14px;
}
.ccm-detail-timing {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 14px 0 0;
}

/* =====================================================================
   The I-Ching on phones — its own thing, not a card journey.
   The plate IS the reading: the line-morph transformation and the
   mutual-gua construction animation carry the meaning, so phones get
   the same instrument desktop does, restacked to one column (the
   1000px rule already drops it there) with the measurements tightened.
   The only borrowed piece of mobile chrome is the Read-together sheet
   (.tcm-sheet--floor), which stands in for the inline section.
   ===================================================================== */

@media (max-width: 720px) {
  .ich-shell .ich-stage {
    padding: 24px 14px 0;
    gap: 32px;
  }
  /* The six line tracks are a fixed 236px — reading-mobile's sibling
     script sizes .seg in px to match — so the plate cannot fluidly
     shrink; it fits inside 375px once the stage padding is tightened.
     The trigram bands' -14px bleed is what would poke out, so pull it
     back in at this width. */
  .ich-shell .trigram {
    padding-left: 0;
    padding-right: 0;
    margin-left: 0;
    margin-right: 0;
  }
  .ich-shell .changebar {
    padding-left: 0;
    margin-top: 30px;
  }
  /* The inline synthesis gives way to the floor sheet. Hiding it also
     keeps ReadTogether.auto() off it — auto() skips mounts with no
     client rects, so only the sheet ever opens a stream. */
  .ich-shell .iching-reflection { display: none; }
  /* Clearance for the sheet's peek, so the last of the reading is not
     trapped beneath it. */
  .ich-shell { padding-bottom: 78px; }
}

/* The floor variant of the Read-together sheet: the same drag grammar
   as the reading machine's (reading-mobile.js drives both), but it
   rests on the floor — no fixed footer beneath it — and exists only on
   phones, where it replaces a page's inline synthesis section. */
.tcm-sheet--floor { display: none; }
@media (max-width: 720px) {
  .tcm-sheet--floor {
    display: flex;
    bottom: 0;
    max-height: calc(100vh - 150px);
    max-height: calc(100dvh - 150px);
  }
}

/* =====================================================================
   The mobile gate — "This reading asks for room."
   A modal interstitial over the input of the four readings that want a
   desk (OOTK, Grand Tableau, Rune Cast, Tarot Table), shown before the
   question can be written. Markup + dismissal live in
   `templates/_mobile_gate.html`; this is only its dress.
   Desktop never renders it — the partial's script removes the node
   above 720px, and this rule is the belt to that braces.
   ===================================================================== */

.mgate { display: none; }

@media (max-width: 720px) {
  .mgate {
    display: flex;
    position: fixed;
    inset: 0;
    /* Above the sticky header (50) and the nav drawer (61): the gate is
       modal, and its own back link is the way out. */
    z-index: 70;
    align-items: center;
    justify-content: center;
    padding: 24px 18px;
  }

  /* Everything but the panel goes dark until the gate is addressed. */
  .mgate-scrim {
    position: absolute;
    inset: 0;
    background: rgba(10, 9, 7, 0.74);
  }

  /* The matted panel of the reading pages, lifted off the scrim. Keeps
     the inset keyline that makes it read as matted, and adds the drop
     shadow that makes it read as raised.
     Two class names deep on purpose: `.matted-panel` is declared later
     in this file (the Ornament layer), so at equal specificity it would
     win and take back both the fill and the shadow. */
  .mgate .mgate-panel {
    position: relative;
    max-width: 33ch;
    background: var(--paper-warm);
    box-shadow:
      inset 0 0 0 var(--panel-keyline) var(--bg),
      0 18px 46px rgba(0, 0, 0, 0.38);
  }

  /* The panel takes focus (tabindex -1) so the keyboard-raising
     autofocus behind it can be held off — but it is a container, not a
     control, so it shouldn't wear a focus ring. The buttons keep theirs. */
  .mgate .mgate-panel:focus { outline: none; }

  .mgate-title {
    font-size: 21px;
    line-height: 1.25;
    margin: 10px 0 12px;
  }

  .mgate-line {
    font-family: var(--serif);
    font-size: 15.5px;
    line-height: 1.55;
    color: var(--fg-muted);
    margin: 0;
  }

  /* The practical instruction, in full ink against the muted
     explanation above it, so the thing to actually DO is the thing that
     reads first. */
  .mgate-note {
    font-family: var(--serif);
    font-size: 15px;
    line-height: 1.5;
    color: var(--fg);
    margin: 13px 0 0;
  }

  .mgate-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    margin: 22px 0 0;
    padding-top: 18px;
    border-top: 1px solid var(--rule);
  }

  /* Both actions sit in the mono chrome voice; the proceed reads as the
     deliberate one, the retreat as the quiet one. */
  .mgate-go,
  .mgate-back {
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    background: none;
    border: 0;
    padding: 11px 0;
    cursor: pointer;
    text-decoration: none;
    -webkit-appearance: none;
    appearance: none;
  }
  .mgate-go { color: var(--red); }
  .mgate-back { color: var(--fg-muted); }

  /* Hold the page still behind the scrim. Scoped to phones so that a
     rotation or resize past 720px can never strand a locked <html>. */
  html.mgate-open,
  html.mgate-open body {
    overflow: hidden;
  }
}

/* =====================================================================
   Ornament — the art-direction layer.
   The sanctioned set of richer-but-still-sober moves that warm the
   reading and landing surfaces WITHOUT adding a hue or breaking the
   hairline grid. Deploy sparingly (~3 of 5 intensity); never decorative
   for its own sake. Rubrication (red used the way a scribe used it —
   initials, section labels, the significator) reuses --red; no new
   colour is ever introduced.

     .paper-grain    faint fractal-noise tooth over the flat fill
     .rule-ornament  double rule closed with a red fleuron (❧)
     .matted-panel   1px rule + card-bg fill + inset keyline
     .corner-marks   four small red L-brackets (needs 4 <i> children)

   The ornament is static: grain, rules and corner marks never animate.
   ===================================================================== */

:root {
  /* Paper grain — barely perceptible. It is a texture, not a pattern;
     keep it beneath legibility. ~14% over parchment, ~12% over night. */
  --grain-parchment: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.14'/%3E%3C/svg%3E");
  --grain-night: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.12'/%3E%3C/svg%3E");

  --fleuron: "\2767";     /* ❧ — the section fleuron */
  --corner-mark: 12px;    /* L-bracket arm length on matted panels */
  --panel-keyline: 5px;   /* inset bg ring inside a matted panel */
}

/* --- Paper grain --- */
.paper-grain { background-image: var(--grain-parchment); }
body.theme-night .paper-grain,
body.theme-night.paper-grain { background-image: var(--grain-night); }

/* --- Ornamental divider: double rule closed with a fleuron ---
   <div class="rule-ornament"><span class="fleuron"></span></div> */
.rule-ornament {
  display: flex;
  align-items: center;
  gap: 16px;
  color: var(--red);
}
.rule-ornament::before,
.rule-ornament::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  height: 4px;
}
.rule-ornament > .fleuron::before { content: var(--fleuron); }

/* --- Matted panel + corner marks ---
   <div class="matted-panel corner-marks"><i></i><i></i><i></i><i></i> … */
.matted-panel {
  position: relative;
  border: 1px solid var(--rule);
  background: var(--card-bg);
  box-shadow: inset 0 0 0 var(--panel-keyline) var(--bg);
  padding: 22px 26px;
}
.corner-marks > i {
  position: absolute;
  width: var(--corner-mark);
  height: var(--corner-mark);
  pointer-events: none;
}
.corner-marks > i:nth-child(1) { top: 7px; left: 7px; border-top: 1px solid var(--red); border-left: 1px solid var(--red); }
.corner-marks > i:nth-child(2) { top: 7px; right: 7px; border-top: 1px solid var(--red); border-right: 1px solid var(--red); }
.corner-marks > i:nth-child(3) { bottom: 7px; left: 7px; border-bottom: 1px solid var(--red); border-left: 1px solid var(--red); }
.corner-marks > i:nth-child(4) { bottom: 7px; right: 7px; border-bottom: 1px solid var(--red); border-right: 1px solid var(--red); }

/* =====================================================================
   Reading page — the art-direction layer applied (handoff "3a").
   The subheader voice takes the labels; DM Mono keeps the pure chrome
   (dates, reading number, running actions) so the apparatus/content
   split stays legible.
   ===================================================================== */

/* The reading names itself, between the mono topbar and the question. */
.reading-title-bar {
  padding: 0 var(--space-6) var(--space-4);
  border-bottom: 1px solid var(--rule);
}

/* The question, matted and cornered. It takes the Read together sheet's
   paper rather than --card-bg: the two blocks bracket the leaf, and the
   deeper beige read as a second, unrelated material between them. */
.question-mat {
  padding: var(--space-5) var(--space-6);
}
.question-mat .matted-panel {
  background: var(--paper-warm);
}
.question-mat .question-text {
  font-family: var(--serif);
  font-size: 25px;
  line-height: 1.32;
  margin: var(--space-3) 0 0;
  color: var(--fg);
}

/* Section header: a label, a double rule running out to the chrome. */
.section-head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 0 var(--space-6) var(--space-1);
}
.section-head-rule {
  flex: 1;
  height: 3px;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.section-head .actions {
  display: flex;
  gap: var(--space-3);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
  white-space: nowrap;
}
.section-head .actions a {
  color: var(--fg-muted);
  text-decoration: none;
}
.section-head .actions a:hover { color: var(--red); }

/* The ornament that closes the cards and opens the synthesis. */
.reading-ornament {
  padding: var(--space-5) var(--space-6) var(--space-4);
}

/* The card's element line takes the subheader voice — it names the
   card's nature, so it belongs with the section labels rather than the
   mono chrome. */
.card-panel .badge {
  font-family: var(--subhead);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* "The Question" on every other reading type keeps its old bar, but
   takes the subheader voice + rubrication so the type system is
   consistent across the app. */
.question-bar .label {
  font-family: var(--subhead);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--red);
}

/* Read Together's own eyebrow, in the subheader voice. (The name stays
   "Read together" — it's the app's own word for this, not "Synthesis".) */
.rt-eyebrow {
  font-family: var(--subhead) !important;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

/* The illuminated initial opens the synthesis prose. Desktop only: the
   mobile sheet is too narrow to carry a 3.6em initial, and .read-together
   is the desktop mount (the phone mounts into .tcm-sheet-body). */
.read-together .rt-synth .rt-p:first-child::first-letter {
  float: left;
  font-family: var(--serif);
  font-weight: 500;
  font-variation-settings: "WONK" 1;
  font-size: 3.6em;
  line-height: 0.72;
  padding: 0.08em 0.18em 0 0;
  color: var(--red);
}

/* The paper takes a tooth. Barely perceptible, and never over the
   phone's reading — the .tcm surfaces stay flat. */
body {
  background-image: var(--grain-parchment);
}
body.theme-night {
  background-image: var(--grain-night);
}

@media print {
  body { background-image: none; }
  .reading-ornament { display: none; }
}
