/* The QOR shell stylesheet (T-112 §1.4 → T-116 §1.1 → T-119) — the editorial
   pass on the tokens.css layer (loaded BEFORE this file everywhere). The three
   moves (t-119 §1): serif speaks / system serves; the overline is the meta
   voice; hairlines separate, boxes work. Base rules ARE the phone; the
   min-width query is the wide-viewport form of the SAME CSS. Single column,
   tap targets >= 44px, no horizontal scroll anywhere (T-112 §1.4 holds).

   The calm laws as CSS law (t-119 §1): NO keyframes, transitions are
   color/border/background only and <= 150ms (dead under
   prefers-reduced-motion), no digits in pseudo-content, danger is never red.
   ⚠ AMENDED (T-211 Q1 ruling, 2026-07-19 — decision #70 discipline): ONE
   ratified keyframe exception exists — the evening post's single arrival
   fade (@keyframes qor-letters-arrive, in the T-211 section below), dead
   under prefers-reduced-motion. Every other keyframe stays forbidden. */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font: var(--text-base)/var(--leading) var(--font-system);
  color: var(--ink);
  background: var(--paper);
  overflow-wrap: break-word;   /* no horizontal scroll, ever (T-112 §1.4) */
}

/* the single-column member surface + every SSR page mount here */
#app, main {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--s4);
}

/* serif speaks (t-119 move 1): every heading is editorial */
h1, h2, h3 {
  font-family: var(--font-serif);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: var(--leading-tight);
  color: var(--ink);
}
h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
h3 { font-size: var(--step-1); }

a { color: var(--amber); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { color: var(--amber-deep); text-decoration: underline; text-underline-offset: 0.15em; }

::selection { background: var(--ring); }

/* the ONE focus treatment (t-119 §1.2): visible on every interactive element */
:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; }

/* motion law: color/border/background ONLY (spec §1) — the focus ring and
   shadows appear instantly, which is better a11y anyway (diff-gate finding 3) */
a, button, input, textarea, .qor-tab {
  transition: color var(--ease), background-color var(--ease),
              border-color var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}

/* media never forces a horizontal scroll (the T-102 renderers size the tile) */
img, video, figure { max-width: 100%; height: auto; }
figure { margin: var(--s4) 0; }

/* tap targets: everything interactive clears 44px (T-112 §1.4) */
button,
input,
textarea,
select {
  min-height: var(--tap);
  font: inherit;
}

/* chrome stays on the system stack even inside a serif reading surface */
button, input, textarea, select { font-family: var(--font-system); }

button {
  padding: var(--s2) var(--s4);
  cursor: pointer;
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
}
button:not([disabled]):hover { background: var(--wash); border-color: var(--line-strong); }
button[disabled] { opacity: 0.55; cursor: default; }

/* the composer + editors usable at 390px: full-width fields, no overflow */
input,
textarea {
  width: 100%;
  max-width: 100%;
  padding: var(--s2) var(--s3);
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input:focus, textarea:focus {
  border-color: var(--amber);
  box-shadow: 0 0 0 3px var(--ring);
  outline: none;
}
textarea { min-height: calc(var(--tap) * 2); resize: vertical; line-height: var(--leading); }

/* ── the overline: the meta voice (t-119 move 2) ─────────────────────────────
   dates, states, labels, bylines — everything that DESCRIBES rather than IS.
   (Georgian has no case; uppercase yields Mtavruli — the official, shouting
   register. Decision #121: a Georgian page never sets Mtavruli through CSS —
   the wordmark's companion is literal characters and is untouched.) */
html[lang="ka"] *:where([class]) { text-transform: none !important; }

.qor-field-label,
.qor-digest-count,
.qor-digest-day-label,
.qor-digest-byline,
.qor-digest-publication-kind,
.qor-reply-byline,
.qor-publication-state,
.qor-request-pending,
.qor-page-add-label,
.qor-shelf-date,
.qor-chip-label,
.qor-preview-domain,
.qor-digest-order-label,
.qor-paper-date,
.qor-paper-yard,
.qor-line-back-foot,
.qor-pubdate {
  font-family: var(--font-system);
  font-size: var(--overline-size);
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}

/* ── the app chrome (t-119 §1.2) ─────────────────────────────────────────── */

/* the calm tab bar (§1.2/§1.3) — real links, NO badge/count, ever */
.qor-tab-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  padding: 0;
  margin-bottom: var(--s4);
  border-bottom: 1px solid var(--line);
}
.qor-tab {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: var(--s2) var(--s3);
  text-decoration: none;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;          /* the underline sits ON the bar's hairline */
}
.qor-tab:hover { color: var(--ink); text-decoration: none; }
.qor-tab[aria-current="page"] { color: var(--ink); border-bottom-color: var(--amber); }

/* ── the component vocabulary (T-116 §1.2, dressed by t-119 §1.3) ──────────── */

/* button kinds */
.qor-btn { border-radius: var(--radius-sm); }
.qor-btn--primary { color: var(--paper); background: var(--amber); border-color: var(--amber); }
.qor-btn--primary:not([disabled]):hover { background: var(--amber-deep); border-color: var(--amber-deep); }
.qor-btn--ghost { color: var(--muted); background: transparent; border-color: transparent; }
.qor-btn--ghost:not([disabled]):hover { color: var(--ink); background: var(--wash); border-color: transparent; }
.qor-btn--danger { color: var(--conseq); background: transparent; border-color: var(--conseq); } /* consequence: saperavi, outlined — never red (#87) */
.qor-btn[disabled] { opacity: 0.55; cursor: default; }

/* the quiet control (t-119 §1.3): every small inline act, one voice —
   text-level, muted → amber, still a 44px target */
.qor-share-delete,
.qor-share-edit,
.qor-share-delete-confirm button,
.qor-reply-take-back,
.qor-reply-send,
.qor-thread-earlier,
.qor-line-back-write,
.qor-digest-chapter-header,
.qor-requests-set-aside-header,
.qor-unfriend-fold,
.qor-publication-open,
.qor-request-in button,
.qor-request-set-aside button,
.qor-request-out button {
  display: inline-flex;
  align-items: center;
  padding: var(--s1) var(--s2);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: var(--text-sm);
}
.qor-share-delete:not([disabled]):hover,
.qor-share-edit:not([disabled]):hover,
.qor-share-delete-confirm button:not([disabled]):hover,
.qor-reply-take-back:not([disabled]):hover,
.qor-reply-send:not([disabled]):hover,
.qor-thread-earlier:not([disabled]):hover,
.qor-line-back-write:not([disabled]):hover,
.qor-digest-chapter-header:not([disabled]):hover,
.qor-requests-set-aside-header:not([disabled]):hover,
.qor-unfriend-fold:not([disabled]):hover,
.qor-publication-open:not([disabled]):hover,
.qor-request-in button:not([disabled]):hover,
.qor-request-set-aside button:not([disabled]):hover,
.qor-request-out button:not([disabled]):hover {
  color: var(--amber-deep);
  background: var(--wash);
  border: none;
}

