/*
webapp/static/brand.css

RevisionIQ's real, branded visual system (Phase 3A) -- an "editor's
desk," not a default-styled form: a single desktop-app-style window
(title bar, traffic-light dots, one accent red) hosting both the
unauthenticated landing page and the authenticated dashboard shell.
Deliberately separate from webapp/static/style.css (the original,
unbranded item-13/14-era engine-testing harness, preserved unchanged at
GET /dev-console per this project's archive-don't-delete convention) --
this file styles only the new templates (landing/dashboard/verify
pages), so neither stylesheet risks the other's page.

Palette and type system are given, not derived here:
  - #800020 accent -- matches report_builder's FLAG_COLOR exactly (one
    red across the whole product now).
  - #1C2B39 ink navy, #F2EEE4 paper, #5B6570 slate, #3F6B52 ink green,
    #DBD3C1 hairline.
  - Newsreader (serif, headings), IBM Plex Sans (UI/body), IBM Plex Mono
    (numbers/timers -- used sparingly in this phase; Phases C/D will use
    it more, for word counts and elapsed-time displays).
*/

:root {
  --accent: #800020;
  --accent-hover: #6b001a;
  --ink-navy: #1C2B39;
  --paper: #F2EEE4;
  --slate: #5B6570;
  --ink-green: #3F6B52;
  --hairline: #DBD3C1;

  --font-serif: "Newsreader", Georgia, "Times New Roman", serif;
  --font-sans: "IBM Plex Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

  --shadow-window: 0 24px 60px rgba(28, 43, 57, 0.20), 0 2px 10px rgba(28, 43, 57, 0.10);
  --shadow-modal: 0 20px 50px rgba(28, 43, 57, 0.30);
  --radius: 10px;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
}

body.rq-body {
  margin: 0;
  color: var(--ink-navy);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  min-height: 100vh;
}

/* ---------- the desktop-app window shell ----------
   Item 24: the shell (title bar + canvas) is now the full-width,
   full-height CONSTANT across every page -- landing, verify-result,
   and dashboard all render inside this exact same structure. What
   used to distinguish a page was a differently-sized centered card;
   now it's only what sits INSIDE the canvas (a floating overlay card
   for logged-out states, real content directly for the dashboard).
   The paper background + its radial-gradient tint (previously on
   <body>, behind a narrower centered window) moved here, since this
   element is now the thing that actually fills the viewport. */
.rq-window {
  width: 100%;
  min-height: 100vh;
  background: var(--paper);
  background-image:
    radial-gradient(ellipse 80% 60% at 15% -10%, rgba(128, 0, 32, 0.05), transparent),
    radial-gradient(ellipse 70% 50% at 100% 0%, rgba(28, 43, 57, 0.05), transparent);
  display: flex;
  flex-direction: column;
}

/* Phase 3A Fix: the dark navy banner and its three decorative
   traffic-light dots are gone entirely, per direct visual feedback --
   not recolored, not restyled. The header row is now the same paper
   background as the rest of the page, separated from the canvas below
   by a thin accent hairline and a soft lift-shadow instead of a solid
   color block (see below). */
.rq-titlebar {
  background: transparent;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.25rem;
  border-bottom: 2.5px solid var(--accent);
  box-shadow: 0 6px 12px -6px rgba(28, 43, 57, 0.18);
  position: relative;
  z-index: 1;
}

.rq-titlebar .rq-logo {
  height: 26px;
  width: auto;
  display: block;
}

.rq-titlebar-spacer { flex: 1; }

.rq-account {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.rq-account-email {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--slate);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 240px;
}

.rq-titlebar button.rq-btn-logout {
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--ink-navy);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.rq-titlebar button.rq-btn-logout:hover {
  background: rgba(28, 43, 57, 0.05);
  border-color: var(--ink-navy);
}

.rq-canvas {
  flex: 1;
  padding: clamp(2rem, 5vw, 3.5rem) clamp(1.5rem, 6vw, 4rem);
}

/* Item 24: opt-in modifier for the two logged-out page types (landing,
   verify-result) whose content is a single floating card rather than
   real full-width dashboard content -- centers that card within
   whatever vertical space the canvas has (flex: 1 on .rq-canvas above
   means that's the full remaining viewport height, not just the
   content's own height, so the card centers on the actual screen, not
   just within a content-sized box). The dashboard does NOT get this
   modifier -- its content flows normally, full width, from the top. */
.rq-canvas-centered {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The floating card itself -- same visual language as .rq-modal (off-
   white surface, hairline border, radius) reusing --shadow-window
   (formerly the whole page-level window's own shadow, now this card's,
   since the card is the thing floating above a surface now) rather
   than --shadow-modal, which stays reserved for actual click-triggered
   popups so the two remain visually distinguishable in weight if ever
   compared side by side. */
.rq-overlay-card {
  width: 100%;
  max-width: 460px;
  background: #FBF9F4;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--shadow-window);
  padding: clamp(2rem, 5vw, 3rem) clamp(1.75rem, 5vw, 2.75rem);
}

/* ---------- typography ---------- */

.rq-canvas h1, .rq-canvas h2, .rq-canvas h3 {
  font-family: var(--font-serif);
  color: var(--ink-navy);
  margin: 0 0 0.5rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.rq-canvas h1 { font-size: 2rem; font-weight: 600; }
.rq-canvas h2 { font-size: 1.4rem; }

.rq-lede {
  color: var(--slate);
  font-size: 1.02rem;
  max-width: 46ch;
  margin: 0 0 2rem;
}

.rq-eyebrow {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.72rem;
  color: var(--accent);
  margin: 0 0 0.6rem;
}

/* ---------- buttons ---------- */

.rq-btn {
  /* Item 58, Part C: made explicit -- previously relied on each
     element's own browser-default display (a real, measured
     ~2.8px height difference surfaced this: #submit-download-link
     is this codebase's only <a class="rq-btn">, defaulting to
     `display: inline` unlike every <button class="rq-btn"> elsewhere,
     which changes how padding participates in the line box). Explicit
     inline-flex centering makes every .rq-btn element -- <button> or
     <a> alike -- render with identical box behavior regardless of tag,
     not just a fix for this one pairing. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 500;
  /* Item 58, Part C: the REAL remaining cause of the ~2.8px height
     mismatch, found by comparing real computed styles after the
     display fix above didn't close it -- <button> elements don't
     inherit body.rq-body's own `line-height: 1.5` (a browser form-
     control default), landing on the UA's own `line-height: normal`
     instead, while #submit-download-link (this codebase's only <a
     class="rq-btn">) DOES inherit the 1.5 value, computing to a real,
     measured 22.8px versus the button's ~20px. Set explicitly so every
     .rq-btn element resolves to the identical value regardless of
     which inheritance rules its own tag type happens to follow. */
  line-height: normal;
  border-radius: 7px;
  padding: 0.65rem 1.4rem;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.05s ease, opacity 0.15s ease;
}

.rq-btn:active { transform: translateY(1px); }

.rq-btn-primary {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 1px 2px rgba(128, 0, 32, 0.25);
}
.rq-btn-primary:hover { background: var(--accent-hover); }
.rq-btn-primary:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }

.rq-btn-secondary {
  background: transparent;
  color: var(--ink-navy);
  border-color: var(--hairline);
}
.rq-btn-secondary:hover { border-color: var(--ink-navy); background: rgba(28, 43, 57, 0.04); }

/* Item 58, Part B: the repurposed Submit button's "Start a new
   submission" state -- a real, distinct modifier from .rq-btn-secondary
   above (which is neutral/--ink-navy, used for Cancel), not a reuse of
   it: this task's own explicit instruction is burgundy border/text on a
   transparent/paper background, reusing --accent (the same token
   .rq-btn-primary's solid fill already uses), not --ink-navy/--hairline.
   No new color introduced -- --accent is this file's own existing
   token. Applied by toggling this class in place of .rq-btn-primary on
   the SAME #submit-btn element (webapp/static/brand.js's
   setSubmitBtnRepurposed()), never a second button. */
.rq-btn-outline-accent {
  background: transparent;
  color: var(--accent);
  border-color: var(--accent);
}
.rq-btn-outline-accent:hover { background: rgba(128, 0, 32, 0.06); }

.rq-entry-actions {
  display: flex;
  gap: 0.8rem;
  flex-wrap: wrap;
}

/* ---------- form fields (shared by modals) ---------- */

.rq-field { margin-bottom: 1.1rem; }

.rq-field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink-navy);
  margin-bottom: 0.35rem;
}

