/* Pauta brand palette and typography — docs/marca/identidade-visual.md in the
   JUSCompany repo. Each token keeps the brand's own color name in a comment,
   because that is how the design doc refers to them. */
:root {
  --brand-blue: #5D87FF;    /* Azul Pauta */
  --brand-cyan: #49BEFF;    /* Ciano Andamento */
  --brand-navy: #171C23;    /* Marinho Toga */
  --brand-ink: #2A3547;     /* Linha Escura */
  --brand-paper: #EAECF4;   /* Papel Timbrado */
  --brand-green: #13DECA;   /* Verde Trânsito */
  --brand-amber: #FFAE1F;   /* Âmbar Prazo */
  --brand-coral: #FA896B;   /* Coral Intimação */

  --bg: #F6F7FB;
  --surface: #FFFFFF;
  --text: var(--brand-ink);
  --text-muted: #5A6A85;
  --border: #E4E7F0;
  --shadow: 0 1px 2px rgba(23, 28, 35, .05), 0 8px 24px rgba(23, 28, 35, .06);
  --radius: 12px;

  /* What the tour paints over the page it is talking about. Its own token
     and not the dialog backdrop's: this one has a hole cut in it, and has to
     be dark enough that the hole reads as the only thing on screen. */
  --veil: rgba(23, 28, 35, .58);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: var(--brand-navy);
    --surface: #1E242E;
    --text: var(--brand-paper);
    --text-muted: #9AA6BF;
    --border: #2E3644;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .25);
    --veil: rgba(0, 0, 0, .66);
  }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

/* For the label a column needs and a reader does not: the actions column is
   obvious to anyone looking at it and nameless to anyone listening. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* ── Shell: sidebar + content ───────────────────────────── */
/* A sidebar and not a row of links across the top, because the navigation has
   two kinds of thing in it — the work and the administration of it — and named
   groups are what keeps those apart as more pages arrive. The cost is 236px
   that never come back, which is the trade this shape asks for. */
.app { display: flex; min-height: 100vh; }

.sidebar {
  width: 236px;
  flex: none;
  display: flex;
  flex-direction: column;
  padding-bottom: 18px;
  background: var(--surface);
  border-right: 1px solid var(--border);
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 96px;
  padding: 0 22px;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
}

.sidebar-brand .brand { line-height: 1.2; }

.brand {
  font-weight: 800;
  font-size: 24px;
  letter-spacing: -.03em;
  color: var(--text);
  text-decoration: none;
}

/* The full stop is always in the accent color — brand rule. */
.brand span { color: var(--brand-cyan); }

.nav-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 20px 14px 0;
}

.nav-title {
  padding: 0 8px 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  border-radius: 8px;
  transition: color .15s, background .15s;
}

.nav-item:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--brand-blue) 7%, transparent);
}

.nav-item[data-nav="publicacoes"] { display: none; }

.unified-refine { margin-top: 14px; }
.unified-refine summary { cursor: pointer; color: var(--text-muted); font-size: 13px; }

.nav-item.active {
  font-weight: 600;
  color: var(--brand-blue);
  background: color-mix(in srgb, var(--brand-blue) 10%, transparent);
}

.nav-item svg { flex: none; }