/* text field + its a11y error line (§1.2) */
.qor-field { display: block; margin: var(--s3) 0; }
.qor-field-label { display: block; margin-bottom: var(--s1); }
.qor-field-error { color: var(--muted); font-size: var(--text-sm); margin-top: var(--s1); }
.qor-field-input[aria-invalid="true"] { border-color: var(--amber); box-shadow: 0 0 0 3px var(--ring); }

/* card + section header */
.qor-card {
  margin: var(--s4) 0;
  padding: var(--s4);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qor-section-header { margin: var(--s5) 0 var(--s3); }

/* the notice inline line (§1.2): findable, never loud — a hairline rail */
.qor-notice {
  padding: var(--s1) var(--s3);
  border-left: 2px solid var(--muted);
  border-radius: 0;
}
.qor-notice--error   { color: var(--muted); }
.qor-notice--success { color: var(--pine); border-left-color: var(--pine); }
.qor-notice--info    { color: var(--muted); }

/* every calm refusal line, one voice (t-119 §1.9b) */
.qor-composer-error,
.qor-page-error,
.qor-digest-error,
.qor-befriend-error,
.qor-share-error,
.qor-reply-error,
.qor-request-error,
.qor-export-error { color: var(--muted); font-size: var(--text-sm); }

/* the one toast render site (§1.4) */
.qor-toasts {
  position: fixed;
  left: 50%;
  bottom: var(--s5);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  max-width: var(--measure);
  width: calc(100% - var(--s6));
  z-index: 10;
}
.qor-toast {
  padding: var(--s3) var(--s4);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-left-width: 2px;
  border-left-color: var(--muted);
  border-radius: var(--radius);
  color: var(--ink);
  box-shadow: var(--shadow-soft);
}
.qor-toast--success { border-left-color: var(--pine); }

/* empty states: a librarian's note, never a void that begs */
.qor-empty-state,
.qor-digest-empty {
  color: var(--muted);
  font-family: var(--font-serif);
  font-style: italic;
  padding: var(--s4) 0;
}
.qor-byline { color: var(--muted); font-size: var(--text-sm); }

/* the ONE modal (§1.2) */
.qor-modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s4);
  z-index: 20;
}
.qor-modal {
  position: relative;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s5);
  max-width: var(--measure);
  width: 100%;
  box-shadow: var(--shadow-soft);
}
.qor-modal-title { margin: 0 0 var(--s3); padding-right: var(--s7); }   /* clears the absolute × */
.qor-modal-close {
  position: absolute;
  top: var(--s2);
  right: var(--s2);
  margin: 0;
  padding: var(--s1) var(--s3);
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: var(--text-lg);
}
.qor-modal-close:not([disabled]):hover { color: var(--ink); background: var(--wash); border: none; }

/* ── the block renderers (t-119 §1.4 — every scope reads the same) ─────────── */

.qor-block { font-family: var(--font-serif); font-size: var(--text-reading); line-height: var(--leading-reading); }
.qor-text p { margin: 0 0 var(--s4); }
.qor-text p:last-child { margin-bottom: 0; }

.qor-block img, .qor-block video { border-radius: var(--radius); display: block; }
.qor-block figcaption { color: var(--muted); font-size: var(--text-sm); margin-top: var(--s2); font-family: var(--font-system); }

.qor-quote {
  border-left: 2px solid var(--line-strong);
  padding: var(--s1) 0 var(--s1) var(--s4);
}
.qor-quote blockquote {
  margin: 0;
  font-size: var(--text-lg);
  font-style: italic;
}
.qor-quote figcaption::before { content: "— "; }   /* punctuation, not copy */

.qor-link-card {
  display: block;
  margin: var(--s3) 0;
  padding: var(--s3) var(--s4);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: var(--font-system);
  font-size: var(--text-base);
  line-height: var(--leading);
  text-decoration: none;
}
a.qor-link-card:hover { border-color: var(--line-strong); color: var(--ink); text-decoration: none; }
/* a captioned card (T-120 §1.5): the figure carries the block margin */
.qor-link-card-figure .qor-link-card { margin: 0; }
.qor-link-card-title { display: block; font-weight: 500; }
.qor-link-card-desc { display: block; color: var(--muted); font-size: var(--text-sm); margin-top: var(--s1); }
.qor-link-card-domain {
  display: block;
  margin-top: var(--s2);
  font-size: var(--overline-size);
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}

/* a single photo in the FLOW surfaces is bounded (T-119 walk finding
   2026-07-15: a portrait upload ran 1.5 screens and broke the day-book's
   rhythm) — the reader serves the full frame, the digest serves the day */
.qor-photo img { max-height: 34rem; width: auto; max-width: 100%; }

/* photo grids: one column on the phone, tight mortar; widened past the fold.
   Cells are EQUALIZED (same walk finding: two intrinsic ratios rendered a
   lopsided pair with dead air under the shorter frame) — the grid is a
   contact sheet, the reader is the print */
.qor-photo-pair-grid img,
.qor-photo-wall-grid img {
  width: 100%;
  height: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
.qor-photo-pair-grid,
.qor-photo-wall-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s1);
}

/* ── the digest (t-119 §1.5 — the flagship): hairlines, not boxes ──────────── */

.qor-digest-count { margin: var(--s4) 0 var(--s2); }

.qor-digest-day { margin-top: var(--s5); }
.qor-digest-day-label {
  margin: 0;
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--line);
}
.qor-digest-day-items > * { padding: var(--s5) 0; }
.qor-digest-day-items > * + * { border-top: 1px solid var(--line); }

.qor-digest-item { font-family: var(--font-serif); font-size: var(--text-reading); line-height: var(--leading-reading); }
.qor-digest-byline { margin: 0 0 var(--s2); }

/* the collapsed publication announcement — announce, don't flood; beautifully */
a.qor-digest-publication {
  display: block;
  margin: var(--s3) 0;   /* air between the card's border and the row hairlines */
  padding: var(--s4) var(--s5);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  text-decoration: none;
}
a.qor-digest-publication:hover { background: var(--wash); border-color: var(--line-strong); color: var(--ink); text-decoration: none; }
.qor-digest-publication-title { font-size: var(--step-1); margin: var(--s1) 0; }
.qor-digest-publication-kind { margin: 0; }