/* Item 26 (Phase C) broadened this selector from just input[type="email"]
   to every field type the submission form actually uses (text areas,
   selects, file inputs) -- same visual treatment throughout rather than
   a second, duplicated rule set for the new modal's fields. */
.rq-field input[type="email"],
.rq-field input[type="text"],
.rq-field input[type="file"],
.rq-field select,
.rq-field textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 1rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 7px;
  background: #fff;
  color: var(--ink-navy);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.rq-field textarea {
  resize: vertical;
  min-height: 5.5rem;
  font-family: var(--font-sans);
}

.rq-field input[type="email"]:focus,
.rq-field input[type="text"]:focus,
.rq-field select:focus,
.rq-field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(128, 0, 32, 0.12);
}

/* Item 42: the waiver scroll-and-accept box -- a fixed, real height
   (not vh-relative) so a normal viewport genuinely requires scrolling
   to reach the bottom, per this task's own explicit "scroll-detection
   logic gets genuinely exercised" instruction. Same field-level visual
   language as the text inputs above (border/radius/focus ring) rather
   than a bespoke look. */
.rq-waiver-scroll-box {
  width: 100%;
  max-height: 180px;
  overflow-y: auto;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 7px;
  background: #fff;
  font-size: 0.85rem;
  color: var(--slate);
  line-height: 1.5;
}

.rq-waiver-scroll-box:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(128, 0, 32, 0.12);
}

.rq-waiver-scroll-box p {
  margin: 0 0 0.85rem;
}

.rq-waiver-scroll-box p:last-child {
  margin-bottom: 0;
}

.rq-hint {
  font-size: 0.82rem;
  color: var(--slate);
  margin: 0.4rem 0 0;
}

.rq-hint.over-limit { color: var(--accent); font-weight: 500; }

/* Item 35: the Thesis Checker's word count + Clear button, sharing one
   row below the textarea. */
.rq-thesis-field-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.4rem;
}
.rq-thesis-field-footer .rq-hint { margin-top: 0; }

/* Same plain-text-button formula as .rq-nav-secondary-btn -- no
   background/border, --slate, underlined, small -- reused rather than
   inventing a new small-button style for this one control. */
.rq-clear-btn {
  background: none;
  border: none;
  color: var(--slate);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  flex-shrink: 0;
}
.rq-clear-btn:hover { color: var(--ink-navy); }

.rq-notice {
  font-size: 0.78rem;
  color: var(--slate);
  background: rgba(128, 0, 32, 0.06);
  border-radius: 6px;
  padding: 0.5rem 0.65rem;
  margin: 0.6rem 0 0;
}

/* Item 41, Part D: the same .rq-notice look, but standing alone above
   the whole form (not nested under one field) needs its own bottom
   margin instead of .rq-notice's default top-only spacing. SUPERSEDED
   by item 51, Part 2 below (dashboard.html no longer references this
   class) -- kept, not deleted, per this project's archive-don't-delete
   convention; harmless as dead CSS. */
.rq-sensitive-info-notice {
  margin: 0 0 1.1rem;
}

/* Item 51, Part 2: replaces the old .rq-notice/.rq-sensitive-info-notice
   tinted-pink alert-style box entirely, per this task's own explicit
   instruction to move away from a warning/error read. Judgment call on
   exact visual treatment (documented in webapp/BUILD_LOG.md item 51):
   a plain hairline-bordered card, --paper background, NO accent/burgundy
   tint anywhere in the box itself -- deliberately calmer than even a
   muted accent tint would read, matching this task's own "an
   intentional, calm piece of guidance, not an alert" instruction as
   literally as possible. A short --accent left-edge stripe (3px) is the
   ONE place the brand accent appears, functioning as a quiet marker
   (this belongs to RevisionIQ's own voice) rather than an alert color.
   All three tokens (--hairline, --paper, --accent) are this file's own
   already-existing custom properties (line 24-31 above) -- nothing new
   defined. */
.rq-privacy-notice {
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  background: var(--paper);
  border-radius: 6px;
  padding: 0.75rem 0.9rem;
  margin: 0 0 1.1rem;
}

.rq-privacy-notice-heading {
  font-weight: 600;
  color: var(--ink-navy);
  font-size: 0.88rem;
  margin: 0 0 0.3rem;
}

.rq-privacy-notice-body {
  color: var(--slate);
  font-size: 0.82rem;
  margin: 0;
}

.rq-checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 1.1rem 0 0;
}

.rq-checkbox-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

.rq-checkbox-row label {
  font-size: 0.9rem;
  color: var(--ink-navy);
  cursor: pointer;
}

.rq-field-error {
  color: var(--accent);
  font-size: 0.82rem;
  margin-top: 0.4rem;
  display: none;
}
.rq-field-error.active { display: block; }

/* Item 33, Part 2.6: a cancelled submission's note -- deliberately
   --slate, this project's existing neutral token, not --accent (the
   error color .rq-field-error above uses). Cancellation is a user
   action, not a failure. */
