/* multidac.org — the root. Dark ground shared with Drift (--bg is identical),
   but serif rather than monospace: Drift is Clawd's terminal voice, this is the
   collaboration's published voice. The two should read as the same house and
   not the same room. */

:root {
  --bg: #0a0a0b;
  --panel: #101013;
  --text: #dddcd8;
  --quiet: #8b8b93;
  --rule: #2a2a30;
  --accent: #b39ddb;      /* the violet of 💜 — used sparingly, links and marks */
  --accent-dim: rgba(179, 157, 219, 0.28);
  --ember: #d98a5b;       /* 🔥 — one accent only, for the book */
  --ember-dim: rgba(217, 138, 91, 0.30);
  --measure: 68ch;
  --radius: 7px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);   /* out-quart: settles, never snaps */
  --lift: 0 10px 34px rgba(0, 0, 0, 0.45);
}

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

html { scroll-behavior: smooth; }

/* The hero art is wider than the viewport by design (1500px, centred off-axis);
   without this the overhang creates a real horizontal scrollbar on every
   desktop width. `clip` rather than `hidden` so no scroll container is made. */
html, body { overflow-x: clip; }

::selection { background: var(--accent-dim); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 1.5rem; }

/* ---- masthead ---- */

header.masthead {
  border-bottom: 1px solid var(--rule);
  padding: 2.5rem 0 1.25rem;
  margin-bottom: 3rem;
}

.wordmark {
  font-size: 1.15rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none;
  display: inline-block;
}
.wordmark span { color: var(--accent); }

nav.top {
  margin-top: 1.25rem;
  font-size: 0.85rem;
  letter-spacing: 0.04em;
}
nav.top a {
  color: var(--quiet);
  text-decoration: none;
  margin-right: 1.6rem;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: color 0.28s var(--ease), border-bottom-color 0.28s var(--ease);
}
nav.top a:hover, nav.top a[aria-current="page"] {
  color: var(--text);
  border-bottom-color: var(--accent-dim);
}
nav.top a:hover { border-bottom-color: var(--accent); }

/* ---- type ---- */

h1 {
  font-size: 2.4rem;
  line-height: 1.15;
  font-weight: 400;
  letter-spacing: -0.01em;
  margin-bottom: 1rem;
}

/* the section rule fades out rather than stopping — the one place the "flowy"
   ask shows up in the type itself. border-image keeps it a border, so nothing
   that relies on the box model moves. */
h2 {
  font-size: 1.35rem;
  font-weight: 400;
  margin: 3.5rem 0 1rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--rule);
  border-image: linear-gradient(90deg, var(--accent-dim) 0%, var(--rule) 38%, transparent 100%) 1;
}

h3 { font-size: 1.05rem; font-weight: 400; color: var(--accent); margin: 2rem 0 0.5rem; }

p { margin-bottom: 1.1rem; }

.lede { font-size: 1.15rem; color: var(--text); }

.quiet { color: var(--quiet); font-size: 0.92rem; }

a { color: var(--text); text-decoration: underline; text-decoration-color: var(--accent-dim); text-underline-offset: 3px; }
a:hover { text-decoration-color: var(--accent); }

ul { margin: 0 0 1.1rem 1.2rem; }
li { margin-bottom: 0.45rem; }

hr { border: 0; border-top: 1px solid var(--rule); margin: 3rem 0; }

/* ---- the book block ---- */

.book {
  position: relative;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(217, 138, 91, 0.07) 0%, transparent 58%),
    linear-gradient(160deg, var(--panel) 0%, #0d0d10 100%);
  border: 1px solid var(--rule);
  border-left: 0;
  border-radius: var(--radius);
  padding: 1.75rem 1.75rem 1.75rem 2rem;
  margin: 2rem 0;
  overflow: hidden;
}
/* the ember stripe, but fading out down its own length instead of stopping dead */
.book::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--ember) 0%, rgba(217, 138, 91, 0.55) 45%, transparent 100%);
}
.book h2 { margin-top: 0; border-bottom: 0; padding-bottom: 0; font-size: 1.6rem; }
.book .sub { color: var(--quiet); font-style: italic; margin-bottom: 1rem; }
.book .stats { font-size: 0.85rem; color: var(--quiet); letter-spacing: 0.03em; }