/* the resonance item (a reply in the digest): quiet, content-first */
.qor-digest-reply,
.qor-digest-reply-text,
.qor-digest-reply-context { font-family: var(--font-serif); }
.qor-digest-reply-context { color: var(--muted); font-size: var(--text-sm); margin: 0 0 var(--s2); }
.qor-digest-reply-text { margin: 0; font-size: var(--text-reading); line-height: var(--leading-reading); }

/* "you're all caught up" — the end-mark; a real place (t-119 §1.5) */
.qor-digest-caught-up {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s4);
  width: 100%;
  margin: var(--s6) 0;
  padding: var(--s2) 0;
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: var(--text-sm);
}
.qor-digest-caught-up::before,
.qor-digest-caught-up::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--line);
}
button.qor-digest-caught-up:not([disabled]):hover { color: var(--ink); background: transparent; border: none; }

/* the paper (T-255): a dated masthead, the yard's small frames, a line back */
.qor-paper-head { margin: var(--s4) 0 var(--s2); }
.qor-paper-head h1 { margin: 0; font-size: var(--step-3); }
.qor-paper-date { margin: var(--s1) 0 0; }
.qor-paper-yard { margin: 0; }
/* one overline, not a padded band between two hairlines (T-255 gate) */
.qor-digest-day-items > .qor-paper-yard { padding: var(--s3) 0 var(--s1); }

.qor-frame-small {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2);
}
/* small means small: the day's hairline between rows stays, the air shrinks */
.qor-digest-day-items > .qor-frame-small { padding: var(--s2) 0; }
.qor-frame-small .qor-digest-byline { margin: 0; color: var(--ink); }
.qor-frame-glimpse {
  flex: 1;
  min-width: 0;
  margin: 0;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.qor-frame-open {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--s2);
  background: transparent;
  border: none;
  color: var(--ink);
  font-size: var(--text-sm);
  text-decoration: underline;
}

.qor-line-back { margin-top: var(--s2); }
.qor-line-back-foot { flex-basis: 100%; margin: 0; }
.qor-line-back-mine,
.qor-line-back-received { margin: var(--s2) 0; color: var(--ink); }
.qor-line-back-mine { display: inline; }
.qor-line-back-received { font-family: var(--font-serif); }

/* collapsed chapters: recession is a quiet shelf, never a nag */
.qor-digest-chapter { margin: var(--s2) 0; }
.qor-digest-chapter-header {
  font-size: var(--overline-size);
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
}
.qor-digest-chapter-items > * { padding: var(--s5) 0; }
.qor-digest-chapter-items > * + * { border-top: 1px solid var(--line); }

/* ── shares: the bench and the flow (t-119 §1.6) ───────────────────────────── */

/* the folded composer: a full-width invitation (POSITIONAL selector — spec
   §1.6 recorded fragility: the tab bar's next sibling is the fold button on
   the Shares tab only; if anything mounts between, this calmly reverts) */
.qor-tab-bar + .qor-btn {
  display: flex;
  width: 100%;
  justify-content: center;
  margin: var(--s4) 0;
  padding: var(--s3);
  background: transparent;
  color: var(--muted);
}
.qor-tab-bar + .qor-btn:not([disabled]):hover { background: var(--wash); color: var(--ink); }

/* the unfolded composer: a working surface — the bench, not the page */
.qor-composer {
  margin: var(--s4) 0;
  padding: var(--s5);
  background: var(--wash);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}
/* the writing-first surface (T-120 §1.1): the field IS the composer */
.qor-composer-text { width: 100%; min-height: calc(var(--tap) * 2.5); }

/* the one quiet row under the field (T-120 §1.2): attach + state chips */
.qor-composer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s2);
}
.qor-composer-attach {
  cursor: pointer;
  font-family: var(--font-system);
  font-size: var(--overline-size);
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
  padding: var(--s1) 0;
}
.qor-composer-attach:hover { color: var(--ink); }
/* the file input stays in the tab order, visually hidden — the label carries
   the focus ring via :focus-within (the T-119 focus law) */
.qor-composer-attach input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
.qor-composer-attach:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.qor-composer-chip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
}
.qor-chip-name { color: var(--muted); font-size: var(--text-sm); }
.qor-chip-alt { max-width: 18rem; }
.qor-composer-chip .qor-btn { margin: 0; }

/* the advisory preview card (T-120 §1.4): quiet, removable */
.qor-composer-preview {
  margin-top: var(--s3);
  padding: var(--s3) var(--s4);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qor-preview-title { margin: 0; overflow-wrap: anywhere; }
.qor-preview-domain { margin: var(--s1) 0 0; }
.qor-composer-preview .qor-btn { margin-top: var(--s2); }

/* the ISS-020 quiet hint, composer voice */
.qor-composer-hint { color: var(--muted); font-size: 0.9rem; margin: var(--s3) 0 0; }

/* the shape/add pickers: one pill voice (the composer's pills retired, T-120) */
.qor-page-shapes,
.qor-publish-actions,
.qor-page-section-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.qor-page-shapes button,
.qor-page-add button {
  border-radius: 999px;
  padding: var(--s1) var(--s4);
  font-size: var(--text-sm);
  background: transparent;
  border-color: var(--line);
  color: var(--muted);
}
.qor-page-shapes button:not([disabled]):hover,
.qor-page-add button:not([disabled]):hover { color: var(--ink); background: var(--paper-raised); }
.qor-page-section-fields { display: block; }
.qor-composer .qor-btn { margin-top: var(--s3); margin-right: var(--s2); }

/* progress: uploading is a fact, not a show (t-119 §1.9b) */
.qor-composer-progress,
.qor-page-uploading,
.qor-page-media-attached { color: var(--muted); font-size: var(--text-sm); }

/* own shares: the same hairline flow the digest reads in */
.qor-shares > * { padding: var(--s5) 0; }
.qor-shares > * + * { border-top: 1px solid var(--line); }
.qor-share {
  font-family: var(--font-serif);
  font-size: var(--text-reading);
  line-height: var(--leading-reading);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.qor-share > * { max-width: 100%; }
/* the owner controls sit as ONE quiet cluster at the row's foot (T-209 §1.6:
   Edit beside Remove; the confirm swaps the whole cluster out) */
.qor-share .qor-share-controls,
.qor-share .qor-share-delete-confirm { align-self: flex-end; margin-top: var(--s2); }
.qor-share-controls { display: inline-flex; align-items: center; gap: var(--s1); }
/* the editing composer stands IN PLACE of the block — full row width */
.qor-share > .qor-composer { width: 100%; }

/* the media states: a labeled resting place, not a broken hole (§1.9b) */
.qor-media-unavailable,
.qor-share-errored,
.qor-share-processing {
  color: var(--muted);
  font-family: var(--font-system);
  font-size: var(--text-sm);
  background: var(--wash);
  border-radius: var(--radius);
  padding: var(--s4);
  margin: var(--s2) 0;
}

/* threads: marginalia under their share (t-119 §1.6) */
.qor-thread {
  margin-top: var(--s4);
  padding-left: var(--s4);
  border-left: 1px solid var(--line);
  width: 100%;
  font-family: var(--font-system);
}
.qor-thread-replies { list-style: none; margin: 0; padding: 0; }
.qor-reply { padding: var(--s2) 0; }
.qor-reply-byline { margin: 0; }   /* the overline group above carries the voice */
.qor-reply-text { margin: var(--s1) 0; font-family: var(--font-serif); }
.qor-reply-composer { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); margin-top: var(--s2); }
.qor-reply-composer .qor-reply-input { flex: 1; min-width: 0; }
/* a refusal breaks BELOW the field, never squeezed beside Send */
.qor-reply-composer .qor-reply-error { flex-basis: 100%; margin: 0; }

/* ── the page: the exhibition at home (t-119 §1.7) ─────────────────────────── */

.qor-page-view > .qor-block { margin: var(--s4) 0 var(--s5); }

/* the line under the name (T-310): one sentence, reading size, muted — never
   bold, never quoted; the same class on /p/, the owner's page and the card */
.qor-page-head-line {
  margin: var(--s1) 0 var(--s3);
  font-size: var(--text-reading);
  font-weight: 400;
  color: var(--muted);
}
.qor-card-names .qor-page-head-line { margin: var(--s1) 0 0; }
/* the field that keeps it: the input full-width, Keep and its calm word beneath */
.qor-page-head-form { margin: 0 0 var(--s5); }
.qor-page-head-actions { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s2); }
.qor-page-head-kept { color: var(--muted); font-size: var(--text-sm); }
.qor-page-draft-note,
.qor-page-publish-consequence,
.qor-page-public,
.qor-publication-public { color: var(--muted); font-size: var(--text-sm); }
/* the fact lines sit under a hairline (spec §1.7) — draft AND published */
.qor-page-draft-note,
.qor-page-public,
.qor-publication-public { border-top: 1px solid var(--line); padding-top: var(--s4); margin-top: var(--s5); }