.rq-status-cancelled-note {
  color: var(--slate);
  font-size: 0.82rem;
  margin-top: 0.4rem;
}

/* Item 33, Part 2.6: the Cancel button's "armed" (awaiting confirmation)
   state -- a plain two-step inline confirm, no separate modal. Still
   --slate, not --accent: confirming a cancellation is not itself an
   error state. */
#submit-cancel-btn.rq-cancel-armed {
  border-color: var(--slate);
  color: var(--slate);
  font-weight: 500;
}

/* ---------- modal overlay ---------- */

.rq-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 22, 29, 0.55);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

.rq-modal-overlay.active {
  opacity: 1;
  pointer-events: auto;
}

.rq-modal {
  background: #FBF9F4;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--shadow-modal);
  width: 100%;
  max-width: 400px;
  padding: 1.75rem 1.75rem 1.5rem;
  transform: translateY(8px) scale(0.98);
  transition: transform 0.18s ease;
  /* Item 28: fixes the first of two known layout bugs this task named
     explicitly -- the download button clipping off the bottom of the
     modal. .rq-modal-overlay centers this element with no height cap
     of its own, so once the gauge (item 27) plus gears plus a rotating
     message plus the download/countdown cluster all stack up, total
     content height can exceed a short viewport with no way to reach
     what overflows -- a fixed-position flex child that's taller than
     its container just overflows invisibly, it does not scroll on its
     own. max-height + overflow-y:auto guarantees every reasonable
     viewport gets a scrollbar INSIDE the modal instead, so the
     download button is always reachable, never permanently clipped. */
  max-height: calc(100vh - 3rem);
  overflow-y: auto;
}

.rq-modal-overlay.active .rq-modal {
  transform: translateY(0) scale(1);
}

/* Item 26 (Phase C): the submission modal needs more room than the
   400px signup/login modals (a file input, a citation-style select, a
   conditional second upload) -- a modifier on THIS modal only, rather
   than widening .rq-modal itself, so the existing auth modals are
   untouched. */
.rq-modal-wide { max-width: 480px; }

.rq-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.35rem;
}

.rq-modal-header h2 { margin: 0; }

.rq-modal-close {
  background: transparent;
  border: none;
  color: var(--slate);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.1rem 0.3rem;
  border-radius: 5px;
  margin-top: -0.2rem;
}
.rq-modal-close:hover { background: rgba(28, 43, 57, 0.06); color: var(--ink-navy); }

.rq-modal-sub {
  color: var(--slate);
  font-size: 0.9rem;
  margin: 0 0 1.25rem;
}

.rq-modal-state { display: none; }
.rq-modal-state.active { display: block; }

.rq-confirm-icon {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(63, 107, 82, 0.12);
  color: var(--ink-green);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  margin-bottom: 1rem;
}

.rq-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 1.4rem;
}

.rq-switch-mode {
  margin-top: 1.1rem;
  font-size: 0.85rem;
  color: var(--slate);
  text-align: center;
}

.rq-switch-mode button {
  background: none;
  border: none;
  color: var(--accent);
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---------- dashboard engine-access panel (item 25, Phase B) ----------
   Replaces the item 19 placeholder card entirely -- this is now the
   dashboard's first real content. Styled as a solid (not dashed) card:
   dashed border was this project's own established "not real yet"
   signal (see .rq-verify-icon/.rq-overlay-card elsewhere in this file
   for the "real content" treatment this reuses), so keeping it here
   would visually contradict this being live data. */

.rq-panel {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: #FBF9F4;
  padding: clamp(1.5rem, 4vw, 2.25rem);
  max-width: 640px;
}

.rq-panel h2 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--slate);
  margin: 0 0 1.1rem;
}

.rq-engine-list {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.rq-engine-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--hairline);
}

.rq-engine-list .rq-engine-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.rq-engine-name {
  font-weight: 500;
  color: var(--ink-navy);
}

.rq-engine-detail {
  display: block;
  font-size: 0.82rem;
  color: var(--slate);
  margin-top: 0.15rem;
}

.rq-badge {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
}

.rq-badge-unlocked {
  background: rgba(63, 107, 82, 0.12);
  color: var(--ink-green);
}

.rq-badge-locked {
  background: rgba(91, 101, 112, 0.12);
  color: var(--slate);
}

.rq-paid-usage {
  margin: 1.1rem 0 0;
  font-size: 0.85rem;
  color: var(--slate);
}

/* Item 26 (Phase C): each engine row's badge is now paired with an
   optional submission action -- grouped together so the row's right
   edge reads as one unit rather than two unrelated things fighting for
   the same alignment. */
.rq-engine-actions {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.rq-btn-engine-submit {
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 500;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease;
}

.rq-btn-engine-submit:hover {
  background: var(--accent);
  color: #fff;
}

/* ---------- submission modal (item 26, Phase C) ---------- */

.rq-field-group { display: none; }
.rq-field-group.active { display: block; }

.rq-conditional { display: none; margin-top: 0.9rem; }
.rq-conditional.active { display: block; }

/* ---------- progress gauge (item 27, Phase D) ----------
   Replaces item 26's phase chips entirely, per that item's own
   explicit "simplest CORRECT version, not a placeholder" framing --
   this is what it was standing in for. Every color used below is one
   of this file's own existing custom properties (--accent, --ink-
   green, --ink-navy, --hairline) -- confirmed by reading this file
   before writing a single rule here, per this task's explicit
   instruction not to introduce new colors. No percentage, no
   interpolated needle motion, no fake sub-progress -- the needle only
   ever rests at one of six fixed positions, this project's "no false
   precision" principle applied to a gauge instead of a chip row. */

.rq-gauge-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Item 59, Part D: margin-bottom trimmed from 0.75rem -- same real,
     measured space-recovery pass as .rq-gauge-message's own trim
     directly below; see that rule's own comment. */
  margin: 0.25rem 0 0.4rem;
}

.rq-gauge {
  width: 100%;
  max-width: 260px;
  display: block;
}

/* The needle's rotation is set via the CSS `transform` property (not
   the SVG `transform` presentation attribute, which a CSS transition
   cannot animate) specifically so this transition applies -- a smooth
   sweep BETWEEN two of the six fixed positions, not progress WITHIN
   one. The needle only ever rests at a phase's exact angle; nothing
   here interpolates based on elapsed time or any other proxy for
   within-phase completion. */
#submit-gauge-needle {
  transform-box: view-box;
  transform-origin: 120px 120px;
  transition: transform 0.6s ease;
}

/* Milestone dots: hollow until reached, filled the instant the needle
   reaches or passes them -- fill color matches whichever band
   (--accent for the two "setup" phases, --ink-green for the four
   "editorial" phases including the terminal "ready") the dot belongs
   to, set per-dot via JS, not here. */