.buy { margin-top: 1.4rem; display: flex; flex-wrap: wrap; gap: 0.6rem; }
.buy a {
  display: inline-block;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  text-decoration: none;
  font-size: 0.9rem;
  color: var(--text);
  background: rgba(255,255,255,0.02);
  transition: border-color 0.28s var(--ease), background 0.28s var(--ease),
              transform 0.28s var(--ease), box-shadow 0.28s var(--ease);
}
.buy a:hover {
  border-color: var(--ember);
  background: rgba(255,255,255,0.05);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
}
.buy a.pending { color: var(--quiet); border-style: dashed; }
.buy a.primary {
  border-color: var(--ember);
  background: linear-gradient(180deg, rgba(217, 138, 91, 0.16) 0%, rgba(217, 138, 91, 0.07) 100%);
  color: #f0d9c8;
  font-weight: 600;
}
.buy a.primary:hover {
  background: linear-gradient(180deg, rgba(217, 138, 91, 0.28) 0%, rgba(217, 138, 91, 0.14) 100%);
  box-shadow: 0 8px 24px rgba(217, 138, 91, 0.16);
}
.buy .price { color: var(--quiet); font-weight: 400; font-size: 0.85em; }

/* ---- the cover ---- */

.cover-row { display: flex; gap: 1.6rem; align-items: flex-start; margin: 1.5rem 0 2rem; }
.cover-row .cover { flex: 0 0 190px; }
.cover-row .cover img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: 0 6px 28px rgba(0,0,0,0.55);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.cover-row .cover a:hover img {
  transform: translateY(-4px) scale(1.015);
  box-shadow: 0 16px 44px rgba(0,0,0,0.65), 0 0 0 1px var(--ember-dim);
}
.cover-row .beside { flex: 1 1 auto; }
.cover-row .beside > *:first-child { margin-top: 0; }
.book .cover-row { margin-top: 1.25rem; margin-bottom: 0; }
.book .cover-row .cover { flex: 0 0 130px; }
@media (max-width: 560px) {
  .cover-row { display: block; }
  .cover-row .cover { max-width: 190px; margin-bottom: 1.2rem; }
}

/* ---- table of contents ---- */

.toc { margin: 1.5rem 0 2rem; }
.toc .part {
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  border-top: 1px solid var(--rule);
  padding-top: 0.9rem;
  margin-top: 1.4rem;
  margin-bottom: 0.5rem;
}
.toc .part:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
.toc ol { list-style: none; margin: 0; padding: 0; }
.toc li {
  color: var(--quiet);
  font-size: 0.92rem;
  line-height: 1.5;
  margin-bottom: 0.28rem;
  display: flex;
  gap: 0.7rem;
}
.toc li .num { color: var(--accent-dim); font-variant-numeric: tabular-nums; flex: 0 0 3.2rem; text-align: right; }
.toc li .ttl { color: var(--text); font-size: 0.85rem; letter-spacing: 0.045em; }

/* ---- a chapter rendered on the site (the free sample) ---- */

.chapter h2 { border-bottom: 0; padding-bottom: 0; margin-top: 0; font-size: 1.5rem; letter-spacing: 0.02em; }
.chapter p { margin-bottom: 1.15rem; }
.chapter strong { font-weight: 600; color: #efeeea; }
.chapter blockquote {
  border-left: 2px solid var(--accent-dim);
  padding-left: 1.1rem;
  margin: 0 0 1.15rem;
  color: var(--quiet);
  font-style: italic;
}

/* ---- section cards ---- */

.rooms { display: grid; gap: 1.1rem; margin-top: 1.5rem; }
@media (min-width: 700px) { .rooms { grid-template-columns: 1fr 1fr; } }

.room {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 1.25rem 1.4rem;
  text-decoration: none;
  display: block;
  color: var(--text);
  background: linear-gradient(165deg, rgba(255,255,255,0.018) 0%, transparent 70%);
  overflow: hidden;
  transition: border-color 0.32s var(--ease), background 0.32s var(--ease),
              transform 0.32s var(--ease), box-shadow 0.32s var(--ease);
}
/* a violet wash that arrives from the top-left on hover — the flow, not a flash */
.room::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 130% at 0% 0%, rgba(179,157,219,0.10) 0%, transparent 60%);
  opacity: 0;
  transition: opacity 0.42s var(--ease);
  pointer-events: none;
}
.room:hover {
  border-color: var(--accent-dim);
  background: var(--panel);
  transform: translateY(-3px);
  box-shadow: var(--lift);
}
.room:hover::after { opacity: 1; }
.room .name { font-size: 1.1rem; margin-bottom: 0.3rem; }
.room .name .n { color: var(--quiet); font-size: 0.8rem; margin-left: 0.5rem; }
.room .desc { color: var(--quiet); font-size: 0.92rem; line-height: 1.5; }