/* publish is the primary act; unpublish a quiet one (mirrors the ui kinds) */
.qor-page-publish,
.qor-publication-publish,
.qor-publish-confirm { color: var(--paper); background: var(--amber); border-color: var(--amber); }
.qor-page-publish:not([disabled]):hover,
.qor-publication-publish:not([disabled]):hover,
.qor-publish-confirm:not([disabled]):hover { background: var(--amber-deep); border-color: var(--amber-deep); }
.qor-page-unpublish,
.qor-publication-unpublish,
.qor-publish-cancel { color: var(--muted); background: transparent; border-color: transparent; }
.qor-page-unpublish:not([disabled]):hover,
.qor-publication-unpublish:not([disabled]):hover,
.qor-publish-cancel:not([disabled]):hover { color: var(--ink); background: var(--wash); border-color: transparent; }

/* the page editor: section cards are working surfaces (boxes stay here) */
.qor-page-sections { display: block; }
.qor-page-section {
  margin: var(--s4) 0;
  padding: var(--s4);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qor-page-section-fields > div > input,
.qor-page-section-fields > div > textarea { margin-top: var(--s2); }
.qor-page-section-controls { margin-top: var(--s3); }
.qor-page-section-controls button {
  padding: var(--s1) var(--s2);
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: var(--text-sm);
}
.qor-page-section-controls button:not([disabled]):hover { color: var(--amber-deep); background: var(--wash); border: none; }
.qor-page-add { margin: var(--s4) 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.qor-page-editor .qor-btn { margin-top: var(--s3); margin-right: var(--s2); }
.qor-page-editing-published,
.qor-publication-editing-published { color: var(--muted); font-size: var(--text-sm); }

/* ── publications: the desk and the writing room (t-119 §1.8) ──────────────── */

.qor-publications-list { list-style: none; margin: var(--s4) 0; padding: 0; }
.qor-publication-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) var(--s3);
  padding: var(--s2) 0;
  border-top: 1px solid var(--line);
}
.qor-publication-row:last-child { border-bottom: 1px solid var(--line); }
.qor-publication-row:hover { background: var(--wash); }
.qor-publication-title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-serif);
  font-size: var(--text-lg);
}
.qor-publication-open { margin-left: auto; }

/* the view: reader-adjacent */
.qor-publication-view-title { font-size: var(--step-3); margin: var(--s4) 0 var(--s2); }
.qor-publication-view-subtitle {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  color: var(--muted);
  margin: 0 0 var(--s4);
}
.qor-publication-view > .qor-block { margin-bottom: var(--s5); }
.qor-publication-view .qor-btn { margin-right: var(--s2); }

/* the editor: an input that looks like the title it will be. The three
   REQUIRED properties (spec §1.8): the hairline underneath, the muted
   placeholder (global), the focus ring — none may be dropped. */
.qor-publication-title-input,
.qor-publication-subtitle-input {
  font-family: var(--font-serif);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: var(--s2) 0;
}
.qor-publication-title-input { font-size: var(--step-2); font-weight: 600; }
.qor-publication-subtitle-input { font-size: var(--text-lg); margin-bottom: var(--s3); }
.qor-publication-title-input:focus,
.qor-publication-subtitle-input:focus {
  border-color: var(--line-strong);
  border-bottom-color: var(--amber);
  box-shadow: 0 0 0 3px var(--ring);
}
/* an EMPTY headline input must read as a prompt, not a rendered heading —
   the muted-at-full-weight placeholder cost the founder his title TWICE in
   one walk (ISS-020): "Title" looked typeset, so the eye typed a line below */
.qor-publication-title-input::placeholder,
.qor-publication-subtitle-input::placeholder {
  font-style: italic;
  font-weight: 400;
  color: var(--muted);
  opacity: 0.5;
}
/* ISS-020's voice: the quiet line explaining why Save withholds itself */
.qor-publication-hint { color: var(--muted); font-size: 0.9rem; margin: var(--s3) 0 0; }
.qor-publication-editor .qor-btn { margin-top: var(--s3); margin-right: var(--s2); }