.rq-gauge-dot {
  stroke-width: 2.5;
  transition: fill 0.3s ease;
}

.rq-gauge-gears {
  display: flex;
  align-items: center;
  margin-top: -0.5rem;
  height: 34px;
}

.rq-gauge-gears.rq-hidden { display: none; }

.rq-gear {
  width: 26px;
  height: 26px;
  fill: var(--hairline);
  stroke: var(--slate);
  stroke-width: 1.5;
}

.rq-gear-small {
  width: 18px;
  height: 18px;
  margin-left: -6px;
  margin-top: 6px;
}

/* Subtle, continuous, opposite-direction rotation -- a supporting
   "still working" cue, deliberately not attention-grabbing (slow,
   low-contrast fill/stroke, small size), per this task's explicit
   instruction. */
@keyframes rq-gear-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes rq-gear-spin-reverse { from { transform: rotate(360deg); } to { transform: rotate(0deg); } }

.rq-gear-large { animation: rq-gear-spin 6s linear infinite; }
.rq-gear-small { animation: rq-gear-spin-reverse 4s linear infinite; }

.rq-gauge-message {
  color: var(--slate);
  /* Item 59, Part D: trimmed from 0.9rem -- a real, measured fix, not a
     stylistic choice: the new, longer idle-state copy (three sentences
     instead of two) added a real, measured ~43px to this element's own
     height in the idle state at a 700px viewport, pushing the idle
     state's needed content past .rq-dashboard-main's real, physically-
     fixed budget for ALL FOUR engines (previously only Humanities' own
     longer form ever reached that cap in the idle state). Margin trims
     alone (below, and .rq-gauge-wrap's own margin-bottom) recovered
     part of this but left a real ~11px still over the cap; this
     specific step is what actually closes it -- 0.85rem drops the
     paragraph's own real line-wrap count by one full line (a discrete
     jump, not gradual scaling, confirmed by live-testing several
     values before picking this one), landing the idle state's needed
     content at ~466px, safely under the ~481px cap. A modest, barely-
     perceptible reduction for a secondary/informational message, not a
     primary UI element -- see BUILD_LOG item 59 for the full real-
     measured before/after across all three trims together. */
  font-size: 0.85rem;
  text-align: center;
  min-height: 1.3em;
  /* Margin-bottom trimmed from 1rem, margin-top from 0.4rem -- same
     real, measured space-recovery pass as the font-size trim above.
     Confirmed single-use (only #submit-gauge-message) before editing
     this class directly. */
  margin: 0.2rem 0 0.5rem;
}

.rq-gauge-message.rq-hidden { display: none; }

/* Item 26's known, explicitly-flagged bug: the terminal "ready" state
   used to get the exact same --accent "current" treatment as any
   in-progress phase, with nothing else distinguishing them. Fixed
   here two ways at once, not just a color swap: (1) "ready" sits in
   the --ink-green editorial band already, same as verifying/analyzing/
   assembling, so the needle/dot fill alone no longer singles it out
   the way solid --accent used to; (2) this glow, applied ONLY on
   "ready" and to nothing in-progress, plus the gears stopping and the
   rotating message going silent (real behavioral differences, not
   just a palette change) make the terminal state unambiguous. */
.rq-modal.rq-status-ready {
  box-shadow: var(--shadow-modal), 0 0 0 3px rgba(128, 0, 32, 0.15), 0 0 46px rgba(128, 0, 32, 0.28);
}

/* Item 29: the gauge (and its glow) now live permanently on the
   dashboard, not inside a modal -- same glow declaration, applied to
   the dashboard's own main panel instead of .rq-modal. */
.rq-dashboard-main.rq-status-ready {
  box-shadow: 0 0 0 3px rgba(128, 0, 32, 0.15), 0 0 46px rgba(128, 0, 32, 0.28);
}

/* ---------- download/deletion cluster (item 28, Phase 3E) ----------
   Fixes the second of two known layout bugs this task named
   explicitly: the deletion notice must visually travel WITH the
   download button, never drift away from it. Both live inside ONE
   wrapper (.rq-download-cluster) rather than as two independent
   children of .rq-modal-actions -- there is no viewport width or
   reflow at which they can end up visually separated, because there
   is only ever one box for both of them to move together. */
.rq-download-cluster {
  display: flex;
  flex-direction: column;
  /* Item 58, Part C: changed from flex-end to center -- this cluster's
     own previous right-alignment was the real, separate cause (on top
     of the two buttons' own mismatched auto-widths, fixed below via a
     shared min-width) of the misalignment the reported screenshot
     showed: #submit-btn-row (this cluster's sibling, holding the
     repurposed Submit/"Start a new submission" button) was never
     right-aligned at all -- it only ever LOOKED centered, because
     .rq-submit-gauge-col's own `align-items: center` centers each
     content-sized row as a block. Matching that same, already-dominant
     column-wide convention here (rather than picking flex-end for this
     one row specifically) is what this task's own "match whatever
     alignment convention the gauge column already uses elsewhere"
     instruction asks for. Confirmed single-use before changing this
     class directly (no other surface shares it). */
  align-items: center;
  /* Item 57: trimmed from 0.6rem -- part of the same real, measured
     space-recovery pass as #submit-download-area's own margin-top
     above, needed once this cluster grew a third real item (the Part C
     "Email me a copy" text-link). Confirmed single-use (only this one
     element in the whole codebase), so trimming it directly rather than
     scoping a narrower override is safe -- no other surface shares this
     class. */
  gap: 0.4rem;
  width: 100%;
}

.rq-download-note {
  color: var(--slate);
  font-size: 0.8rem;
  /* Item 58, Part C: right -> center, matching .rq-download-cluster's
     own alignment change directly above (both usages of this class sit
     inside that one cluster -- confirmed before editing). Right-aligned
     text read correctly when the cluster itself was right-aligned; it
     would look lopsided against centered buttons otherwise. */
  text-align: center;
  max-width: 320px;
  margin: 0;
}

.rq-download-note #submit-countdown {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--ink-navy);
}

/* The expired ("Report deleted") state: pointer-events:none is the
   actual functional disable when this class was first written for a
   plain <a> (no native `disabled` attribute the way a <button> does)
   -- per that task's explicit "disable the download link... rather
   than leaving a dead link that 404s silently" instruction. No new
   color: --slate, already this system's established "inactive/
   neutral" tone (see .rq-badge-locked elsewhere in this file).

   Item 61, Part C: this SAME class is now ALSO applied to
   #submit-download-link's own "Download complete" state, per this
   task's own explicit "reuse the existing gray/disabled visual
   treatment... do not create a new visual variant" instruction --
   #submit-download-link is a real <button> now (item 61, Part A), so
   its own native `disabled` attribute does the REAL functional
   disable there; pointer-events:none/cursor:not-allowed below are
   redundant-but-harmless reinforcement in that usage, not load-
   bearing the way they still are for the plain-<a> "Report deleted"
   case this class was originally written for. */