.content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.contentbar {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 96px;
  padding: 0 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.contentbar-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.session {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.session-user {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  /* A long name shrinks instead of pushing the sign-out button off screen. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 34ch;
}

.session-signout {
  padding: 7px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.session-signout:hover { color: var(--text); border-color: var(--text-muted); }

/* On a narrow screen the sidebar lies down across the top and scrolls
   sideways. A drawer would be the richer answer and needs a button, an overlay
   and a focus trap; this needs none of them and never hides where you are. */
@media (max-width: 860px) {
  .app { flex-direction: column; }

  .sidebar {
    width: auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0;
  }

  .sidebar-brand { min-height: 56px; border-bottom: 0; }
  .contentbar { height: 64px; }

  .sidebar-nav {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 0 14px 12px;
  }

  .nav-group { flex-direction: row; align-items: center; padding: 0; }
  .nav-title { padding: 0 4px 0 8px; }
  .nav-item { white-space: nowrap; }
}

/* ── Sign-in gate ─────────────────────────────────────────────────── */
.gate {
  max-width: 460px;
  margin: 56px auto;
  text-align: center;
}

/* Public, crawlable home shown before sign-in. It deliberately shares the same
   document as the portal: Cognito returns to `/` after authentication. */
.gate.seo-home {
  max-width: none;
  margin: 0;
  text-align: left;
}

.seo-header,
.seo-main,
.seo-footer {
  width: min(1120px, calc(100% - 40px));
  margin-inline: auto;
}

.seo-header {
  min-height: 72px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.seo-header .brand { text-decoration: none; }
.seo-header-link { color: var(--text); font-size: 14px; font-weight: 700; }

.seo-main { padding-bottom: 80px; }

.seo-hero {
  max-width: 840px;
  padding: 88px 0 96px;
}

.seo-eyebrow {
  margin: 0 0 14px !important;
  color: var(--brand-blue) !important;
  font-size: 12px !important;
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.gate.seo-home h1 {
  max-width: 800px;
  margin: 0 0 22px;
  font-size: clamp(38px, 6vw, 68px);
  line-height: 1.04;
  letter-spacing: -.045em;
}

.gate.seo-home h2 {
  margin: 0 0 18px;
  font-size: clamp(26px, 4vw, 38px);
  line-height: 1.12;
  letter-spacing: -.03em;
}

.gate.seo-home h3 { margin: 0 0 10px; font-size: 17px; }
.gate.seo-home p { line-height: 1.7; }

.seo-lead {
  max-width: 710px;
  margin-bottom: 30px !important;
  font-size: 18px !important;
}

.seo-cta {
  display: inline-flex;
  padding: 13px 20px;
  color: #fff;
  background: var(--brand-blue);
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
}

.seo-features,
.seo-how,
.seo-sources,
.seo-faq {
  padding: 72px 0;
  border-top: 1px solid var(--border);
}

.seo-section-heading { max-width: 680px; }
.seo-feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 32px; }
.seo-feature-grid article { padding: 26px; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; }
.seo-feature-grid article p { margin-bottom: 0; }
.seo-how { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; }
.seo-how ol { margin: 2px 0 0; padding-left: 22px; }
.seo-how li { margin-bottom: 20px; color: var(--text-muted); line-height: 1.65; }
.seo-how strong { color: var(--text); }
.seo-sources, .seo-faq { max-width: 780px; }
.seo-faq details { padding: 20px 0; border-bottom: 1px solid var(--border); }
.seo-faq summary { cursor: pointer; font-weight: 700; }
.seo-faq details p { margin: 12px 0 0; }
.seo-footer { display: flex; justify-content: space-between; gap: 20px; padding: 28px 0 40px; border-top: 1px solid var(--border); color: var(--text-muted); font-size: 12px; }

@media (max-width: 720px) {
  .seo-hero { padding: 58px 0 68px; }
  .seo-feature-grid, .seo-how { grid-template-columns: 1fr; }
  .seo-how { gap: 24px; }
  .seo-features, .seo-how, .seo-sources, .seo-faq { padding: 52px 0; }
  .seo-footer { flex-direction: column; }
}

.signin-page { min-height: 100vh; display: grid; place-items: center; padding: 32px 20px; }
.signin-card { width: min(100%, 460px); padding: 38px; text-align: center; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); }
.signin-card .brand { display: inline-block; margin-bottom: 28px; text-decoration: none; }
.signin-card h1 { margin: 0 0 10px; font-size: 26px; }
.signin-card > p { margin: 0 0 28px; color: var(--text-muted); line-height: 1.6; }
.signin-back { display: inline-block; margin-top: 24px; color: var(--text-muted); font-size: 13px; }

@media (max-width: 520px) {
  .signin-card { padding: 30px 22px; }
}

.gate h1 {
  margin: 0 0 10px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.02em;
}

.gate p { margin: 0 0 26px; color: var(--text-muted); font-size: 14.5px; }

.providers {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
}

/* White with a border, not the brand color: the two identity logos living
   inside the button are colored, and a blue background would clash with both.
   It is also the convention Google and Microsoft publish for their buttons. */
.provider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 13px 22px;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .05s;
}

.provider:hover {
  border-color: var(--text-muted);
  box-shadow: var(--shadow);
}

.provider:active { transform: translateY(1px); }

.provider:focus-visible {
  outline: none;
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px rgba(93, 135, 255, .18);
}

.provider:disabled { opacity: .6; cursor: default; }

/* Fixed size: the two logos have different viewBoxes and would end up
   misaligned with each other if they depended on their content. */
.provider-logo { width: 19px; height: 19px; flex: none; }

@media (prefers-reduced-motion: reduce) {
  .provider { transition: none; }
  .provider:active { transform: none; }
}

main {
  /* `width: 100%` is not redundant next to `max-width`. Inside `.content`, which
     is a column flex container, an auto cross-axis margin beats the default
     stretch — so without it the page shrink-wraps to its content and the layout
     jumps around as results arrive. */
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  padding: 28px 20px 72px;
}

/* Pages whose content is a table.
   860px is a reading width — right for a case timeline, and about 130px short of
   the admin table's six columns, which put a scrollbar under content that had
   room to spare beside it. Measured against the real rows: the widest table
   wants 953px, so this leaves room for a longer name or address before the
   scrollbar comes back. It still comes back on a narrow window, which is what
   `.table-scroll` is for. */
main.wide { max-width: 1100px; }

/* The form on such a page spans the same width as the table below it. A card
   that stops 240px short of the table reads as a mistake rather than as a
   reading measure — the two edges are right next to each other.

   What the narrower card was protecting was the fields, not the card: a case
   number in a 500px box looks like an error. So the columns are capped instead,
   which leaves every field the size it was and lets the card line up. */
main.wide .filter-grid { grid-template-columns: repeat(auto-fit, minmax(190px, 340px)); }

/* ── Page heading ─────────────────────────────────────────────────── */
.page-title {
  margin: 0 0 4px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--text);
}

.page-lead { margin: 0 0 28px; font-size: 14.5px; color: var(--text-muted); }

.gate-brand { display: block; margin-bottom: 22px; }

/* ── "Informe ao menos um" ────────────────────────────────────────── */
/* The rule sits above the fields and belongs to the group, not to any one of
   them. That is why no input here carries an asterisk: none of them is required
   on its own, and marking them individually would state the opposite. */
.required-group {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.required-title { font-size: 13.5px; font-weight: 700; color: var(--text); }

.required-note { font-size: 12.5px; color: var(--text-muted); }

.required-ok {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  font-weight: 600;
  /* Darkened from Verde Trânsito, which at brand strength does not carry enough
     contrast against white for text this size. */
  color: #1B9E8F;
}

/* ── Refinements, folded away ─────────────────────────────────────── */
/* <details> because the browser already implements disclosure, including the
   keyboard and the accessibility tree. Four extra empty boxes on the open page
   is four more things that read as pending work. */
.refine {
  margin-top: 18px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.refine > summary {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 14px;
  list-style: none;
  cursor: pointer;
  color: var(--text-muted);
}

.refine > summary::-webkit-details-marker { display: none; }

.refine > summary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(93, 135, 255, .18);
  border-radius: var(--radius);
}

.refine-title { font-size: 13.5px; font-weight: 600; color: var(--text); }

.refine-tag {
  padding: 2px 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .3px;
  color: var(--text-muted);
  background: var(--brand-paper);
  border-radius: 999px;
}

.refine-summary { margin-left: auto; font-size: 12.5px; color: var(--text-muted); }

/* Closing the block must never hide a filter that is doing something, so the
   summary line says how many are set. */
.refine-summary-active { color: var(--brand-blue); font-weight: 600; }

.refine-chevron { flex: none; transition: transform .15s; }
.refine[open] > summary .refine-chevron { transform: rotate(90deg); }

.refine-body { padding: 0 14px 16px; }

@media (prefers-reduced-motion: reduce) {
  .refine-chevron { transition: none; }
}

/* ── Monitoring ───────────────────────────────────────────────────── */
/* Two kinds and you pick one. They are not two flavours of the same request:
   a case is read from both courts every cycle, an OAB is a single search that
   spans every case the lawyer has. */
.watch-kinds { display: flex; gap: 8px; margin-bottom: 16px; }

.watch-kind {
  padding: 8px 16px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}

.watch-kind:hover { color: var(--text); border-color: var(--text-muted); }

.watch-kind.active {
  color: var(--brand-blue);
  border-color: color-mix(in srgb, var(--brand-blue) 45%, transparent);
  background: color-mix(in srgb, var(--brand-blue) 10%, transparent);
}

.watch-label { display: block; font-weight: 600; font-variant-numeric: tabular-nums; }

.row-actions { display: inline-flex; gap: 8px; }

/* Paused, not deleted — dimmed rather than hidden, because it is still a thing
   the person asked for and still has its history. */
.row-paused .watch-label,
.row-paused td { color: var(--text-muted); }

.role-action.danger { color: var(--brand-coral); border-color: color-mix(in srgb, var(--brand-coral) 40%, transparent); }
.role-action.danger:hover { color: var(--brand-coral); border-color: var(--brand-coral); }

/* ── Search ───────────────────────────────────────────────────────── */
.search { margin-bottom: 28px; }

.search-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 8px;
  color: var(--text-muted);
}

.search-field { display: flex; gap: 10px; }

.search-field input {
  flex: 1;
  min-width: 0;
  padding: 13px 16px;
  font: inherit;
  /* Tabular: the number is an identifier, it has to align digit by digit. */
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color .15s, box-shadow .15s;
}

.search-field input:focus {
  outline: none;
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px rgba(93, 135, 255, .18);
}

.search-field button {
  padding: 13px 22px;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: var(--brand-blue);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  transition: filter .15s;
}

.search-field button:hover { filter: brightness(1.07); }
.search-field button:disabled { opacity: .55; cursor: default; }

/* The unified search reads as one control, not an input with an unrelated
   action parked beside it. */
#search .search-field {
  gap: 0;
  padding: 5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: border-color .15s, box-shadow .15s;
}

