/* Underlying — an Ivy League concordance.
   Harvard/Yale archival: parchment stock, archival ink, crimson rules, dull
   brass ornament, fine lead hairlines. The register of a shareholder letter
   and a university library catalogue, not an app.

   Rules of the system:
   - Crimson is the institution's colour. It draws rules, marks type, and
     fills a control ONLY on hover. Brass is ornament: numerals, ordinals,
     small marks. Neither is a background.
   - Every corner is 0, or 2px on a stamp, which reads as a cut edge. The
     ONE exception is the call slip: 8px, because it is the control you
     actually touch and a cut corner there reads hard rather than considered.
   - Focus is a sharp offset ring in crimson. Never a soft halo, never a glow.
   - Transitions are instant on colour. A prestige control does not ease.
   - EB Garamond reads; JetBrains Mono records.
*/

:root {
  /* Stock */
  --parchment:   #F7F5F0;   /* the page */
  --paper:       #FFFFFF;   /* a document laid on it */
  --parchment-2: #F1EEE6;   /* an inset, a well */

  /* Ink */
  --ink:    #1A1918;        /* archival ink */
  --ink-2:  #33312E;
  --ink-3:  #55524B;
  --muted:  #6E6A61;

  /* Institution */
  --crimson:   #A51C30;     /* Harvard crimson */
  --crimson-2: #8A1727;     /* pressed */
  --brass:     #C5A059;     /* dull gold ornament */
  --rule:      #D6D1C7;     /* fine lead */
  --rule-2:    #C2BCB0;

  --serif: 'EB Garamond', 'Baskerville', Caslon, Georgia, serif;
  --mono:  'JetBrains Mono', 'Courier New', Courier, monospace;

  --measure: 720px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--serif);
  font-size: 18px;
  background: var(--parchment);
  color: var(--ink);
  display: flex; flex-direction: column;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--crimson); text-underline-offset: 3px; text-decoration-thickness: 1px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* A sharp, high-contrast offset ring. Never a soft halo. */
:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--crimson);
  outline-offset: 2px;
}

/* Everything catalogued is recorded in the same hand. */
.index-head, .claim-rule, .fine,
.session .m, .drawer-head h2, .session-group h3,
.stamp, .primary, .finding-terms,
.dateline, .share, .retry, .waiting-body {
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---------- Head of the volume ---------- */
.top {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 10px; padding-top: max(12px, env(safe-area-inset-top));
  background: var(--parchment);
  border-bottom: 1px solid var(--ink);
}
.icon {
  width: 40px; height: 40px; border: 1px solid transparent; border-radius: 0;
  background: transparent; color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: none;
}
.icon:hover { border-color: var(--ink); background: var(--crimson); color: var(--paper); }
.icon-space { width: 40px; }
.brand { display: flex; flex-direction: column; align-items: center; gap: 3px; text-decoration: none; color: var(--ink); }
.brand-name {
  font-family: var(--serif); font-size: 27px; font-weight: 600;
  letter-spacing: 0.08em; line-height: 1; text-transform: uppercase;
}
.brand-sub {
  font-family: var(--mono); font-size: 8px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted);
}

/* ---------- The desk ---------- */
.thread {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 30px 18px 16px;
  width: 100%; max-width: var(--measure); margin: 0 auto;
}

/* ---------- Home ---------- */
.standfirst {
  margin: 0 0 24px; font-size: 18px; line-height: 1.6; color: var(--ink-2);
  max-width: 32em; padding-bottom: 22px;
  border-bottom: 1px solid var(--ink);
}

/* A ruled heading over a column of an index. */
.index-head {
  font-size: 9px; color: var(--crimson);
  padding-bottom: 6px; margin: 28px 0 0;
  border-bottom: 1px solid var(--crimson);
}