/* the writing surface: ProseMirror in the serif reading voice */
.qor-prose {
  margin: var(--s3) 0;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qor-prose:focus-within { border-color: var(--line-strong); }
.qor-prose-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1);
  padding: var(--s1) var(--s2);
  border-bottom: 1px solid var(--line);
}
.qor-prose-btn {
  min-height: var(--tap);
  padding: var(--s1) var(--s3);
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: var(--text-sm);
}
.qor-prose-btn:not([disabled]):hover { color: var(--ink); background: var(--wash); border: none; }
.qor-prose-host { padding: var(--s3) var(--s4); }
.qor-prose-host .ProseMirror {
  outline: none;
  font-family: var(--font-serif);
  font-size: var(--text-reading);
  line-height: var(--leading-reading);
  min-height: 12rem;
  /* PM's contract (its console warning is right): without pre-wrap,
     consecutive spaces and soft breaks collapse while editing */
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* the publish dialog: the one consent moment — it may sit up straight */
.qor-publish-dialog {
  margin: var(--s4) 0;
  padding: var(--s5);
  background: var(--wash);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}
.qor-publish-signs { margin-top: 0; }
.qor-publish-open-web { color: var(--muted); font-size: var(--text-sm); }
.qor-publish-url { font-size: var(--text-sm); }

/* the byline consent controls sit on ONE line with their sentence (T-118
   §1.5): both callsites, same anatomy. The LABEL is the 44px tap target;
   the box itself sizes like a checkbox. */
.qor-publications-byline,
.qor-publish-byline {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: var(--tap);
}
.qor-publications-byline input[type="checkbox"],
.qor-publish-byline input[type="checkbox"] {
  min-height: 0;
  width: 1.1rem;
  height: 1.1rem;
  margin: 0;
  flex: none;
  accent-color: var(--amber);
}

/* ── people + things (t-119 §1.9) ──────────────────────────────────────────── */

/* descendant, not child (diff-gate finding 1): the request lists nest their
   ULs inside divs — child-only left them browser-indented 40px beside a
   flush friends list. The classed lists' own rules win where they differ. */
main section ul { list-style: none; margin: var(--s2) 0; padding: 0; }

.qor-request-in,
.qor-request-out,
.qor-request-set-aside,
main li:has(> .pen-name) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1) var(--s3);
  padding: var(--s2) 0;
  border-top: 1px solid var(--line);
}
li .pen-name { font-family: var(--font-serif); font-weight: 600; }
li .real-name { color: var(--muted); font-size: var(--text-sm); }

/* T-208 §1.10: the end-of-friendship fold on a My People row. The label is
   the quiet control above; the fold's body takes the row's full width so the
   one line, the one sentence and the one control sit under the name, never
   crowding it. Nothing here is red — the act is calm, not an alarm. */
.qor-unfriend-fold { margin-left: auto; }
.qor-unfriend-panel { flex-basis: 100%; padding: var(--s2) 0 var(--s1); }
.qor-unfriend-line { margin: 0 0 var(--s1); }
.qor-unfriend-note,
.qor-unfriend-error { color: var(--muted); font-size: var(--text-sm); }
.qor-unfriend-note { margin: 0 0 var(--s2); max-width: 34em; }
.qor-unfriend-error { margin: var(--s1) 0 0; }

.qor-export {
  margin: var(--s5) 0;
  padding: var(--s5);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qor-export h2 { margin-top: 0; font-size: var(--step-1); }
.qor-export-building, .qor-export-expiry { color: var(--muted); font-size: var(--text-sm); }

/* the digest ordering choice (T-121 §3.4): a quiet Things control */
.qor-digest-order { margin: var(--s5) 0; }
.qor-digest-order-options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s2);
}
.qor-digest-order-options button {
  border-radius: 999px;
  padding: var(--s1) var(--s4);
  font-size: var(--text-sm);
  background: transparent;
  border-color: var(--line);
  color: var(--muted);
}
.qor-digest-order-options button:not([disabled]):hover { color: var(--ink); background: var(--paper-raised); }
.qor-digest-order-options button.is-selected {
  background: var(--paper-raised);
  border-color: var(--line-strong);
  color: var(--ink);
}
.qor-digest-order-explainer { color: var(--muted); font-size: var(--text-sm); margin: var(--s2) 0 0; }
.qor-digest-order-error { color: var(--muted); font-size: var(--text-sm); }

/* ── the calm states (t-119 §1.9b) ─────────────────────────────────────────── */

.connecting,
.pending-logout,
.signed-out {
  text-align: center;
  margin-top: var(--s7);
  font-family: var(--font-serif);
  color: var(--muted);
}
.pending-logout button { margin-top: var(--s3); }

.qor-befriend-prompt { font-family: var(--font-serif); font-size: var(--text-lg); }

/* /privacy — the honesty page (A6 ruling 2026-07-16): the reading voice,
   left-set unlike the centered welcome — it is read, not glanced */
main.qor-privacy { max-width: 34rem; margin: 0 auto; padding: var(--s6) var(--s4); }
.qor-privacy-wordmark { font-family: var(--font-serif); }
.qor-privacy-wordmark a { text-decoration: none; }
main.qor-privacy h1 { font-family: var(--font-serif); font-weight: 400; }
main.qor-privacy p:not(.qor-privacy-wordmark) {
  font-family: var(--font-serif);
  font-size: var(--text-reading);
  line-height: var(--leading-reading);
}

/* the in-app not-found surface (ISS-023): calm bearings, the way home */
.qor-not-found { text-align: center; margin-top: var(--s7); }
.qor-not-found-title { font-family: var(--font-serif); font-weight: 400; }
.qor-not-found-line { color: var(--muted); }
.qor-not-found-home { display: inline-block; margin-top: var(--s3); }

/* ── the doors + the welcome (SSR — t-119 §1.10) ───────────────────────────── */

/* the SSR welcome (T-112 §1.3): a closed door with a warm lamp on */
main:has(> .qor-welcome-tagline) { text-align: center; padding-top: 18vh; }
main:has(> .qor-welcome-tagline) h1 { margin-bottom: var(--s5); }
.qor-welcome-tagline { font-family: var(--font-serif); font-size: var(--text-lg); }
.qor-welcome-invitation { color: var(--muted); }

/* the door forms (login/join): scoped on what doors OWN — `main > form`
   (NEVER `body > main`: the welcome, /p, and the /p 404 share that anatomy).
   Door buttons stay STANDARD (spec-gate finding 4: the code-entry door's two
   buttons are structurally identical — CSS cannot split them). */
main > form { max-width: 26rem; margin: var(--s4) 0; }
main > form label {
  display: block;
  font-size: var(--overline-size);
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}
main > form label input { display: block; margin-top: var(--s2); font-size: var(--text-base); }
main > form p { margin: var(--s3) 0; }
/* the door's own prose — intro, stale notice, refusal, "didn't arrive?" —
   speaks in the notice voice (spec §1.10; diff-gate finding 2). Doors alone
   have a form as main's direct child (audited: not the welcome, /p, the 404,
   or any app surface), so the h1 stays ink and the meta lines go muted. */
main:has(> form) > p { color: var(--muted); }

/* ── the public /p surfaces (t-119 §1.11 — now on this stylesheet) ─────────── */