#search .search-field:focus-within {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px rgba(93, 135, 255, .18);
}

#search .search-field input { padding: 14px 18px; background: transparent; border: 0; border-radius: 999px; box-shadow: none; }
#search .search-field button { width: 50px; height: 50px; display: grid; place-items: center; padding: 0; border-radius: 50%; }
#search .search-field button span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

.hint { margin: 8px 2px 0; font-size: 12.5px; color: var(--text-muted); }

/* ── Filter grid (search by lawyer or party) ──────────────────────── */
.filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px 16px;
}

.filter-field { min-width: 0; }
.filter-field .search-label { margin-bottom: 6px; }

/* The two free-text fields earn a full row of their own on wide screens: a
   party's name and a phrase from the publication are the long values here. */
.filter-text { grid-column: 1 / -1; }

.filter-field input,
.filter-field select {
  width: 100%;
  padding: 11px 14px;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color .15s, box-shadow .15s;
}

.filter-field input:focus,
.filter-field select:focus {
  outline: none;
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px rgba(93, 135, 255, .18);
}

/* Number and state travel together — the DJEN takes the pair, and a bar number
   without its state belongs to 27 different lawyers. */
.oab-pair { display: flex; gap: 8px; }
.oab-pair input:first-child { flex: 1; min-width: 0; font-variant-numeric: tabular-nums; }
.oab-pair input:last-child { width: 68px; flex: none; text-transform: uppercase; }

.filter-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 16px;
}

.filter-actions button {
  padding: 11px 22px;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: var(--brand-blue);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  transition: filter .15s;
}

.filter-actions button:hover { filter: brightness(1.07); }
.filter-actions button:disabled { opacity: .55; cursor: default; }

.filter-actions .ghost {
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  font-weight: 500;
}

.filter-actions .ghost:hover { color: var(--text); border-color: var(--text-muted); filter: none; }

.filter-actions .hint { margin: 0 0 0 auto; text-align: right; max-width: 42ch; }

.field-error {
  margin: 8px 2px 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--brand-coral);
}

/* ── States ───────────────────────────────────────────────────────── */
.state { padding: 8px 2px; }
.state-title { margin: 0 0 4px; font-size: 16px; font-weight: 600; }
.state-text { margin: 0; color: var(--text-muted); font-size: 14px; }

.skeleton {
  height: 14px;
  margin-bottom: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--border) 25%, var(--surface) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.3s infinite;
}

.skeleton-header { height: 64px; margin-bottom: 20px; }
.skeleton-line { height: 42px; }
.skeleton-line.short { width: 60%; }

@keyframes shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

/* ── Unavailable source warning ───────────────────────────────────── */
.warning {
  display: flex;
  gap: 10px;
  padding: 13px 16px;
  margin-bottom: 18px;
  font-size: 14px;
  border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--brand-amber) 45%, transparent);
  background: color-mix(in srgb, var(--brand-amber) 12%, var(--surface));
}

.warning strong { font-weight: 600; }

/* ── Identification card ──────────────────────────────────────────── */
.card {
  padding: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.identification-top {
  display: flex;
  gap: 16px;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
}

.identification .case-number {
  margin: 0;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.subject { margin: 4px 0 0; color: var(--text-muted); font-size: 14.5px; }

.badges { display: flex; gap: 8px; flex-wrap: wrap; }

.badge {
  padding: 5px 11px;
  font-size: 12px;
  font-weight: 600;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand-blue) 13%, transparent);
  color: var(--brand-blue);
  white-space: nowrap;
}

.fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px 22px;
  margin: 22px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.fields dt {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.fields dd { margin: 3px 0 0; font-size: 14.5px; font-weight: 500; }

/* ── Parties ──────────────────────────────────────────────────────── */
.parties {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.parties-group + .parties-group { margin-top: 16px; }

.parties h3 {
  margin: 0 0 9px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.party { display: flex; align-items: baseline; gap: 9px; padding: 3px 0; font-size: 14.5px; }

.side {
  flex: none;
  width: 62px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
}

.side-claimant { color: var(--brand-blue); }
.side-respondent { color: var(--brand-coral); }
.side-unknown { color: var(--text-muted); }

.oab { color: var(--text-muted); font-size: 13px; font-variant-numeric: tabular-nums; }

/* ── Timeline ─────────────────────────────────────────────────────── */
.section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin: 32px 0 14px;
}

.section-heading h2 { margin: 0; font-size: 17px; font-weight: 700; }

.count { color: var(--text-muted); font-weight: 500; font-size: 14px; }

/* A sentence about the list as a whole, between its heading and its rows.
   Measured rather than full-width: it is prose, and prose that runs the width of
   a wide table is prose nobody reads. */
.section-note {
  margin: -4px 0 12px;
  max-width: 72ch;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
}

.filters { display: flex; gap: 6px; flex-wrap: wrap; }

.filter {
  padding: 6px 13px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: all .15s;
}

.filter:hover { color: var(--text); border-color: var(--text-muted); }

.filter.active {
  color: #fff;
  background: var(--brand-ink);
  border-color: var(--brand-ink);
}

@media (prefers-color-scheme: dark) {
  .filter.active { color: var(--brand-navy); background: var(--brand-paper); border-color: var(--brand-paper); }
}

.timeline { list-style: none; margin: 0; padding: 0; }

/* ── Grouping by day ──────────────────────────────────────────────── */
.day + .day { margin-top: 22px; }

.day-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 8px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

.day-date {
  font-size: 13.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.day-relative { font-size: 12.5px; color: var(--text-muted); }

.day-events { list-style: none; margin: 0; padding: 0; }

.event {
  position: relative;
  padding: 16px 18px 16px 20px;
  margin-bottom: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  /* The bar on the left is the deadline signal — wide enough to be read at a
     glance, without depending on reading the badge. */
  border-left: 4px solid transparent;
  border-radius: var(--radius);
}

/* Âmbar Prazo: the color the brand reserves for deadlines. */
.event.deadline {
  border-left-color: var(--brand-amber);
  background: color-mix(in srgb, var(--brand-amber) 5%, var(--surface));
}

/* Cancelled: no amber bar, because there is no deadline here at all. */
.event.cancelled { opacity: .72; }
.event.cancelled .event-title { text-decoration: line-through; }

.event-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

.event-title { font-size: 15px; font-weight: 600; flex: 1; min-width: 180px; }

/* In the publications list the title is a line of its own, under the case
   number, rather than the first thing in the top row. */
p.event-title { margin: 6px 0 0; flex: none; min-width: 0; }

.flags { display: flex; gap: 6px; flex-wrap: wrap; }

.flag-source {
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .4px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--text-muted) 14%, transparent);
  color: var(--text-muted);
  white-space: nowrap;
}

/* ── Descomplica ───────────────────────────────────────────────────────
   The button sits with the card's other actions and is deliberately quieter
   than the court's own link beside it: this is a convenience, and the inteiro
   teor is the document. */
.event-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
}

.explain-button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand-blue);
  background: color-mix(in srgb, var(--brand-blue) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-blue) 26%, transparent);
  border-radius: 999px;
  cursor: pointer;
}

.explain-button:hover:not(:disabled) {
  background: color-mix(in srgb, var(--brand-blue) 14%, transparent);
  border-color: color-mix(in srgb, var(--brand-blue) 45%, transparent);
}

.explain-button:disabled { opacity: .6; cursor: progress; }

.explain-button.open { background: color-mix(in srgb, var(--brand-blue) 16%, transparent); }

.explain-spark { font-size: 12px; line-height: 1; }

/* A panel and not a tooltip: it is several paragraphs somebody reads slowly,
   and it has to survive them scrolling and looking back at the original. */
.explain-panel {
  margin-top: 10px;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--brand-blue) 22%, transparent);
  background: color-mix(in srgb, var(--brand-blue) 5%, var(--surface));
}

.explain-body p { margin: 0 0 10px; font-size: 14px; line-height: 1.6; }

.explain-body p:last-child { margin-bottom: 0; }

.explain-working { margin: 0; font-size: 13.5px; color: var(--text-muted); }

.explain-problem { margin: 0; font-size: 13.5px; color: var(--brand-coral); }

/* How much is left, above a list. Small and unemphatic — it is a budget, and a
   budget shown loudly is a budget people ration themselves against. */
/* The number field in the admin row. Narrow on purpose: it holds a handful of
   units a day, and a field sized for anything wider invites one. */
.allowance-field {
  width: 5.5em;
  padding: 6px 8px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 7px;
}

.allowance-field:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand-blue) 55%, transparent);
  outline-offset: 1px;
}

.explain-counter {
  font-size: 12.5px;
  color: var(--text-muted);
}

/* ── Caminhos possíveis ────────────────────────────────────────────────
   Triage, and quieter than everything it sits between. The amber bar and the
   PRAZO badge are the court's own facts about this card; what follows is the
   portal reading it, and it must never out-shout the thing it is describing. */

/* Empty until an answer lands, and empty is the normal state on a card whose
   act nobody could name. No margin of its own, so an empty one is invisible. */
.guidance-slot:empty { display: none; }

.guidance-slot { margin-top: 10px; }

/* The act, beside PRAZO and the source. Neutral on purpose: naming the kind of
   document is not a warning, and a second coloured badge next to the deadline
   one would dilute the only badge on the card that means urgency. */
.flag-act {
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .3px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--brand-blue) 12%, transparent);
  color: var(--brand-blue);
  white-space: nowrap;
}

/* The change rows on the OAB page have no flag container — a chip there is one
   more inline-block beside "Inicia prazo", which is the shape that row has. */
.change .flag-act { margin-top: 5px; display: inline-block; }

/* What the document asks for, read at a glance. The one line on this card that
   is meant to be scanned rather than read. */
.guidance-line {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}

/* Folded by default. The routes are reference material somebody opens when the
   act is unfamiliar; open by default, they would push the inteiro teor and the
   recipients off every card on the page. */
.guidance-paths { margin-top: 10px; }

/* A button and not a line of blue text. It was the latter and read as fine print
   next to the Descomplica's pill on the same card — the quieter of the two, which
   is backwards: this one is the reason the card carries an act at all.

   Same pill language as `.explain-button`, deliberately, so a card has one kind
   of action rather than two. Bigger than it, because it is the primary one, and
   filled a shade stronger so the two are told apart without a second colour.
   Amber is not an option here however well it would show: the brand reserves it
   for prazos, and a second amber thing on the card would dilute the one badge
   that means urgency. */