.rq-btn.rq-btn-disabled {
  background: var(--slate);
  color: #fff;
  opacity: 0.6;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
}
.rq-btn.rq-btn-disabled:hover { background: var(--slate); }

.rq-coupon-form {
  margin-top: 1.5rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--hairline);
}

.rq-coupon-form label {
  display: block;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink-navy);
  margin-bottom: 0.5rem;
}

.rq-coupon-row {
  display: flex;
  gap: 0.6rem;
}

.rq-coupon-row input[type="text"] {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 7px;
  background: #fff;
  color: var(--ink-navy);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.rq-coupon-row input[type="text"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(128, 0, 32, 0.12);
}

.rq-coupon-message {
  font-size: 0.85rem;
  margin: 0.6rem 0 0;
  display: none;
}

.rq-coupon-message.active { display: block; }
.rq-coupon-message.rq-message-error { color: var(--accent); }
.rq-coupon-message.rq-message-success { color: var(--ink-green); }

/* ---------- verify-email landing page ---------- */

.rq-verify-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.7rem;
  margin-bottom: 1.25rem;
}

.rq-verify-icon.ok { background: rgba(63, 107, 82, 0.12); color: var(--ink-green); }
.rq-verify-icon.err { background: rgba(128, 0, 32, 0.10); color: var(--accent); }

.rq-verify-note {
  margin-top: 1.75rem;
  padding: 1rem 1.15rem;
  background: rgba(28, 43, 57, 0.05);
  border-radius: 8px;
  font-size: 0.9rem;
  color: var(--slate);
}

.rq-verify-note strong { color: var(--ink-navy); }

/* ---------- dashboard redesign (item 29, Phase 4) ----------
   Replaces the item 25/26 engine-access panel + submission-modal
   pattern entirely: engine selection moves to a left-hand nav, the
   submission form and the progress gauge both become permanent,
   always-visible fixtures of the main dashboard area, not modal
   content. No new colors anywhere below -- every color here is one of
   this file's own existing custom properties, confirmed by reading
   this file first, per this task's explicit instruction. */

.rq-dashboard-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

@media (max-width: 720px) {
  .rq-dashboard-layout { grid-template-columns: 1fr; }
}

/* Item 51, Part 5: wraps the new "Choose an Editor" heading + the
   existing <nav> together as ONE grid child, so .rq-dashboard-layout's
   own `grid-template-columns: 220px 1fr` (unchanged) still applies
   correctly to exactly two direct children -- this column, then
   .rq-dashboard-main. No layout/structure change beyond that wrapper. */
.rq-engine-nav-col {
  display: flex;
  flex-direction: column;
  /* Item 56: a static, engine-independent offset that visually centers
     this whole block (heading + buttons + the "X of 5 beta submissions
     used" counter text, when shown) against the Thesis-Statement
     Checker's own submission panel specifically -- the shortest of the
     four (novel_fiction/short_story land on the exact same panel
     height too, since all three are governed by the shared gauge
     column's height, not their own shorter form fields; only
     Humanities' own taller form makes its panel taller). Real-measured
     (not estimated): this column's own real content height with the
     counter text visible is ~358px, the reference panel's real height
     is ~468px -- `(468 - 358) / 2 ≈ 55px`, the value used below.
     Deliberately STATIC, not a per-engine recalculation -- `.rq-
     dashboard-layout`'s own `align-items: start` means this column's
     position is otherwise independent of `.rq-dashboard-main`'s height
     regardless, so a fixed value here never moves when a taller
     engine (Humanities) is selected; it only ever centers exactly
     against the reference panel, landing visibly higher than center
     against a taller one -- the deliberate, accepted trade-off over
     reintroducing per-engine layout jumping. See BUILD_LOG item 56 for
     the full real-measured derivation and the no-scroll re-
     verification this required. */
  margin-top: 55px;
}

.rq-engine-nav-heading {
  /* .rq-eyebrow already supplies the small-caps mono look; only this
     column's own bottom spacing needs a small adjustment, tighter than
     .rq-eyebrow's page-level default since it sits directly above a
     list of buttons, not a page title. Item 54, Part 2: bumped from
     0.5rem to 0.75rem alongside the button-gap increase below, so the
     heading-to-first-button gap grows in proportion rather than
     staying fixed while the gaps between buttons themselves grow --
     still comfortably less than the between-button gap so the heading
     still reads as belonging to the list beneath it. */
  margin: 0 0 0.75rem;
  /* Item 53: centered over the button column below it (was left-
     aligned, matching .rq-eyebrow's own page-level default, which read
     as an afterthought rather than a real heading for the column).
     Font-size raised from .rq-eyebrow's base 0.72rem to 1.05rem -- an
     ALREADY-DEFINED step in this file's own type scale (reused
     verbatim from .rq-admin-created-banner code's own font-size, not a
     new value invented for this), a clearly visible jump without
     ballooning into actual-heading territory (h1/h2 are 2rem/1.4rem --
     this is a label above a button list, not a competing heading).
     Font-family/text-transform/letter-spacing/color are all untouched,
     still inherited from .rq-eyebrow -- same small-caps mono
     treatment, just bigger and centered, per this task's own explicit
     "size/alignment change, not a full restyle" scope. */
  text-align: center;
  font-size: 1.05rem;
}

.rq-engine-nav {
  display: flex;
  flex-direction: column;
  /* Item 54, Part 2: up from 0.6rem to a clearly-more-breathing-room
     value that still reads as one grouped menu, not four separate
     items. Real-measured against the task's own explicit constraint
     (this column must not become the new overflow source once
     Humanities' own right column grows in Part 3): the nav column's
     real total height (heading + four buttons at this gap) is ~304px
     at a 700px viewport, well under half of Humanities' own right
     (gauge) column height at the same viewport (~423px, itself the
     larger of the two real column heights that governs the dashboard
     card's needed height on that tab) -- so this task's own stated
     fallback ("reduce spacing to whatever fits") was never actually
     triggered; the originally-intended value is the one shipped. See
     BUILD_LOG item 54 for the full real-measured comparison. */
  gap: 1rem;
}

.rq-nav-engine {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
  width: 100%;
  text-align: left;
  background: #FBF9F4;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: border-color 0.15s ease, background 0.15s ease;
}

.rq-nav-engine:hover { border-color: var(--ink-navy); }

.rq-nav-engine.active {
  border-color: var(--accent);
  background: rgba(128, 0, 32, 0.05);
  box-shadow: 0 0 0 1px var(--accent);
}