/* the SSR wordmark: its own anatomy — body > header, page-wide hairline */
body > header { border-bottom: 1px solid var(--line); }
body > header a {
  display: inline-block;
  padding: var(--s4) var(--s5);
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}
body > header a:hover { color: var(--amber-deep); text-decoration: none; }

/* the shelf: published work, listed like a colophon */
.qor-shelf { margin: var(--s6) 0; }
.qor-shelf-list { list-style: none; margin: 0; padding: 0; }
.qor-shelf-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s3);
  padding: var(--s3) 0;
  border-top: 1px solid var(--line);
}
.qor-shelf-item:last-child { border-bottom: 1px solid var(--line); }
.qor-shelf-item a { flex: 1; min-width: 0; font-family: var(--font-serif); font-size: var(--text-lg); }

/* the studio: the intimate layer reads like the digest */
.qor-studio { margin: var(--s6) 0; }
.qor-studio > * { padding: var(--s5) 0; }
.qor-studio > * + * { border-top: 1px solid var(--line); }

/* the SSR befriend line (page.clj — distinct from the client surface) */
p.qor-befriend { color: var(--muted); }

/* ── T-211: the letters experience (the founder-approved concept) ────────────
   Make time visible and beautiful. The `.qor-letters-*`/`.qor-tempo-*` family
   consumes tokens ONLY. One deliberate amendment to the t-119 no-keyframes
   law: the Q1 ruling — the evening post's bundle APPEARS with ONE slow fade
   (motion as breath, once; dead under prefers-reduced-motion). No digit ever
   enters this chrome (the no-digit pin extends to every rule below). */

/* the shared overline voice for the letters surfaces */
.qor-letters-post-head,
.qor-letter-cue,
.qor-letters-when,
.qor-letters-overline {
  font-family: var(--font-system);
  font-size: var(--overline-size);
  font-weight: 500;
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}

/* A · the evening post: today's arrivals as ONE raised bundle */
.qor-letters-post { margin: var(--s4) 0; }
.qor-letters-post-head { display: block; margin: 0 0 var(--s3); color: var(--amber); }
.qor-letters-bundle {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
  animation: qor-letters-arrive 900ms ease-out both;   /* the Q1 fade — once */
}
@keyframes qor-letters-arrive { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .qor-letters-bundle { animation: none; }
}
.qor-letter-threads { list-style: none; margin: var(--s4) 0 0; padding: 0; }
.qor-letters-bundle .qor-letter-thread-row + .qor-letter-thread-row { border-top: 1px solid var(--line); }
.qor-letter-threads .qor-letter-thread-row { border-top: 1px solid var(--line); }
.qor-letter-threads .qor-letter-thread-row:last-child { border-bottom: 1px solid var(--line); }
.qor-letter-thread-link {
  display: flex;
  gap: var(--s3);
  align-items: baseline;
  padding: var(--s3) var(--s4);
  color: var(--ink);
  min-height: var(--tap);
}
.qor-letter-thread-link:hover { color: var(--ink); text-decoration: none; background: var(--wash); }
.qor-letter-friend {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: var(--text-lg);
  min-width: 4.4em;
}
.qor-letters-here-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--here);      /* presence: live and mutual, gone when gone */
  margin-left: 6px;
  vertical-align: 2px;
}
.qor-letter-main { flex: 1; min-width: 0; }
.qor-letters-day { color: var(--muted); font-size: var(--text-sm); white-space: nowrap; }
.qor-letters-empty { color: var(--muted); }

/* the notices lens (T-206 call 3) — in the letters rows' voice: a quiet
   line, the phrase in serif, the day-word muted and apart. (Found at the
   2026-08-28 walk: the surface had shipped with NO css — a browser-default
   bulleted list, the day-word colliding with the phrase.) */
.qor-notices { list-style: none; margin: var(--s3) 0 var(--s4); padding: 0; display: grid; gap: var(--s1); }
.qor-notice-row { margin: 0; }
.qor-notice-link {
  display: flex;
  gap: var(--s2);
  align-items: baseline;
  color: var(--ink);
  text-decoration: none;
  padding: var(--s1) 0;
}
.qor-notice-link:hover { text-decoration: underline; }
.qor-notice-text { font-family: var(--font-serif); }
.qor-notice-day { color: var(--muted); font-size: var(--text-sm); white-space: nowrap; }

/* B · the thread that breathes: letters as letters, talk as talk */
.qor-letter-thread-name { margin-bottom: var(--s1); }
/* T-208 §1.8: an ended correspondence closes on one quiet line where the
   writing room used to be — the same weight as the gone line, never louder */
.qor-letters-between { color: var(--muted); font-size: var(--text-sm); margin: var(--s4) 0; }
.qor-letters-flow { margin: var(--s4) 0; }
.qor-letters-letter { margin: var(--s5) 0 var(--s2); }
.qor-letters-letterhead { margin-bottom: var(--s2); }
.qor-letters-from { font-family: var(--font-serif); font-weight: 600; }
.qor-letters-when { margin-left: var(--s2); }
.qor-letters-body {
  font-family: var(--font-serif);
  font-size: var(--text-reading);
  line-height: var(--leading-reading);
  max-width: 34em;
  margin: 0;
  white-space: pre-wrap;
}
/* your letters carry a rule, not a bubble — the quote-rail idiom */
.qor-letters-body.qor-mine {
  border-left: 2px solid var(--line-strong);
  padding-left: var(--s3);
}
.qor-letters-gap-rule {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: var(--s5) 0;
  color: var(--muted);
}
.qor-letters-gap-rule::before,
.qor-letters-gap-rule::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.qor-letters-gap-rule span {
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
}
/* runs breathe: --s1 within a run, --s5 between runs (walk ruling 2026-08-28 —
   at --s3 a nineteen-minute silence measured 12px against 4px, and read as
   nothing; a silence has to weigh something). */
.qor-letters-chat-run { display: grid; gap: var(--s1); margin: var(--s5) 0; }
/* the header's pine `· on your line` beside the rhythm cue (the concept's
   identity line); the separator is chrome, so it lives here, not in the dict */
.qor-letters-on-line { color: var(--here); }
.qor-letters-on-line::before { content: " · "; color: var(--muted); }
.qor-chat-line {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: 1.45;
  padding: 6px 12px;
  border-radius: var(--radius);
  max-width: 85%;
  width: fit-content;
  white-space: pre-wrap;
}
.qor-chat-line.qor-theirs { background: var(--wash); }
.qor-chat-line.qor-mine {
  background: var(--paper-raised);
  border: 1px solid var(--line);
  margin-left: auto;
}