.guidance-open {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 9px 16px;
  font-size: 13.5px;
  color: var(--brand-blue);
  background: color-mix(in srgb, var(--brand-blue) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-blue) 34%, transparent);
  border-radius: 999px;
  cursor: pointer;
  list-style: none;
  width: fit-content;
  max-width: 100%;
  transition: background .15s, border-color .15s;
}

.guidance-open::-webkit-details-marker { display: none; }

.guidance-open:hover {
  background: color-mix(in srgb, var(--brand-blue) 18%, transparent);
  border-color: color-mix(in srgb, var(--brand-blue) 55%, transparent);
}

/* The keyboard gets the same ring the rest of the portal uses; a summary is
   focusable and would otherwise show the browser's own outline on a pill. */
.guidance-open:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand-blue) 55%, transparent);
  outline-offset: 2px;
}

/* Two glyphs rather than one rotated. A rotation would need a transform on the
   marker of a <details>, which is exactly the sort of thing that quietly does
   nothing on some engine and is never noticed; swapping `content` cannot fail
   halfway. */
.guidance-open::before {
  content: "▸";
  font-size: 10px;
  line-height: 1;
}

.guidance-paths[open] .guidance-open::before { content: "▾"; }

@media (prefers-reduced-motion: reduce) {
  .guidance-open { transition: none; }
}

.guidance-open-icon { font-size: 14px; line-height: 1; }

.guidance-open-label { font-weight: 700; }

/* Carried inside the control rather than under the list it opens. A caution below
   a list of recursos is a caution about something the reader has already started
   reading; quieter than the label, because it qualifies it rather than competing
   with it. */
.guidance-open-note {
  font-size: 12px;
  font-weight: 500;
  opacity: .8;
}

/* On a phone the label and the caution do not fit on one line, and a pill that
   wraps is a 68px lozenge. It becomes a block button instead: the full width of
   the card, squared off to the portal's own radius, which is a better tap target
   than the stadium was and reads as deliberate rather than as a pill that broke. */
@media (max-width: 520px) {
  .guidance-open {
    width: 100%;
    justify-content: flex-start;
    border-radius: var(--radius);
  }
}

.guidance-body {
  margin-top: 8px;
  padding: 12px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg);
}

.guidance-lead { margin: 0 0 10px; font-size: 13px; }

.guidance-path-list { margin: 0; padding: 0; list-style: none; }

.guidance-path {
  padding: 6px 0;
  border-top: 1px solid var(--border);
}

.guidance-path:first-child { border-top: none; padding-top: 0; }

.guidance-path-label { display: block; font-size: 13px; font-weight: 600; }

/* The article and the term, always together and always present — a route the
   reader cannot look up is an assertion, and this product does not make those. */
.guidance-path-meta {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.guidance-none { margin: 0; font-size: 13px; color: var(--text-muted); }

/* What the list above does not settle. Given the emphasis of the list itself
   rather than of a footnote: it is the half that decides whether any of those
   routes applies at all. */
.guidance-caveat {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  line-height: 1.55;
}

.guidance-note {
  margin: 8px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* The caution shown once a session, before the first list of recursos is opened.
   Wider than the admin screen's confirm, which holds one question: this one has
   three paragraphs and each is load-bearing, and squeezing them into 38ch turns
   a caution into a wall. */
.guidance-confirm { width: min(52ch, calc(100vw - 32px)); }

/* Every paragraph gets the spacing the admin dialog gives its single one, rather
   than the first sitting tight under the heading and the rest running together. */
.guidance-confirm .confirm-text + .confirm-text { margin-top: 12px; }

.flag-deadline {
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  border-radius: 5px;
  background: var(--brand-amber);
  color: #3D2A00;
  white-space: nowrap;
}

.flag-repeat {
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  border-radius: 5px;
  font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, var(--brand-cyan) 18%, transparent);
  color: var(--brand-cyan);
  white-space: nowrap;
}

.flag-cancelled {
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--brand-coral) 18%, transparent);
  color: var(--brand-coral);
  white-space: nowrap;
}

.event-court { margin: 6px 0 0; font-size: 13px; color: var(--text-muted); }

.event-deadline-note {
  margin: 8px 0 0;
  font-size: 12.5px;
  color: color-mix(in srgb, var(--brand-amber) 72%, var(--text));
}

.event-cancelled-note {
  margin: 8px 0 0;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--brand-coral);
}

.event-notified { margin: 10px 0 0; font-size: 13px; color: var(--text-muted); }
.event-notified strong { font-weight: 600; color: var(--text); }

.event-lawyers { margin: 4px 0 0; font-size: 12.5px; color: var(--text-muted); }
.event-lawyers strong { font-weight: 600; }

.event-link {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand-blue);
  text-decoration: none;
}

.event-link::after { content: " ↗"; }
.event-link:hover { text-decoration: underline; }

.full-text { margin-top: 12px; }

.full-text summary {
  font-size: 13px;
  font-weight: 600;
  color: var(--brand-blue);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.full-text summary::-webkit-details-marker { display: none; }
.full-text summary::before { content: "▸ "; display: inline-block; transition: transform .15s; }
.full-text[open] summary::before { content: "▾ "; }

.full-text-body {
  margin-top: 10px;
  padding: 14px 16px;
  font-size: 13.5px;
  line-height: 1.65;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--bg);
  border-radius: 8px;
  max-height: 420px;
  overflow-y: auto;
}

/* ── Publications found across cases ──────────────────────────────── */
/* The case number leads the entry here, where the case lookup can take it for
   granted: these publications come from however many different cases. */
.pub-case {
  padding: 0;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--brand-blue);
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
}

.pub-case:hover { text-decoration: underline; }

.more { display: flex; justify-content: center; margin-top: 18px; }

.more button {
  padding: 10px 22px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.more button:hover { color: var(--text); border-color: var(--text-muted); }
.more button:disabled { opacity: .55; cursor: default; }

/* ── Admin module ─────────────────────────────────────────────────── */
/* A table that is wider than the screen scrolls inside its own box. Without this
   the whole page scrolls sideways, and the header goes with it. */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.admin-table th {
  text-align: left;
  padding: 12px 16px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.admin-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  white-space: nowrap;
}

.admin-table tr:last-child td { border-bottom: none; }

/* Counts and dates line up column-wise only if the digits are the same width. */
.admin-table .numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* A name that opens something. It reads as a link because that is what it does;
   it is a button because it runs script rather than going to a URL. */
.link-button {
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--brand-blue);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
}