/* ---------- The index of enquiries ---------- */
.seeds { list-style: none; margin: 0; padding: 0; counter-reset: seed; }
.seeds li { counter-increment: seed; }
.seed {
  position: relative; display: block; width: 100%; text-align: left;
  padding: 14px 0 14px 44px;
  border: 0; border-bottom: 1px solid var(--rule); border-radius: 0;
  background: transparent; cursor: pointer; transition: none;
  font-family: var(--serif); font-size: 19px; line-height: 1.32; color: var(--ink);
}
.seed::before {
  content: counter(seed, upper-roman) '.';
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em; color: var(--brass);
}
/* The served-HTML openers are text until app.js makes them buttons. */
.seed.is-static { cursor: default; color: var(--ink-2); }
.seed.is-static:hover { background: transparent; color: var(--ink-2); padding-left: 44px; }
.seed:hover { background: var(--crimson); color: var(--paper); padding-left: 48px; }
.seed:hover::before { color: var(--paper); left: 4px; }

/* ---------- An entry: what was asked, then what came back ----------
   A scrolling chat and nothing else. The question sits right, the answer
   sits left, and there is no header, no rule across the top and no third
   thing on the screen. */
.entry { margin: 0 0 34px; }
.asked { display: flex; justify-content: flex-end; margin: 26px 0 18px; }
.thread > .entry:first-child .asked { margin-top: 0; }
.entry-q {
  margin: 0; max-width: 84%;
  font-family: var(--serif); font-weight: 600;
  font-size: 19px; line-height: 1.35; color: var(--ink);
  background: var(--paper); border: 1px solid var(--ink);
  padding: 11px 14px;
}
.said { display: block; }

/* The dateline sits under the answer, not over it. It is the framing
   constraint -- 48 letters, 1977-2024, and nothing after -- which is why the
   UI never says "latest" or "what he thinks today". */
.entry-meta {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-top: 14px; padding-top: 9px;
  border-top: 1px solid var(--rule);
}
.dateline { font-size: 9px; color: var(--muted); }
.share {
  border: 0; background: transparent; padding: 0; cursor: pointer;
  font-size: 9px; color: var(--crimson); text-decoration: underline;
  text-underline-offset: 3px; white-space: nowrap;
}
.share:hover { color: var(--crimson-2); }
.share.is-done { color: var(--muted); text-decoration: none; }

/* ---------- A claim ----------
   One rule down the left says the type; nothing else is boxed. The card had
   its own border, an inner tinted block around the quote and a button that
   repeated the citation underneath it -- three frames and two links for one
   passage. The quote is the thing; everything else is a label on it. */
.claim {
  border-left: 3px solid var(--crimson);
  padding: 2px 0 2px 15px;
  margin: 0 0 22px;
}
.claim.is-revision    { border-left-color: var(--ink); }
.claim.is-conditional { border-left-color: var(--brass); }
.claim.is-evidence,
.claim.is-example     { border-left-color: var(--rule-2); }

