/* door.css — only what style.css does not already give: the sign-in card, the honest
   sentence list, the seat reveal banner, the intake/upload/read/delivery screens of
   app.html. Reuses style.css's tokens (--ink, --gold, --cream, --s-*, --step-*, etc.)
   rather than inventing a second palette. Verified by hand at 375px and at desktop
   widths — no rule below assumes a width wider than a phone. */

.door-shell {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--ink-deep);
}

.door-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-6) var(--s-4);
}

.door-card {
  width: 100%;
  max-width: 34rem;
  background: var(--cream);
  border-radius: var(--radius-lg);
  border-top: 5px solid var(--gold);
  box-shadow: var(--shadow-3);
  padding: var(--s-7) var(--s-6);
}

.door-card h1 {
  font-size: var(--step-2);
  margin-bottom: var(--s-4);
}

.sentence-list {
  list-style: none;
  margin: var(--s-5) 0;
  padding: 0;
  display: grid;
  gap: var(--s-4);
}
.sentence-list li {
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-soft);
  padding-left: var(--s-4);
  border-left: 3px solid var(--parchment-deep);
}

.field-label {
  display: block;
  font-family: var(--sans);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin: var(--s-5) 0 var(--s-2);
}

.text-field {
  width: 100%;
  font-family: var(--sans);
  font-size: var(--step-0);
  padding: var(--s-3) var(--s-4);
  /* THE UI PASS (2026-09-20, WCAG 2.2 · 1.4.11 Non-text Contrast): the field's edge is the only
     thing that says a field is there, so it must clear 3:1 against what is beside it. The old
     `--parchment-deep` measured 1.32:1 on white — invisible to a reader with low contrast
     sensitivity. `--wood` measures 7.5:1 on white and 7.04:1 on cream, and is already a house
     token; no new colour is invented. */
  border: 1px solid var(--wood);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
}
.text-field:focus-visible { outline: 3px solid var(--gold); outline-offset: 1px; }

.form-row { margin: var(--s-4) 0; }
.form-note { font-size: var(--step--1); color: var(--ink-soft); margin: var(--s-2) 0 0; }
.form-error {
  font-family: var(--sans);
  font-size: var(--step--1);
  color: var(--brick, #8C2F1E);
  margin: var(--s-2) 0 0;
  min-height: 1.2em;
}

.seat-reveal {
  background: var(--ink);
  color: var(--navy-band-soft);
  border-radius: var(--radius);
  border-top: 4px solid var(--gold);
  padding: var(--s-5) var(--s-6);
  margin-bottom: var(--s-5);
  text-align: center;
}
.seat-reveal .seat-code {
  font-family: var(--sans);
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--gold-bright);
  word-break: break-all;
  margin: var(--s-2) 0;
}

/* ---------- app.html: steps ---------- */

.app-shell { max-width: 52rem; margin: 0 auto; padding: var(--s-6) var(--s-4) var(--s-9); }

.step-rail {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  padding: 0;
  margin: 0 0 var(--s-6);
  font-family: var(--sans);
  font-size: var(--step--1);
}
.step-rail li {
  padding: var(--s-2) var(--s-3);
  border-radius: 999px;
  background: var(--parchment);
  color: var(--ink-soft);
}
.step-rail li[aria-current="step"] { background: var(--gold); color: var(--ink-deep); font-weight: 700; }
.step-rail li[data-done="true"] { background: var(--ink); color: var(--gold-bright); }