/* C · the writing room: room to write, one line of foreknowledge */
.qor-letter-composer {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper-raised);
  padding: var(--s3);
  margin-top: var(--s5);
}
.qor-letter-text {
  font-family: var(--font-serif);
  font-size: var(--text-reading);
  line-height: var(--leading-reading);
  min-height: 5.2em;                 /* paragraph height: sentences, not fragments */
  border: 0;
  padding: var(--s1) 0;
}
.qor-letter-text:focus { border: 0; box-shadow: none; }
/* the field is borderless inside the card, so the ONE focus ring (t-119
   §1.2) rides the card itself */
.qor-letter-composer:focus-within {
  border-color: var(--amber);
  box-shadow: 0 0 0 3px var(--ring);
}
.qor-letters-composer-foot {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s3);
}
.qor-letters-composer-foot > :last-child { margin-left: auto; }
.qor-tempo-line { margin: 0; font-size: var(--text-sm); color: var(--muted); }
.qor-tempo-line--pine { color: var(--pine); }
.qor-letter-hint, .qor-letter-error { color: var(--muted); font-size: var(--text-sm); }

/* D · when letters reach you: the day-arc, the seats, the two modes */
.qor-letters-settings .qor-letters-overline { display: block; margin: var(--s4) 0 var(--s2); }
.qor-letters-arc { margin: var(--s2) 0; }
.qor-letters-arc-band {
  display: flex;
  height: 34px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  overflow: hidden;
  touch-action: none;                 /* the paint gesture owns the pointer */
}
.qor-letters-arc-seg { flex: 1; border-left: 1px solid var(--line); cursor: pointer; }
.qor-letters-arc-seg:first-child { border-left: 0; }
.qor-letters-arc-seg--on { background: var(--amber); opacity: 0.85; }
/* the keyboard path's cursor (the band is tabbable; arrows walk it) */
.qor-letters-arc-seg--cursor { box-shadow: inset 0 0 0 2px var(--amber-deep); }
.qor-letters-arc-labels { display: flex; margin-top: var(--s1); }
.qor-letters-arc-labels span {
  flex: 1;
  text-align: center;
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}
.qor-letters-consequence { margin: var(--s3) 0 0; font-size: var(--text-sm); color: var(--muted); }
.qor-letters-cue-preview { margin: var(--s1) 0 0; font-size: var(--text-sm); color: var(--muted); }
.qor-letters-cue-words { color: var(--here); font-weight: 600; }
.qor-letters-seats { display: flex; gap: var(--s2); flex-wrap: wrap; margin: var(--s2) 0 var(--s1); }
.qor-letters-seat {
  width: var(--tap);
  height: var(--tap);
  min-height: var(--tap);
  padding: 0;
  border-radius: 50%;
  border: 1px dashed var(--line-strong);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-serif);
  font-weight: 600;
  color: var(--muted);
}
.qor-letters-seat--filled {
  border-style: solid;
  border-color: var(--amber);
  background: var(--wash);
  color: var(--ink);
  cursor: pointer;
}
.qor-letters-seat--filled:not([disabled]):hover { background: var(--wash); border-color: var(--amber-deep); }
.qor-letters-open-line-cap { color: var(--muted); font-size: var(--text-sm); margin: var(--s2) 0; }
.qor-letters-line-add { display: flex; gap: var(--s2); flex-wrap: wrap; }
.qor-letters-chip { font-size: var(--text-sm); padding: var(--s2) var(--s3); }
.qor-letters-modes { display: flex; gap: var(--s2); margin-top: var(--s4); }
.qor-letters-mode {
  flex: 1;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: transparent;
  padding: var(--s3);
  font-size: var(--text-sm);
  color: var(--muted);
}
.qor-letters-mode .qor-letters-overline { margin: 0 0 var(--s1); }
.qor-letters-mode--on { border-color: var(--amber); background: var(--wash); color: var(--ink); }
.qor-letters-mode-body { display: block; }
.qor-letters-cadence { margin-top: var(--s4); }
.qor-letters-cadence-label {
  display: block;
  margin-bottom: var(--s1);
  font-size: var(--text-sm);
  color: var(--muted);
}
.qor-letters-settings > button, .qor-letters-settings .qor-btn { margin-top: var(--s4); }
.qor-letters-error { color: var(--muted); font-size: var(--text-sm); }

/* ── wide viewport: the same CSS, roomier (T-112 §1.4) ─────────────────────── */
@media (min-width: 48rem) {
  .qor-photo-pair-grid { grid-template-columns: 1fr 1fr; }
  .qor-photo-wall-grid { grid-template-columns: repeat(3, 1fr); }
  #app, main { padding: var(--s6); }
}

/* ── the shell: the gradient (T-256, decision #90) ─────────────────────────
   Phone: one column — the route's own surface — and the foot naming the depth.
   Desk (≥ 62.5rem): the same screens as three columns, street · yard · focus
   (proto v2); the foot hides. Every column is rendered; CSS decides what shows. */
main.qor-shell { padding-bottom: calc(var(--tap) + var(--s5) + env(safe-area-inset-bottom)); }
.qor-col:not(.is-route) { display: none; }

.qor-foot {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: space-around;
  padding: 0 var(--s2) env(safe-area-inset-bottom);
  background: var(--paper);
  border-top: 1px solid var(--line);
  z-index: 5;
}
.qor-foot a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--s2);
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
}
.qor-foot a[aria-current="page"] {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: var(--s1);
}
.qor-toasts { bottom: calc(var(--tap) + var(--s5) + env(safe-area-inset-bottom)); }

/* the overline with its hairline (the proto's section label) */
.qor-overline {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: var(--s5) 0 var(--s2);
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}
.qor-overline::after { content: ""; flex: 1; border-top: 1px solid var(--line); }