.claim-rule {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 9px; color: var(--muted); margin-bottom: 8px;
}
.claim-year { color: var(--ink); font-weight: 700; letter-spacing: 0.14em; }
.claim-type { margin-left: auto; font-size: 8px; letter-spacing: 0.12em; color: var(--crimson); }
.is-revision .claim-type    { color: var(--ink); }
.is-conditional .claim-type { color: #6E5520; }
.is-evidence .claim-type,
.is-example .claim-type     { color: var(--muted); }

.claim-label {
  margin: 0 0 9px; font-family: var(--serif); font-weight: 600;
  font-size: 19px; line-height: 1.32; color: var(--ink);
}

/* The evidence. Verbatim, and set to look it. */
.claim-quote {
  margin: 0; font-family: var(--serif); font-size: 18px; line-height: 1.6;
  color: var(--ink); font-style: italic;
}
.claim-quote::before { content: '\201C'; }
.claim-quote::after  { content: '\201D'; }

/* The citation is the link. It used to be a button that said "read at
   Berkshire" with the citation repeated beside it. */
.claim-foot { margin-top: 9px; }

/* ---------- A finding: no coverage, no live data ----------
   The calm centre of the product. There is no model in the request path, so
   "these documents do not discuss that" is the honesty mechanism. It is set
   as a considered finding on library stock — never as a fault, never red. */
.finding {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
  padding: 20px 22px 18px;
  margin: 0 0 14px;
}
.finding-body {
  margin: 0; font-family: var(--serif); font-size: 22px; line-height: 1.45;
  color: var(--ink);
}
.finding-terms { margin: 15px 0 0; font-size: 9px; color: var(--muted); }
.absent {
  display: inline-block; margin-right: 6px; padding: 2px 8px 1px;
  background: var(--parchment-2); border-bottom: 2px solid var(--brass);
  color: var(--ink);
}
.finding-note {
  margin: 17px 0 4px; font-family: var(--serif); font-style: italic;
  font-size: 17px; color: var(--ink-3);
}
.finding .seeds { margin-top: 4px; }

/* ---------- Waiting on the service ----------
   There is a network hop now. A pending answer has to look like a search in
   progress, and a failed one has to read as the service being unreachable --
   never as the letters having nothing to say. Those are opposite statements
   and the styling keeps them apart: pending is quiet but unmistakable,
   failure is a finding with the question offered back, and neither is red. */
.waiting { display: flex; align-items: center; gap: 10px; padding: 4px 0 14px; }
.waiting-body { font-size: 11px; color: var(--ink-3); }

/* Three dots, because that is the one "working" signal nobody has to learn.
   Round, in a building with cut corners, for the same reason the call slip
   is: it is feedback for a person, not furniture. */
.dots { display: inline-flex; align-items: center; gap: 5px; }
.dots i {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--crimson); opacity: 0.25;
  animation: pulse 1.15s ease-in-out infinite;
}
.dots i:nth-child(2) { animation-delay: 0.16s; }
.dots i:nth-child(3) { animation-delay: 0.32s; }
@keyframes pulse {
  0%, 70%, 100% { opacity: 0.22; transform: translateY(0); }
  35%           { opacity: 1;    transform: translateY(-3px); }
}
/* Still legible as "waiting" when the animation is switched off. */
@media (prefers-reduced-motion: reduce) {
  .dots i { animation: none; opacity: 0.55; }
  .dots i:nth-child(1) { opacity: 1; }
}