.app-panel {
  background: var(--cream);
  border: 1px solid var(--parchment-deep);
  border-top: 4px solid var(--gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: var(--s-6);
  margin-bottom: var(--s-5);
}
.app-panel[hidden] { display: none; }

.intake-question { margin-bottom: var(--s-5); }
.intake-question .q-text { font-family: var(--serif); font-size: var(--step-1); font-style: italic; margin-bottom: var(--s-2); }
.intake-answer-row { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.intake-answer-row button {
  font-family: var(--sans);
  font-size: var(--step--1);
  padding: var(--s-2) var(--s-5);
  border-radius: var(--radius);
  /* THE UI PASS (2026-09-20, WCAG 2.2 AA):
     · the border is the ONLY thing that says a button is there, so 1.4.11 Non-text Contrast
       applies to it. `--gold` measures 2.4:1 on cream; `--gold-deep` measures 5.78:1. Same
       house token family, same look, a boundary a low-contrast reader can actually find.
     · an explicit colour, because a bare <button> otherwise inherits the platform's own
       `buttontext`, which is not a colour this palette has measured (1.4.3 Contrast);
       var(--ink) on var(--cream) is 12.66:1.
     · min-height 44px and a matching min-width, because these are the writer's main answer
       controls and 2.5.8 Target Size (Minimum) asks for 24px, while the house's own phone
       standard is 44 (2.5.5 Target Size (Enhanced)). The old padding gave about 35px. */
  border: 2px solid var(--gold-deep);
  background: transparent;
  color: var(--ink);
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
}
.intake-answer-row button[aria-pressed="true"] { background: var(--gold); color: var(--ink-deep); }

.creative-context-offer { color: var(--ink-soft); font-size: var(--step--1); }
textarea.text-field { min-height: 6rem; resize: vertical; }

.upload-drop {
  border: 2px dashed var(--wood);
  border-radius: var(--radius);
  padding: var(--s-6);
  text-align: center;
  color: var(--ink-soft);
}
.upload-drop.is-over { border-color: var(--gold); background: var(--parchment); }
.upload-drop input[type="file"] { max-width: 100%; min-height: 44px; }
/* "choose a file" inside the drop zone's sentence is a REAL button (2026-09-27, build bt — the
   beta reader clicked those words and nothing happened). It reads as a link in the sentence, and
   it keeps a 44px target (2.5.5) and the house's visible focus ring. Nothing overlays the native
   input: .upload-drop has no pseudo-elements and no positioned children, so no z-index is needed. */
.upload-drop .choose-file-link {
  display: inline-block;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  cursor: pointer;
}
.upload-drop .choose-file-link:hover { color: var(--gold-deep); }
.upload-drop .choose-file-link:focus-visible { outline: 3px solid var(--gold-deep); outline-offset: 2px; }
.upload-summary { margin-top: var(--s-4); font-size: var(--step--1); }
.upload-summary table { width: 100%; border-collapse: collapse; }
.upload-summary td, .upload-summary th {
  text-align: left;
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--parchment-deep);
  /* A long file name must wrap, not push the table past a 380px screen (1.4.10 Reflow). */
  overflow-wrap: anywhere;
}

.pdf-note, .parse-note {
  background: var(--parchment);
  border-left: 4px solid var(--wood);
  padding: var(--s-4);
  border-radius: 6px;
  font-size: var(--step--1);
  color: var(--ink-soft);
  margin-top: var(--s-4);
}

/* THE 120,000-WORD REFUSAL (THE UI PASS, item 1). Read as a refusal, not as a note: the brick
   rule and the brick text are the same pair `.form-error` uses (7.74:1 on cream). */
.bound-refusal {
  background: #F3E7DF;
  border-left: 4px solid var(--brick, #8C2F1E);
  padding: var(--s-4);
  border-radius: 6px;
  font-family: var(--sans);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--brick, #8C2F1E);
  margin-top: var(--s-4);
}
.bound-refusal[hidden] { display: none; }

/* "Readable" — the one line that says the count passed, before CONTINUE. */
.readable-line {
  font-family: var(--sans);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--wood);
  border-left: 4px solid var(--gold);
  background: var(--parchment);
  border-radius: 6px;
  padding: var(--s-3) var(--s-4);
  margin: var(--s-4) 0 0;
}
.readable-line[hidden] { display: none; }

.own-key-panel { border-top: 1px dashed var(--parchment-deep); margin-top: var(--s-5); padding-top: var(--s-5); }
.own-key-panel .masked-key { font-family: var(--sans); letter-spacing: 0.1em; }
.own-key-steps {
  margin: var(--s-3) 0 var(--s-4);
  padding-left: 1.4em;
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--ink);
}
.own-key-steps li { margin-bottom: var(--s-2); }
/* The key page's address is long and must wrap rather than widen the page on a phone. */
.own-key-link { overflow-wrap: anywhere; word-break: break-word; }
.remember-row {
  display: flex;
  gap: 0.5em;
  align-items: center;
  margin-top: var(--s-3);
  font-size: var(--step--1);
  /* The label is the checkbox's own touch target; 44px keeps the whole row tappable. */
  min-height: 44px;
}
.remember-row input[type="checkbox"] { width: 22px; height: 22px; flex: 0 0 auto; }