.rq-nav-engine-name {
  font-weight: 500;
  color: var(--ink-navy);
  font-size: 0.92rem;
}

.rq-nav-engine-status {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--slate);
}

.rq-nav-secondary {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--hairline);
}

.rq-nav-secondary-btn {
  background: transparent;
  border: none;
  color: var(--slate);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  text-align: left;
  padding: 0.3rem 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.rq-nav-secondary-btn:hover { color: var(--ink-navy); }

.rq-dashboard-main {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: #FBF9F4;
  /* Item 52, Part 1: trimmed from clamp(1.25rem, 3vw, 1.75rem) -- this
     class is dashboard-only (confirmed, not assumed -- grepped for
     other templates), so no "-compact" variant needed; the real,
     measured overflow fix required this specific reduction. */
  padding: clamp(1rem, 2vw, 1.35rem);
  /* Item 52, Part 1 established this card's own bounded max-height (a
     fixed viewport-relative subtraction, real-measured against
     "everything else on the page" at a 700px viewport) so a genuinely
     tall field-group (Humanities) scrolls internally instead of
     pushing the whole page into overflow. See that item's own BUILD_LOG
     entry for the original two-miss derivation of that approach.

     Item 54 changed several of the exact things the old 254px constant
     measured: Part 1 removed the "DASHBOARD" eyebrow above the heading
     (shrinks the fixed budget, freeing room), and Part 4 raised
     .rq-page-footer-links' own top padding from 0.6rem to 2rem AND
     removed .rq-canvas-compact's `flex: 1` growth (both change how much
     fixed space sits below this card). Re-measured from scratch rather
     than adjusting the old constant by estimate: real total of
     everything outside this card (titlebar bottom to canvas's own top
     padding, the heading block, .rq-dashboard-layout's own top offset,
     canvas's bottom padding, and the footer row's full real height) is
     ~218.8px at a 700px viewport, confirmed via getBoundingClientRect on
     the real rendered elements, not estimated from the CSS box model
     alone. 219px (the raw measured value, rounded up a fraction of a
     pixel, not padded with extra safety margin -- same "raw measured
     value" precedent item 52 established) is the value used below.

     This also had to correctly re-absorb Part 3's relocation of the
     email-copy checkbox and Submit button into the gauge column: that
     column's own real content height grew by their real, measured
     addition (~24px more than the old form-column-driven need), which
     at the STALE 254px constant (cap 446px at 700px) newly overflowed
     this card's own max-height by ~20px for the three short engines
     (thesis_checker/novel_fiction/short_story) -- a real, measured
     regression caught by re-running the full four-engine/three-height
     matrix this task required, not assumed fixed by inspection. The
     recomputed 219px constant (cap 481px at 700px) closes that gap with
     real margin to spare (short engines' real content, gauge-column-
     driven now, measures ~466px including this card's own padding) while
     Humanities' genuinely taller content (governed by its own form
     column, ~648px including padding) still correctly exceeds the cap
     and scrolls internally, landing the page itself at exactly 0px
     overflow -- confirmed by re-testing all twelve engine/height
     combinations after this change, not by math alone.

     The PAGE itself never scrolls either way -- titlebar, nav, gauge,
     and the footer links stay fully visible at all times; only this
     one card's own content (a natural, expected scroll boundary -- it
     already has its own border/background) scrolls internally, and
     only for a genuinely tall field-group. */
  max-height: calc(100vh - 219px);
  overflow-y: auto;
}

/* Item 31: the email-copy checkbox + its honest-disclosure note sit at
   the bottom of an already-tall form (Humanities, the tallest of the
   three, was already an exact 800/800 fit at 1280x800 before this was
   added -- item 30's own no-scroll constraint). Scoped, tighter spacing
   for just this block rather than shrinking .rq-checkbox-row/.rq-hint's
   own shared defaults, which are also used elsewhere (the academic-
   context toggle) and shouldn't change look for those. */
/* Item 54, Part 3: the checkbox + note now live in the gauge column,
   directly under the retention note and directly above the (also
   relocated) Submit button -- top margin matches the vertical rhythm
   of the other stacked elements already in this column
   (.rq-gauge-message's own margin) rather than the tighter 0.5rem this
   rule used when it sat inside an already-dense form. */
#email-copy-row {
  margin: 0.9rem 0 0;
}

#email-copy-note {
  margin: 0.2rem 0 0;
  font-size: 0.76rem;
  line-height: 1.3;
  text-align: center;
  max-width: 320px;
}

/* Item 54, Part 3: the relocated Submit button sits directly beneath
   the checkbox/note above it -- .rq-modal-actions' own shared
   `margin-top: 1.4rem` (tuned for sitting below a full field list in a
   modal) reads as too detached from the two-line note immediately
   above it here; tightened just for this instance via its own ID
   rather than editing the shared class other modals still use
   unchanged. justify-content stays flex-end from the shared rule, but
   since this row's own width is content-sized (the gauge column
   itself uses align-items:center, not stretch), that has no visible
   effect -- the button ends up centered in the column exactly like
   the checkbox row above it. */
#submit-btn-row {
  margin-top: 0.7rem;
}

/* Item 57: same reasoning as #submit-btn-row directly above -- .rq-modal-
   actions' shared `margin-top: 1.4rem` (tuned for a full modal) reads as
   too detached from whatever's immediately above it in this permanent
   gauge column. Tightened via this specific ID, not the shared class.
   Part of a real, measured trim (see BUILD_LOG item 57): the results
   state's own real content height, now that it includes the Part C
   "Email me a copy" action, pushes close to (and at a 700px viewport,
   past) .rq-dashboard-main's own real, physically-fixed budget -- this
   trim, together with .rq-download-cluster's own tightened gap below,
   claws back real pixels without visibly crushing the layout. */
#submit-download-area {
  margin-top: 0.8rem;
}

/* Item 58, Part C: a shared min-width so "Download report" and the
   repurposed Submit button ("Submit for review" / "Start a new
   submission") render at identical size whenever both are visible
   together (the ready state) -- previously each auto-sized to its own
   label's text width. Real-measured (Chromium, this element's own real
   rendered width with the CSS min-width temporarily stripped, not
   estimated from character count): "Submit for review" 169.7px,
   "Start a new submission" 208.7px (the longest of the three, as
   expected), "Download report" 163.5px. 220px, used below, is ~11px
   over that longest real value -- a small, deliberate margin, not a
   raw/unpadded value: unlike this file's own max-height-ceiling
   precedent elsewhere, under-filling a min-width would make text touch
   the button's edge at the exact longest label, so rounding up is the
   correct direction for this property specifically. Combined with
   .rq-submit-gauge-col's own `align-items: center` and
   .rq-download-cluster's own (this task's own) `align-items: center`,
   equal widths are what make the two buttons' edges actually line up,
   not just each look independently centered. Real-measured width AND
   height now match exactly (confirmed via getBoundingClientRect() on
   both real elements, see BUILD_LOG item 58) -- closing a second, real
   ~2.8px height mismatch found along the way (`<a>` vs `<button>`
   line-height inheritance, fixed above in the shared .rq-btn rule, not
   here). */