.link-button:hover { text-decoration: underline; }

/* The one cell allowed to wrap, and the reason the table fits a laptop. Cells are
   nowrap so a date or a count never breaks in two; an e-mail address under that
   rule makes its column as wide as itself, and three long addresses are the
   difference between a table that fits and a table with a scrollbar under it. */
#users .admin-table td:first-child { white-space: normal; }
#users .row-sub { overflow-wrap: anywhere; }

/* And it is the column that takes the slack: the three on its right size to a
   date, a count and a button, so anything the table has spare belongs here. That
   is what keeps an address on one line whenever there is room for one. */
#users .admin-table th:first-child,
#users .admin-table td:first-child { width: 100%; }

/* The name, with the badge beside it rather than in a column of its own. */
.row-name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* Pushed to the right edge, where the eye looks for what it can do to a row.
   Not `.row-actions`: the monitoring page owns that name and gives it
   display:inline-flex, which on a <td> is the cell dropping out of the table. */
.user-actions { text-align: right; }

.row-sub {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text-muted);
}

/* Role, and the button that changes it. A wrapper inside the cell, never the
   cell: display:flex on a <td> takes it out of the table layout, so it no longer
   grows to the row's height and its bottom border lands above the neighbouring
   ones — a staggered divider on every row that has one. */
.role-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}

.role-cell .row-sub { margin-top: 0; }

/* A check that reached a court and could not finish. Amber and not coral: the
   reading on screen is real, it is only short, and colouring it like a failure
   would say the opposite of what it means. */
.row-warning {
  display: block;
  margin-top: 4px;
  max-width: 34ch;

  /* The one thing in a table cell that is allowed to wrap. Cells are nowrap so a
     date or a case number never breaks across two lines, and a sentence under
     that rule does not wrap either — it just makes its column as wide as itself,
     which pushed the actions column off the edge and put a scrollbar under the
     whole table. The max-width above only binds once wrapping is possible. */
  white-space: normal;
  text-wrap: pretty;

  font-size: 12px;
  font-weight: 500;
  line-height: 1.45;
  color: color-mix(in srgb, var(--brand-amber) 55%, var(--text));
}

.row-warning::before {
  content: "⚠ ";
}

.flag-admin {
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--brand-blue) 16%, transparent);
  color: var(--brand-ink);
}

/* Deliberately quiet. Granting access is consequential, but a button styled to
   look consequential is a button people click to see what it does. */
.role-action {
  padding: 5px 12px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.role-action:hover { color: var(--text); border-color: var(--text-muted); }
.role-action:disabled { opacity: .55; cursor: default; }

/* ── One user's sheet ─────────────────────────────────────────────── */
/* A <dialog>, so the backdrop, Esc and the focus that stays inside are the
   browser's job rather than ours. Sized in ch and capped by the viewport: the
   longest line in it is an e-mail address, and a sheet wider than that is a
   modal with a column of empty space down one side. */
.sheet {
  width: min(46ch, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow);
  overflow-y: auto;
}

.sheet::backdrop { background: rgba(23, 28, 35, .45); }

.sheet-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 18px;
}

.sheet-head h2 { margin: 0; font-size: 18px; font-weight: 700; overflow-wrap: anywhere; }

.sheet-sub {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.sheet-close {
  margin-left: auto;
  padding: 0 6px;
  font: inherit;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
  background: none;
  border: 0;
  cursor: pointer;
}

.sheet-close:hover { color: var(--text); }

/* What the portal knows, as pairs. Two columns because these are short values
   that read as a block, not as four paragraphs. */
.sheet-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 16px;
  margin: 0;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}