/* the hearth (T-256 §1.3, #91): the top line, the faces, the door, the paper, a room to write */
.qor-yard-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s2) 0 var(--s1);
}
.qor-wordmark { font-weight: 700; font-size: var(--text-lg); }
.qor-wordmark-ka { margin-left: var(--s2); font-weight: 500; font-size: var(--text-sm); color: var(--muted); }
.qor-yard-top-end { display: flex; align-items: baseline; gap: var(--s3); }
.qor-yard-yours { font-size: var(--text-sm); color: var(--muted); }
.qor-yard-yours:hover { color: var(--ink); }
.qor-yard-day {
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}
.qor-faces {
  display: flex;
  gap: var(--s4);
  overflow-x: auto;
  padding: var(--s3) var(--s1) var(--s2);
  scrollbar-width: none;
}
.qor-face-link {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  gap: var(--s1);
  width: calc(var(--tap) + var(--s5));
  font-size: var(--text-sm);
  color: var(--ink);
  text-decoration: none;
}
.qor-face-link:hover { text-decoration: none; }
.qor-face {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  border-radius: 50%;
  background: var(--wash);
  border: 1px solid var(--line);
  font-weight: 600;
  color: var(--muted);
}
.qor-face.here::after {   /* the ring that says here — saperavi, never a dot or a count */
  content: "";
  position: absolute;
  inset: calc(-1 * var(--s1));
  border-radius: 50%;
  border: 2px solid var(--here);
}
.qor-face-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.qor-yard-door,
.qor-yours-row,
.qor-card-row,
.qor-balcony-page {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  min-height: var(--tap);
  padding: var(--s3) var(--s1);
  border: none;
  border-top: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  text-align: left;
  text-decoration: none;
}
.qor-yard-door:hover,
.qor-yours-row:hover,
.qor-card-row:hover,
.qor-balcony-page:hover { color: var(--ink); text-decoration: none; background: var(--wash); }
.qor-yard-door-sub,
.qor-yours-row-sub,
.qor-card-row-sub,
.qor-balcony-page-sub { color: var(--muted); font-size: var(--text-sm); }
.qor-yard-write {
  display: block;
  width: 100%;
  margin: var(--s5) 0;
  padding: var(--s3) var(--s4);
  text-align: left;
  color: var(--muted);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* the balcony and your room: a title, a quiet sub, then rows */
.qor-balcony-head h1,
.qor-yours-head h1 { margin: var(--s2) 0 0; }
.qor-balcony-sub,
.qor-yours-sub { margin: var(--s1) 0 0; color: var(--muted); font-size: var(--text-sm); }
.qor-balcony-pages { list-style: none; margin: 0; padding: 0; }
.qor-balcony-page { flex-direction: column; align-items: flex-start; gap: var(--s1); }
.qor-balcony-page-sub > * + *::before { content: " · "; }   /* the separator is chrome */
.qor-balcony-face { padding: var(--s3) 0; }
.qor-balcony-pen { margin: 0 0 var(--s1); font-size: var(--step-1); font-weight: 700; }
.qor-balcony-lace,
.qor-yours-end { margin: var(--s5) 0; color: var(--muted); font-size: var(--text-sm); }
.qor-yours-end { text-align: center; }

/* your code (T-303 §6): the QR (its SVG carries its own white ground — a
   camera reads contrast, not the theme), then the asks, each a face, a pen
   name, yes · not now */
.qor-code-sub { margin: 0 0 var(--s4); color: var(--muted); font-size: var(--text-sm); }
.qor-code-qr {
  display: block;
  width: 100%;
  max-width: 18rem;
  margin: 0 auto var(--s5);
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
}
.qor-code-asks { list-style: none; margin: 0; padding: 0; }
.qor-code-ask {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--tap);
  padding: var(--s2) 0;
  border-top: 1px solid var(--line);
}
.qor-code-pen { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* an invitation's ask (T-304): the typed address over when it arrived, then
   the holder's two answers — the yes is a sentence, so the row wraps */
.qor-invite-ask { flex-wrap: wrap; }
.qor-invite-who { display: flex; flex-direction: column; flex: 1 1 100%; min-width: 0; }
.qor-invite-word { font-weight: 600; letter-spacing: .02em; }

/* the relationship card (T-256 §1.8): the pair's page — one face, two seats, one quiet way out */
.qor-card-held,
.qor-card-identity {
  margin: var(--s2) 0 0;
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}
.qor-card-who { display: flex; align-items: center; gap: var(--s4); margin: var(--s4) 0 var(--s1); }
.qor-card-face { width: calc(var(--tap) + var(--s5)); height: calc(var(--tap) + var(--s5)); font-size: var(--step-2); }
.qor-card-names { flex: 1; min-width: 0; }
.qor-card-name {
  min-height: var(--tap);
  padding: 0;
  border: none;
  background: transparent;
  color: var(--ink);
  font-size: var(--step-2);
  font-weight: 700;
  text-align: left;
}
.qor-card-name-form { display: flex; align-items: flex-end; gap: var(--s2); }
.qor-card-name-form .qor-field { flex: 1; }
.qor-card-identity > * + *::before { content: " · "; }   /* the separator is chrome */
.qor-card-row:disabled { color: var(--muted); }
.qor-card-refusal,
.qor-card-here { margin: var(--s2) 0 0; color: var(--muted); font-size: var(--text-sm); }

@media (min-width: 62.5rem) {
  #app { max-width: none; padding: 0; }
  /* the mount's reading measure (#app above) would otherwise cap the desk at
     720px and starve the middle column to 0px (the 2026-10-23 desk walk) */
  #app:has(> main.qor-shell) { width: 100%; max-width: none; margin: 0; padding: 0; }
  main.qor-shell {
    display: flex;
    flex-direction: column;
    max-width: none;
    height: 100vh;
    padding: 0;
  }
  .qor-desk {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: 300px minmax(0, 1.25fr) 420px;   /* proto v2's desk */
  }
  .qor-col:not(.is-route),
  .qor-col { display: block; min-height: 0; overflow-y: auto; padding: var(--s4) var(--s5) var(--s6); }
  .qor-col + .qor-col { border-left: 1px solid var(--line); }
  .qor-foot { display: none; }
  .qor-toasts { bottom: var(--s5); }
}

/* your rhythm (T-257 §1.11): the page's sections under overlines, the paper's
   native time field, the zone said aloud, the disclosure, the quiet choices */
.qor-rhythm-time {
  display: block;
  min-height: var(--tap);
  margin: var(--s1) 0 var(--s2);
  padding: var(--s2) var(--s3);
  font: inherit;
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qor-rhythm-zone {
  margin: var(--s3) 0 0;
  font-size: var(--overline-size);
  letter-spacing: var(--overline-ls);
  text-transform: uppercase;
  color: var(--muted);
}
.qor-rhythm-disclosure { margin: var(--s2) 0 0; color: var(--muted); font-size: var(--text-sm); }
.qor-rhythm-choice { display: flex; flex-wrap: wrap; gap: var(--s4); }
.qor-rhythm-choice button {
  min-height: var(--tap);
  padding: 0 var(--s1);
  border: none;
  border-bottom: 1px solid transparent;
  border-radius: 0;
  background: transparent;
  font-size: var(--text-sm);
  color: var(--muted);
}
.qor-rhythm-choice button:hover { color: var(--ink); background: transparent; }
.qor-rhythm-choice button[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--ink); }

/* T-305 · the welcome letter: the thread's letterhead and reading measure,
   its paragraphs spaced as a letter's, its links whole sentences */
.qor-welcome .qor-letters-body { white-space: normal; }
.qor-welcome .qor-letters-body p { margin: 0 0 var(--s3); }
.qor-welcome-signed { font-weight: 600; }