/* ---------- THE QUIET READING PANEL (owner order 2026-09-28) ----------
   One small, calm panel in place of "the entire process". Every colour is a house token; every
   pairing below is one the door already measures: --ink on --cream 12.66:1, --ink-soft on --cream
   7.29:1, --gold-deep fill on --parchment track 5.12:1 (1.4.11), --brick on --cream 7.74:1. */
.read-screen { min-height: 8rem; }
.quiet-panel {
  background: var(--cream);
  border: 1px solid var(--parchment-deep);
  border-radius: var(--radius);
  padding: var(--s-5);
  margin: var(--s-4) 0 0;
  max-width: 34rem;
}
.quiet-indicator { display: flex; gap: 0.45rem; margin: 0 0 var(--s-4); height: 10px; align-items: center; }
.quiet-indicator[hidden] { display: none; }
.quiet-indicator span {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--gold-deep);
  opacity: 0.35;
  animation: quiet-breathe 1.8s ease-in-out infinite;
}
.quiet-indicator span:nth-child(2) { animation-delay: 0.3s; }
.quiet-indicator span:nth-child(3) { animation-delay: 0.6s; }
@keyframes quiet-breathe {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50% { opacity: 1; transform: scale(1); }
}
.quiet-status { margin: 0; }
.quiet-line { font-family: var(--sans); font-size: var(--step-0); font-weight: 600; color: var(--ink); margin: 0 0 var(--s-3); overflow-wrap: anywhere; }
.quiet-line[hidden], .quiet-what[hidden], .quiet-close[hidden], .quiet-bar[hidden] { display: none; }
.quiet-what { font-size: var(--step--1); color: var(--ink); line-height: 1.55; margin: 0 0 var(--s-3); overflow-wrap: anywhere; }
.quiet-panel[data-mode="paused"] .quiet-what,
.quiet-panel[data-mode="stopped"] .quiet-what { font-size: var(--step-0); border-left: 4px solid var(--brick, #8C2F1E); padding-left: var(--s-3); }
.quiet-bar {
  display: block;
  width: 100%;
  height: 6px;
  margin: 0 0 var(--s-4);
  border-radius: 999px;
  overflow: hidden;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  background: var(--parchment);
}
.quiet-bar::-webkit-progress-bar { background: var(--parchment); }
.quiet-bar::-webkit-progress-value { background: var(--gold-deep); transition: width 0.6s ease; }
.quiet-bar::-moz-progress-bar { background: var(--gold-deep); }
.quiet-close { font-size: var(--step--1); color: var(--ink-soft); line-height: 1.55; margin: 0; }
.quiet-controls { align-items: center; }
/* Stop the Read is SECONDARY: a quiet text button, still a real <button>, still a 44px target,
   still behind its confirmation. */
.quiet-stop {
  background: none;
  border: 0;
  padding: 0 var(--s-2);
  min-height: 44px;
  font: inherit;
  font-size: var(--step--1);
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.quiet-stop[hidden] { display: none; }
.quiet-stop:hover { color: var(--brick, #8C2F1E); }
.quiet-stop:focus-visible { outline: 3px solid var(--gold-deep); outline-offset: 2px; }
.stop-confirm {
  margin: var(--s-4) 0 0;
  padding: var(--s-4);
  border-left: 4px solid var(--brick, #8C2F1E);
  background: var(--cream);
  border-radius: 6px;
  max-width: 34rem;
}
.stop-confirm[hidden] { display: none; }
.stop-confirm p { margin: 0 0 var(--s-3); font-size: var(--step--1); color: var(--ink); overflow-wrap: anywhere; }
.stop-confirm .btn { min-height: 44px; }

/* THE HOLD — RETIRED 2026-09-28 (owner ruling "DELIVER, NEVER HOLD"): the documents are never held, so
   the brick hold banner and its heading and body styles are gone with the element that used them. */
.delivery-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-4);
  margin: var(--s-5) 0;
}
@media (min-width: 640px) {
  .delivery-grid--two { grid-template-columns: repeat(2, 1fr); }
}
.deliverable-btn {
  display: block;
  width: 100%;
  font-family: var(--sans);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: var(--s-4);
  border-radius: var(--radius);
  /* Explicit, measured ink rather than the platform's own `buttontext` (1.4.3), a boundary that
     clears 3:1 against the page it sits on (1.4.11 — `--gold-deep`, 5.78:1 on cream, where the
     old `--gold` measured 2.4:1), and a 44px floor on the tap target (2.5.5). */
  border: 2px solid var(--gold-deep);
  background: var(--cream);
  color: var(--ink);
  min-height: 44px;
  cursor: pointer;
  text-align: center;
}
.deliverable-btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* THE WALKTHROUGH IS THE FIRST THING THE WRITER MEETS (owner ruling 2026-09-15). */
.deliverable-btn--lead {
  background: var(--gold);
  color: var(--ink-deep);
  font-size: var(--step-0);
  padding: var(--s-5) var(--s-4);
}
.delivered-first {
  border-left: 4px solid var(--gold);
  background: var(--parchment);
  border-radius: 6px;
  padding: var(--s-4) var(--s-5);
  margin: var(--s-5) 0 var(--s-6);
}
.delivered-first h3 { font-size: var(--step-1); margin-bottom: var(--s-3); }

.readcode-display {
  font-family: var(--sans);
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--gold-deep);
  text-align: center;
  margin: var(--s-5) 0;
  /* A Read Code must wrap rather than widen a phone screen. */
  overflow-wrap: anywhere;
}

/* `.walkthrough-offer` carried the thirty-day window sentence, which came off the screen in S13
   under the owner's 2026-09-15 15:46 ruling. The rule is kept, unused, rather than deleted: this
   sheet is shared with the site's own pages and a rule removed is a rule a later pass has to
   rediscover. Retire, never delete. */
.walkthrough-offer { text-align: center; font-size: var(--step--1); color: var(--ink-soft); }

/* S13 — the delivered screen's lead card carries a two-line heading now ("Start here — your
   Elevation Brief: the full walkthrough of your manuscript, unit by unit"), which must wrap
   cleanly on a phone rather than widening the page. */
.delivered-first h3 { text-wrap: balance; overflow-wrap: anywhere; }

.close-resume-row { display: flex; gap: var(--s-3); flex-wrap: wrap; margin-top: var(--s-5); }
.resume-banner {
  background: var(--ink);
  color: var(--navy-band-soft);
  border-radius: var(--radius);
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-5);
}

/* THE RESUME BUTTON (2026-09-20): the standing note that replaces the two buttons once Resume
   is pressed. It stays on the screen while the writer walks the normal path, so it reads as a
   standing instruction rather than a message that has already scrolled away. */
.resume-standing {
  margin: var(--s-3) 0 0;
  padding-top: var(--s-3);
  border-top: 1px solid currentColor;
  opacity: 0.92;
}

/* The ghost button's outline is the only thing that says it is a button, and it stands on both
   door screens (Close for Now · Start Over Instead · Download Your Run Log). Same 1.4.11 fix as
   the controls above, scoped to these two screens so the storefront's own styling is untouched.
   Its hover/pressed fill and its text colour are style.css's and are not changed. */
.door-card .btn--ghost, .app-shell .btn--ghost { border-color: var(--gold-deep); }

/* Visually hidden, still read aloud — used for the upload table's caption. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- THE PHONE (THE UI PASS, item 6) ----------
   Verified by hand at 380px: nothing below assumes a width wider than a phone, and no rule here
   can push the page past the viewport. The two guards that matter are a hard ceiling on anything
   that could be intrinsically wide (a pre, a long code, an input) and a real side gutter. */
.app-shell, .door-card { max-width: 100%; }
.quiet-panel, .stop-confirm { max-width: 100%; overflow-wrap: anywhere; }
.text-field, .upload-drop, .app-panel, .delivery-grid, .upload-summary table { max-width: 100%; }
.seat-reveal .seat-code { overflow-wrap: anywhere; }

/* ---------- THE SIGN-IN COMES FIRST (owner order 2026-09-28: "WHERE DOES PASTE THE CODE?") ----------
   The box a returning writer pastes her code into is the first thing on the door's first page; the
   new writer's seat stands under it, under its own smaller heading. */
.signin-first {
  border-bottom: 1px solid var(--parchment-deep);
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-5);
}
.signin-first h1 { margin-bottom: var(--s-2); }
.signin-first .field-label { margin-top: var(--s-3); }
.signin-first .btn { min-height: 44px; }
.get-seat-h { font-size: var(--step-1); margin-bottom: var(--s-2); }

/* ---------- GET YOUR SEAT (ONE BUTTON, the server decides — 2026-09-27) ----------
   The entry on the door's first page, above Sign In, and the two-field free-seat form. Every
   control keeps the house's 44px target and the same 1.4.11 edges the rest of the door uses. */
.get-seat {
  border-bottom: 1px solid var(--parchment-deep);
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-5);
}
.get-seat .seat-rung { font-family: var(--sans); font-weight: 600; color: var(--ink); margin: var(--s-2) 0; overflow-wrap: anywhere; }
.get-seat .btn, .claim-form .btn, .seat-reveal-actions .btn { min-height: 44px; }
.claim-form { margin-top: var(--s-3); }
/* THE REVEAL'S TWO BUTTONS stand on the reveal's dark ground: the ghost button takes the navy
   band's own light pair (the storefront's `.band--navy .btn--ghost`), and the notes take the
   reveal's own soft ink, so neither reads dark-on-dark. */