.sheet-facts dt {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.sheet-facts dd {
  margin: 2px 0 0;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.sheet-block { margin-top: 20px; }

.sheet-block h3 {
  margin: 0 0 10px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.sheet-check {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
  cursor: pointer;
}

.sheet-check input { width: 16px; height: 16px; accent-color: var(--brand-blue); }

.sheet-allowance {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.sheet-field-label { font-size: 14px; color: var(--text-muted); }

/* Greyed rather than hidden while the portal's number is in force: the number is
   the thing an administrator came to see, and a field that vanishes takes the
   answer with it. */
.allowance-field:disabled {
  color: var(--text-muted);
  background: var(--bg);
  cursor: default;
}

.sheet-note { margin: 10px 0 0; font-size: 12.5px; color: var(--text-muted); }

.sheet-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.sheet-actions button {
  padding: 9px 18px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  background: var(--brand-blue);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  transition: filter .15s;
}

.sheet-actions button:hover { filter: brightness(1.07); }
.sheet-actions button:disabled { opacity: .55; cursor: default; filter: none; }

.sheet-actions .ghost {
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  font-weight: 500;
}

.sheet-actions .ghost:hover { color: var(--text); border-color: var(--text-muted); filter: none; }

/* Fechar and Salvar go to the right; "ver consultas" is a way out of this screen
   rather than an answer to it, so it stays on the left. */
#sheet-cancel { margin-left: auto; }

.sheet .notice { margin-top: 16px; }

/* Narrower than the sheet it opens over, and it stops being a form: one question
   and two answers. */
.confirm { width: min(38ch, calc(100vw - 32px)); }

.confirm h2 { margin: 0; font-size: 17px; font-weight: 700; }

.confirm-text {
  margin: 10px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-muted);
}

/* Both answers to the right, in reading order. Nothing here is a way out of the
   screen, so nothing anchors the left edge the way "ver consultas" does. */
.confirm .sheet-actions { justify-content: flex-end; }

/* Taking access away is the destructive half, and it is the half coloured. The
   other direction is expansive and gets the ordinary button — a screen where both
   answers look like alarms is a screen where neither does. */
.sheet-actions button.danger { background: var(--brand-coral); color: #3D1A0F; }

/* Sits above the table rather than replacing it: it comments on one row, and the
   reader is still working through the rest. */
.notice {
  margin: 14px 0 0;
  padding: 12px 14px;
  font-size: 13.5px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--brand-cyan) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-cyan) 30%, transparent);
}

.notice-error {
  background: color-mix(in srgb, var(--brand-coral) 14%, transparent);
  border-color: color-mix(in srgb, var(--brand-coral) 34%, transparent);
}

/* The ghost button already exists inside the filter bar; the admin heading needs
   the same thing, so the rule is repeated rather than the markup bent to match. */
.section-heading .ghost {
  padding: 8px 16px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.section-heading .ghost:hover { color: var(--text); border-color: var(--text-muted); }

@media (max-width: 560px) {
  .search-field { flex-direction: column; }
  .side { width: auto; }
  .party { flex-wrap: wrap; }
  .filter-actions .hint { margin: 4px 0 0; text-align: left; }

  /* On a phone the name and the way into it are all there is room for, and both
     numbers are one tap away in the sheet behind the row. Kept as columns on a
     laptop, where they are what a reader scans down. Only on the user list: every
     column of the lookup table is the answer to the question that opened it. */
  #users .admin-table th:nth-child(2),
  #users .admin-table td:nth-child(2),
  #users .admin-table th:nth-child(3),
  #users .admin-table td:nth-child(3) { display: none; }

  .sheet-facts { grid-template-columns: minmax(0, 1fr); }

  /* Three buttons do not fit across 375px. The way out of the sheet takes the
     first line on its own; Fechar and Salvar keep the line the thumb reaches. */
  .sheet-actions { flex-wrap: wrap; }
  #sheet-lookups-open { flex: 1 0 100%; }
}

/* ── Monitoring: the processes behind an OAB ──────────────────────── */
/* The count of processes, inside the sub-line of a row. Quiet, because a link
   styled like a call to action there would out-shout the registration it
   belongs to. */
.row-link { font-weight: 600; color: var(--brand-blue); text-decoration: none; }

.row-link:hover { text-decoration: underline; }

/* The way back from a page reached by link or bookmark, where the browser's own
   button has nowhere to go. */
.back-link {
  display: inline-block;
  margin-bottom: 10px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
}

.back-link:hover { color: var(--text); }

.case-list { margin: 18px 0 0; padding: 0; list-style: none; }

.case {
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.case + .case { margin-top: 10px; }

.case-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.case-number {
  font-weight: 700;
  color: var(--brand-blue);
  text-decoration: none;
}

.case-number:hover { text-decoration: underline; }

.case-count { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }

.case-last { margin: 6px 0 0; font-size: 14px; }

/* Âmbar Prazo, the same signal the case timeline uses — and the only reason to
   colour anything in this list. */
.case-last.deadline,
.change.deadline .change-title { color: var(--brand-amber); font-weight: 600; }

.case-changes { margin-top: 8px; font-size: 13px; }

/* What changed, one entry each. Ruled on the left rather than boxed: it is a
   detail of the process above it, not a list of its own. */
ol.changes {
  margin: 10px 0 0;
  padding: 2px 0 2px 14px;
  list-style: none;
  border-left: 2px solid var(--border);
}

.change { padding: 7px 0; }

.change-title { display: block; font-size: 13.5px; }

.change .row-sub { font-size: 12px; }

.change .flag-deadline { margin-top: 5px; display: inline-block; }

/* Like `.fields`, but each label and value stay together: a flat dl in a grid
   places dt and dd in consecutive cells, which on a wide page puts a label
   beside the previous field's value. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px 22px;
  margin: 18px 0 0;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.facts dt {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.facts dd { margin: 3px 0 0; font-size: 14.5px; font-weight: 500; }

/* A first check already on its way. "ainda não verificado" is true and reads as
   broken: every new subscription starts there, it is the first thing somebody
   sees after adding one, and the check is enqueued the moment the subject is
   saved. */
.checking {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text-muted);
}

.checking-dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand-cyan);
  animation: pulse 1.2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .35; transform: scale(.7); }
}

@media (prefers-reduced-motion: reduce) {
  .checking-dot { animation: none; }
}

/* ── Meu perfil ───────────────────────────────────────────────────── */
/* Three questions, so no grid: two stacked fields and then the block that is the
   reason the page exists. A grid of two would have put the age in a quarter of a
   row with three empty columns beside it. */
.profile .filter-field + .filter-field { margin-top: 14px; }

/* The select holds "35 a 44 anos" and never anything longer. A control the width
   of the page reads as a field that expects a lot. */
.profile .filter-field.short select { max-width: 280px; }

/* A fieldset, because the radios are one question and a screen reader should hear
   it as one. The browser's own border and padding go, since the block already
   sits inside the page's reading column. */
.role-group {
  margin: 22px 0 0;
  padding: 18px 0 0;
  border: none;
  border-top: 1px solid var(--border);
}

/* `legend` inside a fieldset floats oddly across engines, so it is laid out as a
   plain block. It keeps being a legend for anyone listening. */
.role-group > legend {
  display: block;
  float: left;
  width: 100%;
  padding: 0;
  margin-bottom: 14px;
}

.role-options { display: grid; gap: 8px; clear: both; }

/* The whole row is the target, not the 16px circle. These options carry a second
   line of explanation each, and a label you can only hit on the dot is a label
   that reads as decoration. */
.role-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  cursor: pointer;
}

.role-option:hover { border-color: var(--text-muted); }

.role-option input {
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  flex: none;
  accent-color: var(--brand-blue);
}

.role-option:has(input:checked) {
  border-color: var(--brand-blue);
  background: color-mix(in srgb, var(--brand-blue) 8%, transparent);
}

.role-option:has(input:focus-visible) { outline: 2px solid var(--brand-blue); outline-offset: 2px; }

.role-name { display: block; font-size: 14.5px; font-weight: 600; }

.role-note { display: block; margin-top: 2px; font-size: 12.5px; color: var(--text-muted); }

/* ── The registration, under the answer it belongs to ─────────────── */
/* One option and its extra field are one grid item, so nothing sits in the gap
   between them and the two edges meet.

   It used to be a block after the whole list, indented with a rule down its side,
   and it read as a submenu of whichever option happened to be above it — which was
   "prefiro não dizer", the one answer it has nothing to do with. Here it is simply
   the rest of the card that is already open. */