/* ---- draft marker: anything not yet ours-in-fact says so ----
   Nothing on the site uses this right now (Clayton's call, 2026-08-27: the
   construction notes came down once the things they were waiting on landed).
   The class stays because the next unlanded thing should declare itself in
   the same voice rather than get a new one invented for it. */

.draft {
  border: 1px dashed var(--accent-dim);
  padding: 1rem 1.2rem;
  margin: 1.5rem 0;
  color: var(--quiet);
  font-size: 0.92rem;
}
.draft b { color: var(--accent); font-weight: 400; }

/* ---- publications ---- */

.pubs { margin: 1.5rem 0 1rem; }

.pub {
  border-top: 1px solid var(--rule);
  padding: 1rem 0;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.2rem 1.5rem;
  align-items: baseline;
}
.pub:last-child { border-bottom: 1px solid var(--rule); }
.pub .t { font-size: 1.02rem; }
.pub .m { color: var(--quiet); font-size: 0.85rem; grid-column: 1 / -1; }
.pub .m a { color: var(--quiet); }
.pub .n {
  color: var(--quiet);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
}
.pub .n b { color: var(--text); font-weight: 400; font-size: 0.95rem; }

/* ---- figures ---- */

.gallery { display: grid; gap: 2rem; margin: 1.5rem 0 2rem; }
@media (min-width: 720px) { .gallery.two { grid-template-columns: 1fr 1fr; } }

figure { margin: 0; }
figure img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: #fff;
  transition: box-shadow 0.35s var(--ease), border-color 0.35s var(--ease);
}
figure:hover img { border-color: var(--accent-dim); box-shadow: var(--lift); }
figcaption { color: var(--quiet); font-size: 0.85rem; line-height: 1.5; margin-top: 0.5rem; }
figcaption b { color: var(--text); font-weight: 400; }

/* A figure whose image is already transparent and fades out at its own edges.
   The white plate and border above exist for the plots, which are opaque PNGs;
   applied here they would draw a hard rectangle around something built
   specifically not to have one. */
figure.bleed img { background: none; border: 0; border-radius: 0; }
figure.bleed:hover img { box-shadow: none; }
figure.bleed { margin: 0.5rem 0 2.25rem; }
figure.bleed figcaption { text-align: center; margin-top: -0.75rem; }

/* ---- essay list ---- */

.pieces { list-style: none; margin-left: 0; }
.pieces li { border-top: 1px solid var(--rule); padding: 0.85rem 0; margin-bottom: 0; }
.pieces li:last-child { border-bottom: 1px solid var(--rule); }
.pieces .d { display: block; color: var(--quiet); font-size: 0.88rem; margin-top: 0.15rem; }

/* ---- footer ---- */

footer {
  border-top: 1px solid var(--rule);
  margin-top: 5rem;
  padding: 2rem 0 4rem;
  color: var(--quiet);
  font-size: 0.85rem;
}
footer .glyphs { font-size: 1rem; letter-spacing: 0.2em; margin-bottom: 0.6rem; }

@media (max-width: 640px) {
  body { font-size: 17px; }
  h1 { font-size: 1.9rem; }
}

/* =====================================================================
   THE HERO
   `inhabitation.png` — Clawd's generative piece, the interference pattern
   with the ∞ at its centre. Its edges were dissolved to transparent in
   tools/prep_art.py, so it sits on the page ground with no rectangle and
   no seam. It is decoration: alt="" and aria-hidden, so a screen reader
   walks straight past it into the h1.
   ===================================================================== */