.seat-reveal-actions { justify-content: center; }
/* the two words never break mid-word on a narrow phone: tighter sides, and a row each below 480px */
.seat-reveal-actions .btn, .get-seat .btn { white-space: nowrap; padding-left: var(--s-4); padding-right: var(--s-4); }
@media (max-width: 480px) {
  .seat-reveal { padding: var(--s-5) var(--s-4); }
  .seat-reveal-actions .btn, .get-seat .btn, .signin-first .btn { flex: 1 1 100%; }
}
.seat-reveal .btn--ghost { color: var(--navy-band-text); border-color: var(--gold-bright); }
/* THE RESUME BANNER stands on the same dark ground (found 2026-09-28 in the quiet-panel preview: its
   "Start Over Instead" printed navy on navy — an outline with no words). Same light pair as above. */
.resume-banner .btn--ghost { color: var(--navy-band-text); border-color: var(--gold-bright); }
.resume-banner .btn--ghost:hover { background: var(--gold-bright); color: var(--ink-deep); }
.seat-reveal .form-note { color: var(--navy-band-soft); }
/* THE SAVE-YOUR-CODE GATE (owner order 2026-09-29). The tick box and its label on the reveal's dark
   ground: a 24px box inside a 44px row (the house's target), the label in the band's light text, and a
   disabled state that reads as waiting (dimmed, not-allowed) until Copy or Save my code was pressed. */