.role-choice { display: block; }

.role-choice:has(.role-oab:not([hidden])) .role-option {
  border-bottom: none;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.role-oab {
  /* Left padding lines the label up with the option's text above it: the option's
     own 13px, plus the radio and the gap beside it, less this block's own border. */
  padding: 2px 14px 14px 39px;
  border: 1px solid var(--brand-blue);
  border-top: none;
  border-radius: 0 0 10px 10px;
  background: color-mix(in srgb, var(--brand-blue) 8%, transparent);
}

.role-oab .oab-pair { max-width: 240px; }

.role-oab .hint { margin-top: 8px; max-width: 46ch; }

.optional { font-weight: 400; color: var(--text-muted); text-transform: none; letter-spacing: 0; }

/* ── The invitation to fill it in ─────────────────────────────────── */
/* On the page a sign-in lands on, and nowhere else. Quiet on purpose: it is the
   portal asking a favour, not telling somebody that something is wrong — which is
   why it borrows none of the colours that mean a deadline or a failure. */
.profile-invite {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 22px;
  padding: 13px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand-blue);
  border-radius: var(--radius);
  background: var(--surface);
}

.profile-invite p { margin: 0; flex: 1; min-width: 220px; font-size: 13.5px; color: var(--text-muted); }

.profile-invite a {
  flex: none;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--brand-blue);
  text-decoration: none;
  white-space: nowrap;
}

.profile-invite a:hover { text-decoration: underline; }

/* ── O tour ────────────────────────────────────────────────────────────
   Three layers and nothing more: a transparent veil that swallows clicks,
   a hole whose enormous shadow is what darkens the page, and the card. The
   only stack on the whole portal, so the numbers are small on purpose —
   they say "above the page" and never had to argue with anything else. */
.tour-veil {
  position: fixed;
  inset: 0;
  z-index: 30;
}

/* An opening card is about the product and has nothing to point at, so the
   dark comes from the veil itself rather than from a hole placed nowhere. */
.tour-veil.dim { background: var(--veil); }

.tour-spot {
  position: fixed;
  z-index: 31;
  border-radius: 10px;
  /* Bigger than any screen: what is painted is everything except this box. */
  box-shadow: 0 0 0 9999px var(--veil);
  outline: 2px solid var(--brand-cyan);
  outline-offset: 0;
  /* The hole is a cut-out and not a control — clicks belong to the veil under
     it, which is what stops the page from being operated mid-sentence. */
  pointer-events: none;
}

.tour-pop {
  position: fixed;
  z-index: 32;
  width: 340px;
  max-width: calc(100vw - 24px);
  padding: 16px 18px 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  animation: tour-in .16s ease-out;
}

@keyframes tour-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tour-pop { animation: none; }
}

.tour-count {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.tour-pop h2 { margin: 0 0 8px; font-size: 16px; font-weight: 700; }

.tour-text {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

.tour-text + .tour-text { margin-top: 9px; }

/* Pular sits at one end and Próximo at the other: they are not two answers to
   the same question, and putting them side by side would read as if they were. */
.tour-actions { margin-top: 16px; justify-content: space-between; }

.tour-actions button { padding: 8px 16px; font-size: 13.5px; }

/* ── The way back into it ─────────────────────────────────────────── */
/* In the bar above, beside the page's name rather than beside Sair: it is
   about this screen and not about the session. Hidden until a tour has been
   offered, so a page without one does not grow a button that does nothing. */
.tour-replay {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.tour-replay:hover { color: var(--text); border-color: var(--text-muted); }

/* ── The tour, on the screen that is about the reader ─────────────────
   Its own block below the form and not a field inside it: the form is what
   somebody types about themselves and a save replaces it whole, so a control
   for the tours living in there would have been a control that could reset
   them by accident. */
.tour-reset {
  margin-top: 28px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.tour-reset h2 { margin: 0 0 6px; font-size: 15px; font-weight: 700; }

.tour-reset-state {
  margin: 0 0 14px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 62ch;
}

.tour-reset button {
  padding: 9px 18px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.tour-reset button:hover { color: var(--text); border-color: var(--text-muted); }
.tour-reset button:disabled { opacity: .55; cursor: default; }

.tour-reset .notice { margin-top: 14px; }
/* ── Melhorias: saying something back ─────────────────────────────── */
/* The button on a card is deliberately the quietest thing in the row. It sits
   beside the Descomplica, which is an offer, and next to the court's own link,
   which is the document — this one is a way to complain, and it earns no colour
   until somebody wants it. */
.feedback-button {
  padding: 7px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.feedback-button:hover { color: var(--text); border-color: var(--text-muted); }

/* Always last in the row, whatever order the two modules attached in. The
   Descomplica waits on an allowance the page may still be reading, so without
   this the quieter button lands first on some cards and second on others. */
.feedback-button { order: 1; }

/* The box itself is a sheet, so it inherits the backdrop, the header and the
   footer the admin sheet already defines. What it adds is the writing area. */
.feedback { max-width: 560px; }

.feedback .role-options { margin-bottom: 18px; }

.feedback .search-label { display: block; margin-bottom: 6px; }

.feedback-message {
  display: block;
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  resize: vertical;
}

.feedback-message:focus-visible {
  outline: 2px solid var(--brand-blue);
  outline-offset: 1px;
  border-color: transparent;
}

.feedback .hint { min-height: 18px; margin: 6px 0 0; }

/* What travels with the message, said before it is sent. */
.feedback .sheet-note { margin-top: 10px; }

.feedback-thanks .state-title { margin: 0 0 6px; }

.feedback-thanks .state-text { margin: 0; }

/* ── Melhorias: reading them ──────────────────────────────────────── */
/* Cards and not table rows. What somebody wrote is prose, and prose in a cell is
   either clipped or the reason the table scrolls sideways. */
.notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }

.note {
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.note-top {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.note-when { margin-left: auto; font-size: 12.5px; color: var(--text-muted); }

/* Their words, at reading size and never truncated: a complaint cut off at two
   lines is a complaint half read. */
.note-message {
  margin: 10px 0 0;
  font-size: 14.5px;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.note-where {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 10px 0 0;
  font-size: 12.5px;
  color: var(--text-muted);
}
