.fh-ingestion { width: min(100% - 2rem, 52rem); margin: .75rem auto; padding: .85rem 1rem; border: 1px solid #b8ada1; border-radius: 12px; background: var(--surface-primary, #fffdf9); color: var(--text-primary, #252321); max-height: 38vh; overflow: auto; font-size: 13px; }
.fh-ingestion-heading, .fh-ingestion-actions { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.fh-ingestion-heading strong { font-size: 16px; }
/* Borders are a **light grey**. The old `#9c8a79` was a dark brown, so a file
   row carrying two buttons showed its borders before its filename - decoration
   standing in front of the thing to read.

   The grey is not hand-picked; it is LibreChat's `--border-medium`. That token
   changes in dark mode (`#00000026` / `#d9d9e326`), and the attachment chips on
   the same screen already use it - a grey of our own would catch the eye for
   being different.

   Being pressable is said by one step darker on hover. The border stays because
   these buttons (delete, download original) are ones a misclick would cost
   something, and they need an edge. */
.fh-ingestion button {
  border: 1px solid var(--border-medium, rgba(127, 127, 127, 0.15));
  border-radius: 6px; padding: .25rem .6rem; cursor: pointer;
  background: transparent; color: inherit;
}
.fh-ingestion button:hover {
  border-color: var(--border-heavy, rgba(127, 127, 127, 0.3));
  background: var(--surface-hover, rgba(127, 127, 127, 0.08));
}
.fh-ingestion button:disabled { opacity: .5; cursor: wait; }
.fh-ingestion-help { margin: .5rem 0; color: var(--text-secondary, #625c55); }
.fh-ingestion-notice { padding: .45rem; background: #c38d3220; border-radius: 4px; overflow-wrap: anywhere; white-space: pre-line; }
/* The rename offer under the quiet notice shares its look: one small grid row
   per document, the incoming name in the accent colour. */
.fh-rename { padding: .45rem; background: #c38d3220; border-radius: 4px; overflow-wrap: anywhere; font-size: 12px; text-align: left; }
.fh-ingestion-inline > .fh-rename { flex: 0 0 100%; box-sizing: border-box; }
.fh-rename-heading { margin: 0 0 .35rem; }
.fh-rename-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: .15rem .45rem; padding: .1rem 0; cursor: pointer; }
.fh-rename-row input[type="checkbox"] { margin: 0; accent-color: #8b6e51; }
.fh-rename-from { color: var(--text-secondary, #625c55); }
.fh-rename-input { min-width: 0; width: 100%; box-sizing: border-box; margin: 0; padding: .1rem .3rem; font: inherit; color: inherit; background: transparent; border: 1px solid #b8ada1; border-radius: 3px; cursor: text; }
.fh-rename-error { grid-column: 2 / -1; color: #b23127; }
.fh-rename-actions { display: flex; justify-content: flex-end; gap: .4rem; margin-top: .35rem; }
.fh-ingestion .fh-rename button { padding: .15rem .5rem; font-size: 12px; }
.fh-ingestion-batch, .fh-ingestion-question { margin-top: .6rem; padding-top: .6rem; border-top: 1px solid #b8ada170; }
.fh-ingestion-file { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem .65rem; padding: .45rem 0; }
.fh-ingestion-file strong { overflow-wrap: anywhere; }
.fh-ingestion-file span { color: var(--text-secondary, #625c55); }
.fh-ingestion-question p { margin: .4rem 0; white-space: pre-wrap; }
.fh-ingestion-question button { margin-left: .5rem; }

/* The viewer takes most of the window: the original's page on the left, the
   extracted text on the right. Under 900 px the two stack. */
.fh-ingestion-viewer { width: min(96vw, 90rem); height: min(92vh, 70rem); box-sizing: border-box; overflow: hidden; border: 1px solid #9c8a79; border-radius: 12px; padding: 1rem 1.2rem; background: var(--surface-primary, #fffdf9); color: var(--text-primary, #252321); }
.fh-ingestion-viewer[open] { display: flex; flex-direction: column; gap: .5rem; }
.fh-ingestion-viewer::backdrop { background: #0007; }
.fh-ingestion-viewer button { padding: .4rem .7rem; margin: .3rem;
  border: 1px solid var(--border-medium, rgba(127, 127, 127, 0.15));
  border-radius: 6px; background: transparent; color: inherit; cursor: pointer; }
.fh-ingestion-viewer button:hover { border-color: var(--border-heavy, rgba(127, 127, 127, 0.3)); }
.fh-ingestion-unit-list { display: flex; flex-wrap: wrap; max-height: 22vh; overflow: auto; }
/* An author `display` beats the UA's `[hidden] { display: none }`, so the rule
   above kept the unit list on screen after the citation view set hidden on it
   (observed on 3097, 2026-09-14). Anything this file gives a display to has to
   say what hidden means for it. */
.fh-ingestion-viewer [hidden] { display: none; }
.fh-ingestion-viewer pre { white-space: pre-wrap; overflow-wrap: anywhere; border-top: 1px solid #b8ada170; padding-top: 1rem; tab-size: 4; }
.fh-ingestion-viewer button:disabled { opacity: .45; cursor: default; }
.fh-viewer-head { display: flex; align-items: center; gap: .25rem; flex: none; }
.fh-viewer-head h2 { flex: 1; min-width: 0; margin: 0; font-size: 16px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fh-viewer-indicator { color: var(--text-secondary, #625c55); font-variant-numeric: tabular-nums; white-space: nowrap; }
.fh-viewer-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); grid-template-rows: minmax(0, 1fr); gap: 1rem; }
.fh-viewer-page { display: flex; flex-direction: column; min-height: 0; }
.fh-viewer-tools { display: flex; align-items: center; flex-wrap: wrap; flex: none; }
.fh-viewer-tools input { width: 4.5rem; margin: .3rem; padding: .35rem .4rem; font: inherit; color: inherit; background: transparent;
  border: 1px solid var(--border-medium, rgba(127, 127, 127, 0.15)); border-radius: 6px; }
.fh-viewer-status { margin: .3rem; color: var(--text-secondary, #625c55); }
/* The page sits on a tinted ground so its white edge shows. Fit to width is the
   default; off, the image keeps its own pixels and the box scrolls. */
.fh-viewer-box { flex: 1; min-height: 0; overflow: auto; border-radius: 8px; background: var(--surface-secondary, #efe9e1); }
.fh-viewer-box img { display: block; max-width: none; height: auto; margin: 0 auto; background: #fff; box-shadow: 0 1px 4px #0003; }
.fh-viewer-sheet { position: relative; width: fit-content; margin: 0 auto; }
.fh-viewer-fit .fh-viewer-sheet { width: 100%; }
.fh-viewer-fit img { width: 100%; }
/* The cited words, over the page image; multiply so the text under it still reads. */
.fh-viewer-mark { position: absolute; pointer-events: none; background: #e8b43a55; outline: 1px solid #c38d32; mix-blend-mode: multiply; }
/* Both panes take focus so the arrows and the scroll keys reach them; the ring
   is for keyboard focus only, since the page box is focused on open. */
.fh-viewer-box:focus, .fh-viewer-structured:focus { outline: none; }
.fh-viewer-box:focus-visible, .fh-viewer-structured:focus-visible { outline: 2px solid #c38d3280; outline-offset: -2px; }
.fh-viewer-text { min-height: 0; overflow: auto; }
.fh-viewer-structured { flex: 1; min-height: 0; overflow: auto; padding: .25rem .5rem; }
.fh-viewer-structured p { margin: 0 0 .2rem; min-height: 1.2em; white-space: pre-wrap; overflow-wrap: anywhere; }
.fh-viewer-structured table { margin: .4rem 0; border-collapse: collapse; }
.fh-viewer-structured td { padding: .2rem .45rem; vertical-align: top; white-space: pre-wrap; overflow-wrap: anywhere;
  border: 1px solid var(--border-heavy, rgba(127, 127, 127, 0.3)); }
.fh-viewer-ref { display: block; font-size: 10px; color: var(--text-secondary, #625c55); }
.fh-viewer-unit { padding: .35rem .5rem; }
.fh-viewer-unit + .fh-viewer-unit { border-top: 1px dashed var(--border-medium, rgba(127, 127, 127, 0.15)); }
.fh-viewer-cited { border-left: 3px solid #c38d32; background: #c38d3212; }
.fh-viewer-structured mark { background: #e8b43a66; color: inherit; border-radius: 2px; }
@media (max-width: 899.98px) {
  .fh-viewer-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 3fr) minmax(0, 2fr); }
}

/* A citation's one-line caption, between the head and the (usually folded) body. */
.fh-viewer-caption { display: flex; align-items: baseline; gap: .4rem; flex: none;
  padding: .3rem 0; overflow-wrap: anywhere; }
.fh-viewer-caption button { margin-left: auto; flex: none; }
/* The place label never wraps: with a long quote the flex row squeezed it to two lines (measured 2026-09-29). */
.fh-viewer-caption .fh-ingestion-cite-mark { white-space: nowrap; flex: none; }
/* Folded: the page pane alone: the extracted text is one button away, not gone. */
.fh-viewer-collapsed .fh-viewer-body { grid-template-columns: minmax(0, 1fr); }
.fh-viewer-collapsed .fh-viewer-text { display: none; }

/* In a chat the materials ride in the conversation, not above the composer.
   With a file attached the send is ours: LibreChat writes no user message
   until the answer is delivered, so a box by the input was the only thing on
   screen for the whole wait, in the one place the reader was not looking.

   Right-aligned, because this is the reader's own side of the conversation -
   it stands where their message will stand, and answer-delivery derives that
   message's id from the question so the block can pin itself above the real
   row once it arrives. */
.fh-ingestion-inline {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.375rem;
  width: 100%;
  max-width: 47rem;
  margin: 0.5rem auto;
  padding: 0;
  border: 0;
  background: none;
}

/* The one line left when the block is folded. It sits above the composer, so
   it takes the conversation's width, and it looks like a button without asking
   to be pressed - on most questions there is no reason to open it, but the
   count of attached files still has to be readable. */
.fh-ingestion-inline .fh-ingestion-summary {
  align-self: flex-end;
  border: 0;
  padding: 0.15rem 0.35rem;
  font-size: 12px;
  color: var(--text-secondary, #625c55);
}
.fh-ingestion-inline .fh-ingestion-summary::after {
  content: " ▾";
}
.fh-ingestion-inline.fh-ingestion-collapsed .fh-ingestion-summary::after {
  content: " ▸";
}
/* Folded leaves only the summary line. The list is hidden rather than removed
   so opening does not have to redraw it, and so a screen reader sees the same
   thing aria-expanded claims. */
.fh-ingestion-inline.fh-ingestion-collapsed > *:not(.fh-ingestion-summary):not(.fh-ingestion-notice-quiet):not(.fh-rename) {
  display: none;
}

.fh-ingestion-inline .fh-ingestion-batch,
.fh-ingestion-inline .fh-ingestion-file,
.fh-ingestion-inline .fh-ingestion-question {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  text-align: right;
}

/* The chip is the whole attachment: an icon and a name, the way one reads
   anywhere else. Everything the panel showed beside it - byte counts, the
   retained-original flag, the unit tally - answered a question nobody was
   asking while they waited. */
.fh-ingestion-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 22rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--border-medium, rgba(127, 127, 127, 0.3));
  border-radius: 0.75rem;
  background: var(--surface-secondary, rgba(127, 127, 127, 0.08));
  font-size: 0.8125rem;
}

.fh-ingestion-icon {
  width: 1rem;
  height: 1rem;
  flex: none;
  opacity: 0.75;
}

.fh-ingestion-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fh-ingestion-id { opacity: .7; font-variant-numeric: tabular-nums; }

/* One line under the chip, and it is the line that changes: a 20,737-unit
   document took an hour on 2026-09-13, and without this a reader cannot tell
   a slow file from a stopped one. */
.fh-ingestion-inline .fh-ingestion-stage {
  padding-right: 0.2rem;
  font-size: 0.75rem;
  color: var(--text-secondary, #6b6b6b);
}

/* A citation opened from the answer shows one line: where, then the words.
   The unit list stays in the DOM because the citation handler clicks its
   button to make the selection - it is hidden, not removed. */
.fh-ingestion-viewer-single pre {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
}

.fh-ingestion-cite-mark {
  margin-right: 0.1rem;
  font-weight: 600;
  color: var(--text-secondary, #6b6b6b);
}

/* The checkbox choosing whether a document is used in the answer. It sits
   inside the chip, so it matches the icon's size. A file that cannot be read
   yet is disabled, and that has to be visible - pressing it would mean
   nothing. */
.fh-ingestion-chip input[type="checkbox"] {
  margin: 0 0.15rem 0 0;
  accent-color: #8b6e51;
  cursor: pointer;
}
.fh-ingestion-chip input[type="checkbox"]:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

/* Citation markers inside the answer. They must not break the flow of the
   prose, so they do not look like buttons; an underline is all that says they
   can be pressed - [F12] is already a mark that stands out. */
.fh-cite {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 0.15em;
}
.fh-cite:hover { text-decoration: underline; }

/* The right end of the block's heading row. One `margin-left:auto` does the
   pushing so the button stays at the end however long the heading grows - a
   project name will be added to it one day. */
.fh-ingestion-add { margin-left: auto; }

/* Buttons on a file row **line up at the right edge.**

   Sitting straight after the text puts them at a different place on every row,
   following the filename's length, and three rows read as a staircase (reported
   2026-09-15). `margin-left:auto` on the first button pushes the rest along with
   it - the rule holds however many buttons a row carries (reprocess as CP949,
   pause transfer).

   The chat side stacks vertically and is already right-aligned, so it is left
   alone. */
.fh-ingestion:not(.fh-ingestion-inline) .fh-ingestion-file button:first-of-type {
  margin-left: auto;
}

/* ============================================================================
   EXPERIMENT (upload tiles): attachment cards in chat. Each attachment
   becomes a rounded card — an icon tile on the left, the
   filename over a quiet status line on the right. Scoped to inline/chat mode;
   the chip wrapper is dissolved (display:contents) so its parts join one grid.
   ============================================================================ */
/* Square file tiles flowing left-to-right and wrapping. ONE scroll container:
   the inline block itself wraps the tiles, batches are dissolved (display:contents)
   so multiple upload batches don't each get their own scrollbar, and the summary
   and question rows take their own full-width line. Caps at the summary line plus
   two tile rows, then scrolls. */
.fh-ingestion-inline {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  align-content: flex-start;
  justify-content: flex-start;
  gap: 8px;
  max-height: 288px;
  overflow-y: auto;
  text-align: left;
}
.fh-ingestion-inline > .fh-ingestion-summary { flex: 0 0 100%; }
.fh-ingestion-inline .fh-ingestion-batch { display: contents; }
.fh-ingestion-inline .fh-ingestion-question { flex: 0 0 100%; }
/* Status/notice paragraphs ("자료 상태 확인 중…", error notices) get their own
   full-width line instead of sitting inside the tile grid. */
.fh-ingestion-inline > p { flex: 0 0 100%; margin: 0; }
.fh-ingestion-inline .fh-ingestion-file {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 118px;
  height: 118px;
  flex: none;
  box-sizing: border-box;
  padding: 10px 10px 22px;
  border: 1px solid var(--border-medium, rgba(127, 127, 127, 0.25));
  border-radius: 0.75rem;
  background: var(--surface-primary, #fffdf9);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  text-align: center;
  overflow: hidden;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.fh-ingestion-inline .fh-ingestion-file:hover {
  border-color: var(--border-heavy, rgba(127, 127, 127, 0.42));
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.fh-ingestion-inline .fh-ingestion-chip { display: contents; }
.fh-ingestion-inline .fh-ingestion-icon {
  width: 2rem; height: 2rem; padding: 0.45rem; box-sizing: border-box;
  border-radius: 0.5rem; flex: none;
  background: var(--surface-secondary, rgba(127, 127, 127, 0.1));
  color: var(--text-secondary, #625c55); opacity: 1;
}
/* The short id under a tile name: its own short line, clear of the status word. */
.fh-ingestion-inline .fh-ingestion-stage .fh-ingestion-id { font-weight: 500; opacity: .8; }
.fh-ingestion-inline .fh-ingestion-name {
  width: 100%; flex: none;
  font-weight: 500; font-size: 0.78rem; line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; white-space: normal; word-break: break-word;
}
/* One-word status, pinned bottom-center of the tile; never wraps or overflows. */
.fh-ingestion-inline .fh-ingestion-stage {
  position: absolute; left: 6px; right: 6px; bottom: 7px;
  text-align: center; font-size: 0.7rem; font-weight: 600; line-height: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0;
  color: var(--text-secondary, #8b8375);
}
.fh-ingestion-inline .fh-ingestion-file button {
  margin-top: 3px; font-size: 0.66rem; padding: 2px 6px;
}
/* Ready: green "완료". */
.fh-ingestion-inline .fh-tile-ready .fh-ingestion-stage { color: #1f7a4d; }
/* Failed: red border + red "실패". */
.fh-ingestion-inline .fh-ingestion-file.fh-tile-failed { border-color: #b23127; }
.fh-ingestion-inline .fh-tile-failed .fh-ingestion-stage { color: #b23127; }
/* One icon in the top-right of a failed tile (keeps "실패" at the bottom):
   ↻ where a retry can change the answer, ✕ where it cannot and the only
   thing left to do is clear the row. The two never appear together.
   Selector carries an extra class so it beats the generic tile-button rule. */
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-retry,
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-delete {
  position: absolute; top: 5px; right: 5px; margin: 0;
  width: 20px; height: 20px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
  border: 1px solid #b23127; color: #b23127;
  background: var(--surface-primary, #fffdf9);
  border-radius: 50%; cursor: pointer;
}
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-retry:hover,
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-delete:hover {
  background: rgba(178, 49, 39, 0.08);
}
/* On a ready tile the ✕ is muted: it is an option, not an alarm. */
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-delete-quiet {
  border-color: var(--border-medium, #c9c1b4); color: var(--text-secondary, #8b8375);
}
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-delete-quiet:hover {
  border-color: #b23127; color: #b23127; background: rgba(178, 49, 39, 0.08);
}
/* A delete a running full review holds: still there, plainly not pressable, and
   hovering does not light it up the way the ready tile's ✕ does. */
.fh-ingestion .fh-ingestion-file button.fh-delete-locked,
.fh-ingestion .fh-ingestion-file button.fh-delete-locked:hover,
.fh-ingestion-inline .fh-ingestion-file button.fh-tile-delete-quiet.fh-delete-locked:hover {
  opacity: .35; cursor: not-allowed; background: none;
  border-color: var(--border-medium, #c9c1b4); color: var(--text-secondary, #8b8375);
}
/* The list scrolls inside a capped box; the line keeps to its bottom edge so the
   reason, and its flash, are in view wherever the list is scrolled. */
.fh-ingestion-lock { position: sticky; bottom: 0; margin: .35rem 0 0; padding: .2rem 0; font-size: .8125rem; color: var(--text-secondary, #6b6b6b); background: var(--surface-primary, #fffdf9); }
.fh-ingestion-inline > .fh-ingestion-lock { flex: 0 0 100%; }
.fh-ingestion-lock.fh-review-note-flash { color: var(--text-primary, #212121); font-weight: 600; }
/* 검토 취소 keeps the panel's button edge: a misclick there costs the review. */
.fh-ingestion-lock a.fh-ingestion-lock-action { text-decoration: underline; color: inherit; cursor: pointer; }
/* Small green spinner, top-left, while a tile is still processing. */
.fh-tile-spin {
  position: absolute; top: 7px; left: 7px;
  width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid rgba(94, 126, 110, 0.25);
  border-top-color: #5e7e6e;
  animation: fh-tile-spin 0.7s linear infinite;
}
@keyframes fh-tile-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .fh-tile-spin { animation-duration: 2s; } }

/* The full review's progress, under the handover line in the chat. It wears
   the in-turn progress line (fh-progress: the pulsing dot, the same size and
   colour) so the wait reads as one line continuing, not a new panel. The
   file lines and the cancel button stack in the text column beside the dot. */
.fh-review-lines { grid-row: 1; grid-column: 2; list-style: none; margin: 0; padding: 0; }
.fh-review-lines li { margin: .3rem 0; line-height: 1.6; }
.fh-review-lines li:first-child { margin-top: 0; }
.fh-review-head { color: var(--text-primary, #212121); font-size: .875rem; }
.fh-review-lines li:not(.fh-review-head) { padding-left: .75rem; }
.fh-review-done { opacity: .75; }
.fh-review-waiting { opacity: .6; }
.fh-review-cancel { grid-row: 2; grid-column: 2; justify-self: start; margin-top: .25rem; font-size: .75rem; text-decoration: underline; background: none; border: 0; padding: 0; color: inherit; cursor: pointer; }
.fh-review-lines li.fh-review-note { padding-left: 0; margin-top: .45rem; opacity: .8; }
.fh-review-lines li.fh-review-note-flash { color: var(--text-primary, #212121); opacity: 1; font-weight: 600; }
.fh-review-lines li.fh-review-unreachable { padding-left: 0; color: var(--text-primary, #212121); }
/* An ended review: the dot stops, red on failure, text colour while it waits on the
   reader. Two classes outrank fhellow-progress.css, loaded later: its dot and its reduced-motion rule. */
.fh-progress.fh-review-ended::before { animation: none; opacity: 1; background: #b23127; }
.fh-progress.fh-review-ended.fh-review-held::before { background: var(--text-primary, #212121); }
.fh-review-ended .fh-review-head { font-weight: 600; }
.fh-review-ended .fh-review-lines li:not(.fh-review-head) { padding-left: 0; }
.fh-review-actions { grid-row: 2; grid-column: 2; display: flex; gap: .9rem; margin-top: .25rem; }
.fh-review-actions button { font-size: .75rem; text-decoration: underline; background: none; border: 0; padding: 0; color: inherit; cursor: pointer; }
.fh-compose-hold { max-width: 47rem; margin: 0 auto .35rem; font-size: .8125rem; color: var(--text-secondary, #6b6b6b); text-align: center; }
.fh-compose-hold.fh-review-note-flash { color: var(--text-primary, #212121); font-weight: 600; }
/* The answer of a full review while it is written: under the progress box,
   in the chat's own answer typography. Only the spacing and the plain
   fallback are ours. */
.fh-review-draft { margin-top: .75rem; }
.fh-review-draft .fh-draft-plain { white-space: pre-wrap; }
.fh-review-draft .fh-draft-said { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Styled file-delete confirmation (fhConfirm in fhellow-ingestion.js), in place
   of the browser's native confirm(). Mirrors the admin dialog (fhellow-admin.css):
   warm-ink backdrop, hanji-paper surface, bordered buttons — with a clay accent
   on the destructive action. */
.fh-confirm-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100001;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5vh 16px;
  background: rgba(20, 17, 13, 0.45);
}
.fh-confirm-dialog {
  width: min(27rem, 100%);
  box-sizing: border-box;
  padding: 20px 22px 18px;
  font-family: var(--fh-sans);
  color: var(--fh-ink, #14110d);
  background: var(--fh-paper, #f1e9d9);
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(20, 17, 13, 0.35);
}
.fh-confirm-title { margin: 0 0 0.5rem; font-size: 1.05rem; font-weight: 700; }
.fh-confirm-body {
  margin: 0 0 1.1rem;
  font-size: 0.88rem;
  line-height: 1.55;
  color: rgba(20, 17, 13, 0.75);
}
.fh-confirm-actions { display: flex; justify-content: flex-end; gap: 0.5rem; }
.fh-confirm-btn {
  padding: 0.4rem 0.9rem;
  font: inherit;
  color: inherit;
  background: transparent;
  border: 1px solid rgba(20, 17, 13, 0.25);
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
}
.fh-confirm-btn:hover { background: rgba(20, 17, 13, 0.06); }
.fh-confirm-btn:focus-visible { outline: 2px solid var(--fh-celadon, #5e7e6e); outline-offset: 1px; }
.fh-confirm-danger { color: #8a2c22; border-color: rgba(138, 44, 34, 0.35); }
.fh-confirm-danger:hover { background: rgba(138, 44, 34, 0.08); }

/* Dark mode: the dialog carries role="dialog", so .dark [role="dialog"] in
   fhellow-tone.css gives it a dark surface — the paper text set above would then
   be dark-on-dark. Restate the surface and switch the ink to light so it reads. */
.dark .fh-confirm-dialog {
  background: #2a241c;
  color: var(--text-primary, #ece7dd);
  border: 1px solid var(--border-heavy);
}
.dark .fh-confirm-body { color: rgba(236, 231, 221, 0.78); }
.dark .fh-confirm-btn {
  color: var(--text-primary, #ece7dd);
  border-color: rgba(236, 231, 221, 0.28);
}
.dark .fh-confirm-btn:hover { background: rgba(236, 231, 221, 0.08); }
.dark .fh-confirm-danger { color: #e3685a; border-color: rgba(227, 104, 90, 0.4); }
.dark .fh-confirm-danger:hover { background: rgba(227, 104, 90, 0.12); }