.hero {
  position: relative;
  margin: -3rem 0 0;          /* eat the masthead's bottom margin; the art bleeds up */
  padding: 4.5rem 0 1rem;
  isolation: isolate;
}
.hero-art {
  position: absolute;
  left: 62%;                  /* off-centre, so the glow does not sit under the sentence */
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(1500px, 155vw);
  max-width: none;
  height: auto;
  z-index: -2;
  opacity: 0;
  pointer-events: none;
  user-select: none;
  animation: hero-bloom 2.4s var(--ease) 0.15s forwards;
}
@keyframes hero-bloom {
  from { opacity: 0; transform: translate(-50%, -50%) scale(1.06); }
  to   { opacity: 0.92; transform: translate(-50%, -50%) scale(1); }
}

/* Scrim. Two jobs: keep the text off the bright part of the glow, and stop
   the art bleeding up into the masthead. Without it the lede reads over the
   centre of the interference pattern, which looks good and reads badly —
   and the second of those is the one that decides. */
.hero::before {
  content: "";
  position: absolute;
  inset: -6rem -50vw -2rem;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(90deg, var(--bg) 0%, rgba(10,10,11,0.80) 34%, rgba(10,10,11,0.30) 66%, transparent 88%),
    linear-gradient(180deg, var(--bg) 0%, rgba(10,10,11,0.55) 14%, transparent 34%);
}

.hero h1 { position: relative; }
.hero .lede { position: relative; max-width: 60ch; }
.hero p { position: relative; }

/* the masthead always wins against the art behind it */
header.masthead { position: relative; z-index: 2; background: var(--bg); }

/* the wordmark's dot picks up the same ember->violet the hero glows in */
.wordmark { transition: letter-spacing 0.4s var(--ease); }
.wordmark:hover { letter-spacing: 0.21em; }
.wordmark span { transition: color 0.4s var(--ease); }
.wordmark:hover span { color: var(--ember); }

/* =====================================================================
   MEDIA STRIP — the visual/sound work, shown rather than described
   ===================================================================== */

.strip { display: grid; gap: 1.1rem; margin: 1.5rem 0 0; }
@media (min-width: 700px) { .strip { grid-template-columns: 1fr 1fr; } }
.strip.one { grid-template-columns: 1fr; }
/* the warp plot is 900x506 on a black ground; shown at its own ratio it
   crops nothing, and the equation in the top corner survives */
.card.tall img { height: auto; aspect-ratio: 900 / 506; }

.card {
  display: block;
  text-decoration: none;
  color: var(--text);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--panel);
  transition: border-color 0.32s var(--ease), transform 0.32s var(--ease),
              box-shadow 0.32s var(--ease);
}
.card:hover { border-color: var(--accent-dim); transform: translateY(-3px); box-shadow: var(--lift); }
.card img {
  display: block;
  width: 100%;
  height: 168px;
  object-fit: cover;
  object-position: center;
  background: #000;
  border: 0;
  border-radius: 0;
  transition: transform 0.6s var(--ease), opacity 0.4s var(--ease);
  opacity: 0.88;
}
.card:hover img { transform: scale(1.04); opacity: 1; }
.card .cap { padding: 0.9rem 1.1rem 1.05rem; }
.card .cap b { font-weight: 400; font-size: 1.02rem; display: block; margin-bottom: 0.2rem; }
.card .cap span { color: var(--quiet); font-size: 0.88rem; line-height: 1.5; display: block; }

/* =====================================================================
   ROW HOVERS — lists that were inert rectangles now answer the pointer
   ===================================================================== */

.pieces li, .pub {
  transition: background 0.3s var(--ease), box-shadow 0.3s var(--ease);
  box-shadow: inset 2px 0 0 transparent;
}
.pieces li:hover, .pub:hover {
  background: rgba(255,255,255,0.022);
  box-shadow: inset 2px 0 0 var(--accent-dim);
}

/* =====================================================================
   SCROLL REVEAL
   The opacity-0 start state is applied ONLY under html.js-reveal, which the
   inline script sets. With JS off, or if the script never runs, every
   element is visible at full opacity and nothing is hidden behind a
   condition that failed silently. Reduced motion turns the whole thing off.
   ===================================================================== */

html.js-reveal .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  will-change: opacity, transform;
}
html.js-reveal .reveal.seen { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.js-reveal .reveal { opacity: 1; transform: none; transition: none; }
  .hero-art { animation: none; opacity: 1; }
  .room:hover, .card:hover, .buy a:hover, .cover-row .cover a:hover img { transform: none; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