.retry {
  margin-top: 16px; display: inline-block; cursor: pointer;
  background: transparent; color: var(--ink); border: 1px solid var(--ink);
  padding: 9px 15px; font-size: 9px;
}
.retry:hover { background: var(--crimson); border-color: var(--crimson); color: #FFFFFF; }

/* ---------- Controls ----------
   Sharp edges, a hairline border, tracked uppercase. The fill arrives on
   hover, instantly and at full contrast. */
.stamp {
  display: inline-block; font-size: 9px; color: var(--muted);
  text-decoration: none; border-bottom: 1px solid var(--rule-2);
  padding-bottom: 2px;
}
.stamp:hover { color: var(--crimson); border-bottom-color: var(--crimson); }
.stamp.is-dead { border-bottom-color: transparent; cursor: default; }
.stamp.is-dead:hover { color: var(--muted); }

.primary {
  display: block; width: 100%; min-height: 46px;
  font-size: 0.8rem; color: var(--ink); background: transparent;
  border: 1px solid var(--ink); border-radius: 2px;
  cursor: pointer; transition: none;
}
.primary:hover { background: var(--crimson); border-color: var(--crimson); color: #FFFFFF; }

.link { border: 0; background: transparent; color: var(--crimson); font: inherit; cursor: pointer; padding: 0; text-decoration: underline; }

/* ---------- The call slip ---------- */
.composer {
  position: sticky; bottom: 0; z-index: 5;
  padding: 14px 18px; padding-bottom: max(14px, env(safe-area-inset-bottom));
  background: var(--parchment);
  border-top: 1px solid var(--ink);
  display: flex; flex-direction: column; gap: 10px;
  width: 100%; max-width: var(--measure); margin: 0 auto;
}
/* The one deliberate exception to the 0-2px rule. Everything else in the
   building is cut square, but the call slip is the thing you actually touch,
   and at 2px it reads hard rather than architectural. 8px takes the edge off
   without becoming a chat pill; the inner corner on the submit key is 7px so
   it sits inside the border rather than poking through it. */
.composer form {
  display: flex; align-items: stretch; gap: 0;
  background: var(--paper);
  border: 1px solid var(--rule); border-radius: 8px;
  transition: none;
}
.composer form:hover { border-color: var(--ink); }
/* The ring belongs to the whole slip, not the bare input inside it. Offset
   goes to 3px so the ring clears the rounded corner cleanly. */
.composer form:focus-within { outline: 2px solid var(--crimson); outline-offset: 3px; border-color: var(--ink); }
.composer input {
  flex: 1; min-width: 0; height: 46px; padding: 0 14px;
  border: 0; outline: 0; background: transparent; border-radius: 0;
  font-family: var(--mono); font-size: 15px; font-weight: 500; color: var(--ink);
}
.composer input::placeholder {
  color: var(--muted); font-family: var(--mono);
  text-transform: uppercase; letter-spacing: 0.08em; font-size: 12px; font-weight: 600;
}
.composer input:disabled { color: var(--muted); }
.composer button[type=submit] {
  width: 52px; border: 0; border-left: 1px solid var(--rule); border-radius: 0 7px 7px 0;
  background: transparent; color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; flex-shrink: 0; transition: none;
}
.composer button[type=submit]:hover:not(:disabled) { background: var(--crimson); border-left-color: var(--crimson); color: #FFFFFF; }
.composer button[type=submit]:disabled { color: var(--rule-2); cursor: default; }
.fine { margin: 0; font-size: 8px; line-height: 1.9; color: var(--muted); font-weight: 500; }

/* ---------- The catalogue drawer ---------- */
.drawer[hidden] { display: none; }
.drawer { position: fixed; inset: 0; z-index: 20; }
/* A solid wash. No frosted glass, no blur. */
.drawer-scrim { position: absolute; inset: 0; background: rgba(26, 25, 24, 0.55); }
.drawer-panel {
  position: absolute; top: 0; bottom: 0; left: 0; width: min(90vw, 380px);
  background: var(--parchment); border-right: 1px solid var(--ink);
  display: flex; flex-direction: column; gap: 18px; padding: 0 18px 20px;
  padding-top: env(safe-area-inset-top); overflow-y: auto; border-radius: 0;
}
.drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 0 10px; border-bottom: 1px solid var(--ink);
}
.drawer-head h2 { margin: 0; font-size: 11px; color: var(--crimson); }

.session-list { display: flex; flex-direction: column; gap: 22px; }
.session-group { display: flex; flex-direction: column; }
.session-group h3 {
  margin: 0 0 2px; font-size: 9px; color: var(--muted);
  padding-bottom: 6px; border-bottom: 1px solid var(--crimson);
}
.session {
  display: flex; flex-direction: column; gap: 4px; min-height: 52px; justify-content: center;
  border: 0; border-bottom: 1px solid var(--rule); border-radius: 0;
  background: transparent; text-align: left; cursor: pointer; color: var(--ink);
  padding: 10px 0; transition: none;
}
.session .t { font-family: var(--serif); font-size: 17px; line-height: 1.3; }
.session .m { font-size: 8px; color: var(--muted); }
.session.current .t { color: var(--crimson); font-weight: 600; }
.session:hover .t { color: var(--crimson); }

/* ---------- The larger desk ---------- */
@media (min-width: 720px) {
  .thread { padding: 42px 28px 20px; }
  .composer { padding-left: 28px; padding-right: 28px; }
  .standfirst { font-size: 20px; }
  .entry-q { font-size: 21px; max-width: 74%; }
  .claim-label { font-size: 20px; }
  .claim-quote { font-size: 19px; }
}
