/* ── Display type ───────────────────────────────────────────────
   Newsreader belongs to headings and nothing else. It is the one
   thing in the app that has a voice, and it only keeps that voice
   by staying out of the working furniture: no control, label,
   table, list row or piece of running prose is set in it.

   This file loads last on purpose. The headings it claims are
   declared across base.css and features.css, so owning the type
   role in one place beats chasing it through both -- and when the
   feature stylesheets are eventually split up, this survives as
   the type scale rather than dissolving into them.

   Newsreader runs a touch narrower than the interface face at the
   same size, so display sizes take slight negative tracking to keep
   the colour even; the smaller headings are left alone. */

.auth-heading h1,
.empty-state h2,
.library-title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
}

/* Weight 400 in a serif already reads heavier than 600 in a grotesque,
   so the old weights would shout. The rail, the row names and every
   label keep the interface face and their own weights. */
.auth-heading h1 { font-weight: 400; letter-spacing: -.018em; }
/* A notice runs longer than a greeting and will wrap. Balanced lines keep the
   halves even instead of stranding a word underneath, and the heading needs
   more leading than a one-line greeting ever asked for -- at display size the
   default sets the rows close enough to read as one block of text. */
.empty-state h2 { font-weight: 400; text-wrap: balance; line-height: 1.5; }
.library-title { font-weight: 400; }

/* ── Brand mark ─────────────────────────────────────────────────
   The rail wordmark carries ÚZEI's own mark -- the same file the
   favicon uses, so there is one image to keep current, not two.
   The login screen wears the same one: it is the first thing anyone
   sees, and a second wordmark there would be the app introducing
   itself twice, differently. */
.brand-title,
.auth-brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: .02em;
  text-transform: none;
}

.brand-mark {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  display: block;
}

/* Flexbox centres the wordmark's *box* against the mark, which is not the same
   as centring the wordmark. Newsreader's line box carries ascender and
   descender room that an all-caps wordmark never uses, and the room is not
   shared out evenly, so the ink lands 2.6px high against a 22px mark -- more
   than a tenth of the mark's height, and quite visible as the lockup sitting
   out of true. There is no box-model fix for that: the offset is a property of
   the face's own metrics, so it is measured (from the painted pixels, not from
   font metrics, which disagree with what is drawn) and applied. In em so it
   holds if the wordmark is ever resized.

   line-height pins the row to the mark rather than to the wordmark's leading,
   which keeps the brand row 22px instead of the 23.1px the line box would
   otherwise impose. It does nothing for the centring. */
.brand-title > span,
.auth-brand > span {
  line-height: 1;
  transform: translateY(.154em);
}

/* ── Empty chat ─────────────────────────────────────────────────
   The heading, then three ways in. No second line of prose: the
   empty states say one thing each (see base.css, which hides the
   paragraph here), and the rows already do the orienting a
   subtitle would have done.

   Rows, not pills. A pill has to shrink its label to fit beside its
   neighbours, which pushed the real question into a tooltip; a row
   has the whole width, so what you click is what you get. They also
   read as a short list of things the tool can do, which is the point
   on a first visit. */
.chat-suggestions { display: none; }

body.chat-empty .chat-suggestions {
  display: flex;
  /* #input-area is pointer-events:none so clicks fall through its transparent
     area to the chat behind; #ask-form switches them back on for the composer.
     This host sits outside the form, so it has to do the same or the rows
     look live and swallow nothing. */
  pointer-events: auto;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  width: 100%;
  max-width: 680px;
  /* Well clear of the composer: they are a set of examples sitting below the
     thing you type in, not a fifth row of it. The gap has to beat the spacing
     between the rows themselves by a wide margin, or the whole block reads as
     one list that happens to start with a text field. */
  margin: 46px auto 0;
}

.empty-suggestion {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  font: inherit;
  font-size: 13.5px;
  line-height: 1.4;
  text-align: left;
  color: var(--muted);
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
  padding: 9px 12px;
  cursor: pointer;
  transition: background var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

.empty-suggestion-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  color: var(--faint);
  transition: color var(--dur) var(--ease-out);
}

.empty-suggestion-icon svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.empty-suggestion-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.empty-suggestion:hover {
  background: var(--hover-bg);
  color: var(--ink);
}

/* The one spot of colour: the icon answers the pointer, which is enough
   to say the row is live without giving every row a border. */