#submit-btn,
#submit-download-link {
  min-width: 220px;
  text-align: center;
}

/* Item 54, Part 3: the left form column loses the checkbox+button that
   used to sit at its end -- modest increase to the remaining fields'
   own spacing so what's left doesn't read as cramped at the top of a
   now-shorter column. Scoped to this column specifically, not a change
   to .rq-field/.rq-checkbox-row/.rq-privacy-notice's own shared
   defaults (still used unscoped elsewhere -- the quote/payment
   popups). */
.rq-submit-form-col .rq-field {
  margin-bottom: 1.4rem;
}

.rq-submit-form-col .rq-privacy-notice {
  margin: 0 0 1.4rem;
}

.rq-submit-form-col .rq-checkbox-row {
  margin: 1.4rem 0 0;
}

/* Item 31: the dashboard specifically (not the landing/verify pages,
   which use .rq-canvas/.rq-lede unscoped and stay exactly as they were)
   needed more of its 800px budget back once the email-copy block above
   pushed the tallest form (Humanities) past a no-scroll fit that was
   already an exact 800/800 knife's-edge before this task. Scoped via
   dedicated classes on THIS page's own elements, not a blanket change
   to .rq-canvas/.rq-lede that every other page would also inherit. */
/* Item 52, Part 1: tightened further -- real measurement (this file's
   own BUILD_LOG item 52) found a genuine, confirmed ~45px overflow
   remaining at a 700px-tall viewport even after moving item 51's
   footer row inside .rq-window (a separate, structural fix -- see that
   element's own dashboard.html comment). This and the trims below it
   close that real, measured gap -- not a guess, verified by re-
   measuring after each change. */
/* Item 54, Part 4: cancels the base .rq-canvas rule's `flex: 1` (shorthand
   for grow:1 shrink:1 basis:0%) for the dashboard specifically. With
   flex:1 active, .rq-canvas always grows to consume every pixel of
   .rq-window's leftover height (titlebar and footer being the other two
   fixed-size flex children) -- fine when this canvas's own content is
   tall enough to need that room (Humanities at a short viewport), but
   for shorter engines or taller browser windows, the canvas's own
   top-anchored content (the dashboard-main panel) doesn't grow to match,
   so the flex-grown leftover space visibly landed as a gap ABOVE the
   footer row instead, and that gap grew with viewport height since
   flex:1 always fills exactly up to the 100vh floor. `flex: 0 1 auto`
   (grow:0, same shrink:1, basis:auto -- explicit, not just flex-grow:0
   alone, since leaving basis at the inherited 0% would collapse this
   element to zero height) restores natural content-based sizing: the
   canvas is only ever as tall as .rq-dashboard-layout actually needs,
   so the footer now follows directly after it (a small, fixed,
   viewport-independent gap -- see .rq-page-footer-links' own top
   padding below) rather than being pushed down to wherever 100vh
   happens to land. .rq-window's own `min-height: 100vh` is untouched,
   so any leftover space in a short-content/tall-viewport case still
   ends up below the footer as background, not above it -- the window
   still visually fills the viewport either way, only WHERE the slack
   lands changes. This does not reopen item 52's own overflow fix: in
   the one case that fix was actually protecting (content tall enough
   to hit .rq-dashboard-main's own max-height cap), flex:1 was already
   contributing zero extra space to begin with (no leftover to
   distribute), so total page height is identical with or without this
   change in that case -- confirmed by re-running the full four-engine/
   three-height no-scroll matrix, not assumed from the box model alone
   (BUILD_LOG item 54). */
.rq-canvas-compact {
  padding-top: clamp(0.75rem, 1.5vw, 1rem);
  padding-bottom: clamp(0.75rem, 1.5vw, 1rem);
  flex: 0 1 auto;
}

.rq-lede-compact {
  margin-bottom: 0.4rem;
}

/* ---------- form + gauge, side by side (item 30, Part 2) ----------
   The form used to sit fully above the gauge -- a normal ~1280x800
   browser window needed a scroll to see the gauge at rest. Two columns
   instead of one stack keeps both visible together without scrolling
   on a standard viewport. Collapses back to a single stacked column
   below a real small-device width, where a scroll is unavoidable
   regardless of arrangement. */
.rq-submit-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  align-items: start;
}

@media (max-width: 860px) {
  .rq-submit-layout { grid-template-columns: 1fr; }
}

.rq-submit-gauge-col {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Idle gauge state (Part 1.3): desaturated, muted -- grayscale filter
   is the simplest correct way to mute the SAME burgundy/green-banded
   gauge without maintaining a second, parallel set of "idle" colors
   (which would itself be a new-color risk this task explicitly warns
   against). Real phase colors return the instant a real phase name
   is rendered (rq-gauge-idle is removed by JS the moment a real
   submission is accepted). */
.rq-gauge-wrap.rq-gauge-idle .rq-gauge { filter: grayscale(0.7) opacity(0.55); }

.rq-gauge-message.rq-gauge-message-idle { color: var(--slate); font-style: italic; }

/* ---------- quote popup (item 29, Phase 4, Part 2) ---------- */

.rq-quote-price {
  text-align: center;
  margin: 0.5rem 0 1.25rem;
}

.rq-quote-price-struck {
  display: block;
  font-family: var(--font-mono);
  font-size: 1.3rem;
  color: var(--accent);
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  opacity: 0.75;
}

.rq-quote-price-free {
  display: block;
  font-family: var(--font-mono);
  font-size: 2rem;
  font-weight: 600;
  color: var(--accent);
  margin-top: 0.2rem;
}

/* ---------- quote popup: plain price + inline coupon (item 30, Part 3) ----------
   Shown instead of the struck/$0.00 pair above when the account hasn't
   unlocked this engine yet -- the real, undiscounted price, no strike
   (there's nothing discounted about it yet). */
.rq-quote-price-plain {
  display: block;
  font-family: var(--font-mono);
  font-size: 2rem;
  font-weight: 600;
  color: var(--ink-navy);
}

.rq-quote-coupon-row {
  margin-top: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--hairline);
}

.rq-quote-coupon-row label {
  display: block;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink-navy);
  margin-bottom: 0.5rem;
}

/* ---------- payment-wall popup (item 29, Phase 4, Part 3) ---------- */