.seat-saved-gate {
  display: flex; align-items: center; justify-content: center; gap: var(--s-3);
  min-height: 44px; margin: var(--s-4) 0 var(--s-1);
}
.seat-saved-gate input[type="checkbox"] { width: 24px; height: 24px; margin: 0; accent-color: var(--gold-bright); cursor: pointer; flex: none; }
.seat-saved-gate label { color: var(--navy-band-text); font-family: var(--sans); font-weight: 700; cursor: pointer; }
.seat-saved-gate input[type="checkbox"]:disabled,
.seat-saved-gate input[type="checkbox"]:disabled + label { opacity: 0.55; cursor: not-allowed; }
.seat-saved-gate input[type="checkbox"]:focus-visible { outline: 3px solid var(--gold-bright); outline-offset: 3px; }
.seat-reveal .seat-continue-error { color: var(--gold-bright); }

@media (max-width: 480px) {
  .door-card { padding: var(--s-6) var(--s-4); }
  .app-shell { padding: var(--s-5) var(--s-4) var(--s-7); } /* the 16px phone gutter (2026-09-28) */
  .step-rail { font-size: 0.72rem; }
  .delivered-first { padding: var(--s-4); }
  /* A full-width answer button reads better than three cramped ones at a phone width, and keeps
     every target well over 44px. */
  .intake-answer-row { flex-direction: column; align-items: stretch; }
  .intake-answer-row button { width: 100%; }
}

/* ---------- REDUCED MOTION ----------
   style.css already turns every transition and animation off house-wide under this query; this
   block is the door's own belt-and-braces for the two surfaces this pass touched, so a later
   edit to either file cannot quietly reintroduce movement on a screen a writer asked to be
   still. Nothing in this pass animates in the first place. */
@media (prefers-reduced-motion: reduce) {
  .upload-drop, .deliverable-btn, .intake-answer-row button, .quiet-bar,
  .quiet-bar::-webkit-progress-value {
    transition: none !important;
    animation: none !important;
  }
  /* THE QUIET PANEL'S INDICATOR STANDS STILL: three steady dots, no breathing. */
  .quiet-indicator span { animation: none !important; opacity: 0.7; transform: none; }
  .skip-link { transition: none !important; }
}