.empty-suggestion:hover .empty-suggestion-icon { color: var(--accent); }

.empty-suggestion:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* On a phone a long question needs to wrap rather than be cut. */
@media (max-width: 640px) {
  .empty-suggestion-text { white-space: normal; }
}

/* ── Step icons ─────────────────────────────────────────────────
   One mark per kind of step, so a run reads as a sequence of acts
   instead of a wall of sentences. Quiet by default -- the icon is
   there to be scanned, not to compete with the label it sits
   beside. Same stroke language as the nav. */
.step-icon {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  color: var(--muted);
}

.step-icon svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Top-aligned, not centred: a step that wraps to three lines put its icon
   halfway down the paragraph, pointing at nothing. The nudge sits it on the
   first line's optical centre. */
.loading-step-title {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  color: var(--text);
  font-weight: 500;
}

.loading-step-title > .step-icon { margin-top: 2px; }

/* Rows stay still; only the current final row carries a running-state cue.
   Some providers do not emit an explicit completion event before beginning
   the next act, so position is the dependable expression of "current". */
.loading-step-row {
  animation: none;
  opacity: 1;
}

.loading-step-row:last-child:not(.done) .loading-step-title > span:not(.step-icon),
.loading-step-row:last-child:not(.done):not(.is-thought) .step-icon,
.loading-step-row.is-settling .loading-step-title > span:not(.step-icon),
.loading-step-row.is-settling .step-icon {
  animation: loadingTextPulse 1.25s ease-in-out infinite;
  will-change: opacity;
}

/* ── A run reads as a sequence ───────────────────────────────────
   Finished steps stay on screen and settle back rather than being
   overwritten, so what the answer did to get here is still legible
   while it is being written. Tight rows, because there are now
   several of them where there used to be one status line. */
.loading-steps.is-sequence .loading-step-row {
  padding: 3px 0;
  margin-bottom: 0;
}

.loading-steps.is-sequence .loading-step-title {
  margin-bottom: 0;
  font-size: 14px;
  font-weight: 500;
}

.loading-step-row.done {
  animation: none;
  opacity: 1;
}

.loading-step-row.done .loading-step-title { color: var(--text); }
.loading-step-row.done .step-icon { color: var(--muted); }

/* ── Thinking reads as prose ─────────────────────────────────────
   What the run is saying, as against what it did. Full reading size
   in body ink, no icon, and room around it -- so the small muted
   rows above and below it read as the acts it led to. */
.loading-step-row.is-thought .loading-step-title {
  color: var(--text);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.62;
}

.loading-step-row.is-thought.done .loading-step-title { color: var(--text); }

.loading-step-row.is-thought .step-icon { display: none; }

.loading-steps.is-sequence .loading-step-row.is-thought {
  padding: 10px 0;
}

/* Adding the first act must not pull an existing opening thought upward. */
.loading-steps.is-sequence .loading-step-row.is-thought:first-child {
  padding-top: 14px;
}

/* The bare "Přemýšlím" placeholder is a dot that breathes in and out, sat
   on the line a thought's first words will take. */
.loading-step-title.is-placeholder {
  align-items: center;
  min-height: 1.62em;
}

.loading-step-title.is-placeholder::before {
  content: "";
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--text);
  animation: thinkingDotBreathe 1.4s ease-in-out infinite;
}

.loading-step-title.is-placeholder > span:not(.step-icon) {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@keyframes thinkingDotBreathe {
  0%, 100% { transform: scale(.6); opacity: .75; }
  50% { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .loading-step-title.is-placeholder::before {
    animation: none;
  }

  .loading-step-row:last-child:not(.done) .loading-step-title > span:not(.step-icon),
  .loading-step-row:last-child:not(.done):not(.is-thought) .step-icon,
  .loading-step-row.is-settling .loading-step-title > span:not(.step-icon),
  .loading-step-row.is-settling .step-icon {
    animation: none;
  }
}

/* The trigger used to hold two children -- label and chevron -- so
   space-between put one at each end. With an icon in front it centred
   the label instead, leaving it stranded mid-row. The label takes the
   free space now and the chevron still lands at the end. */
.answer-inspector-step-trigger {
  justify-content: flex-start;
  gap: 9px;
}

.answer-inspector-step-label {
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
}
.answer-inspector-step-trigger .step-icon { color: var(--faint); }
.answer-inspector-step-trigger.active .step-icon { color: var(--accent); }