.rq-payment-wall h2 {
  margin: 0 0 0.75rem;
}

.rq-payment-wall p {
  color: var(--slate);
  font-size: 0.95rem;
}

.rq-payment-wall-links {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 1.25rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--hairline);
}

.rq-payment-wall-links a {
  color: var(--accent);
  font-size: 0.9rem;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---------- discard-warning popup (item 59, Part B) ---------- */

/* Same formula as .rq-payment-wall's own body-paragraph styling
   directly above -- reused, not reinvented, for a modal that's
   structurally the same shape (plain body text + action row). */
.rq-discard-warning p {
  color: var(--ink-navy);
  font-size: 0.95rem;
  margin: 0 0 0.6rem;
}

.rq-discard-warning p:last-of-type {
  margin-bottom: 0;
}

/* Item 59, Part B: "reuse whatever color/class is already used for the
   Thesis Checker's word-count-exceeded state" -- that state
   (`.rq-hint.over-limit`) is plain `color: var(--accent)`, this file's
   own existing red/burgundy token, no separate "warning red" defined
   anywhere in this file. Reused directly here rather than introducing
   a second red -- only the ONE word "Warning:" gets it, per this
   task's own explicit "this word only" instruction, not the whole
   line. */
.rq-warning-label {
  color: var(--accent);
  font-weight: 600;
}

/* ---------- Q&A popup (item 29, Phase 4, Part 5) ---------- */

.rq-qa-category {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.72rem;
  color: var(--accent);
  margin: 1.25rem 0 0.5rem;
}

.rq-qa-category:first-child { margin-top: 0; }

.rq-qa-question-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--hairline);
  padding: 0.55rem 0.1rem;
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--ink-navy);
  cursor: pointer;
}

.rq-qa-question-btn:hover { color: var(--accent); }

.rq-qa-answer-body {
  color: var(--slate);
  font-size: 0.92rem;
  white-space: pre-line;
}

/* ---------- mute toggle (item 29, Phase 4, Part 4) ---------- */

.rq-mute-toggle {
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--slate);
  font-size: 0.9rem;
  line-height: 1;
}

.rq-mute-toggle:hover { border-color: var(--ink-navy); color: var(--ink-navy); }
.rq-mute-toggle.rq-muted { color: var(--accent); border-color: var(--accent); }

/* ---------- utility ---------- */

.rq-hidden { display: none !important; }

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

@media (max-width: 520px) {
  .rq-titlebar .rq-account-email { display: none; }
}

/* ---------- admin: coupon creation (item 39) ----------
   A deliberately minimal, low-priority internal tool -- functional and
   legible over polished, reusing .rq-field/.rq-btn/.rq-checkbox-row/
   .rq-hint above rather than a second design language for one
   admin-only page (webapp/templates/admin_coupons.html). */
.rq-admin-canvas {
  max-width: 760px;
  margin: 0 auto;
  padding: 2.5rem 1.5rem 4rem;
}

.rq-admin-canvas h2 {
  margin-top: 2.5rem;
}

.rq-admin-created-banner {
  background: rgba(63, 107, 82, 0.10);
  border: 1px solid var(--ink-green);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  color: var(--ink-green);
}

.rq-admin-created-banner code {
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-weight: 600;
}

.rq-admin-table-wrap {
  overflow-x: auto;
}

.rq-admin-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
  font-size: 0.9rem;
}

.rq-admin-table th, .rq-admin-table td {
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--hairline);
  white-space: nowrap;
}

.rq-admin-table th {
  color: var(--slate);
  font-weight: 600;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.rq-admin-table code {
  font-family: var(--font-mono);
  font-size: 0.85rem;
}

.rq-admin-empty {
  color: var(--slate);
  font-style: italic;
}

/* Item 51, Part 6 (original): a real support-links row, placed OUTSIDE
   .rq-window with its own --paper background and a top --hairline
   border for definition -- the same "quieter section, separated by a
   hairline" formula .rq-nav-secondary already used elsewhere.

   Item 52, Parts 1+2 (this revision, replacing the above): that
   placement was a real, measured bug -- being a sibling below
   .rq-window added its own full height on top of an already-100vh-tall
   window, forcing a real, confirmed ~53px scroll on every tested
   viewport (see dashboard.html's own comment at this element's new
   location for the measurement). Moved INSIDE .rq-window as the last
   flex child (a standard sticky-footer pattern, no page-height fix
   needed here beyond that move). Now that it's genuinely part of the
   SAME surface as the rest of the dashboard, the --paper background
   and --hairline top border are BOTH removed entirely, not just
   reworded -- transparent background lets .rq-window's own existing
   paper/gradient background show through with no seam, and no rule
   separates it from the content above, per this task's own explicit
   "read as an integrated part of the page, not a distinct section"
   instruction. Prominence increased: larger text (0.95rem, up from
   0.82rem) and semibold weight (600, matching .rq-nav-engine-name's
   own 500-weight "this is a real, deliberate UI element" precedent,
   pushed one step further since these are meant to be MORE noticeable
   than that, not equally so) -- reusing this file's own existing type
   scale, not inventing a new size. Links are --accent-colored by
   default now (not just on hover) so they read as real, branded,
   clickable elements immediately -- the same "burgundy signals
   interactive" language --accent already carries everywhere else in
   this file (nav-engine active state, primary buttons), reused rather
   than introduced fresh here. */
.rq-page-footer-links {
  /* Item 54, Part 4: top padding raised from 0.6rem to close the real
     ~40-60px target gap between the dashboard panel's bottom edge and
     this row, now that .rq-canvas-compact's own `flex: 0 1 auto`
     (above) makes that gap a small fixed quantity instead of a
     viewport-height-dependent one -- see BUILD_LOG item 54 for the
     real measured total. */
  padding: 2rem 1.5rem 0.9rem;
  text-align: center;
  font-size: 0.95rem;
  font-weight: 600;
}

.rq-footer-link-sep {
  margin: 0 0.7rem;
  color: var(--hairline);
  font-weight: 400;
}

/* .rq-footer-link (a real <a href>, for Help/Contact Support) and
   .rq-footer-link-btn (a <button>, for the FAQ link -- it opens the
   existing modal via JS, not a real page navigation) share identical
   appearance so a reader can't tell which is which by looking -- the
   distinction is only in what happens on click, which is correct: the
   FAQ content genuinely does live in a popup already, not a page. */
.rq-footer-link,
.rq-footer-link-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-family: var(--font-sans);
  font-size: inherit;
  font-weight: inherit;
  text-decoration: none;
  cursor: pointer;
}

.rq-footer-link:hover,
.rq-footer-link-btn:hover {
  color: var(--accent-hover);
  text-decoration: underline;
  text-underline-offset: 2px;
}
