/* GENERATED — do not edit.
   Source: strim-ai-portal/tokens/tokens.json
   Regenerate: node scripts/generate-tokens.ts

   Colours are declared per theme; everything scalar is theme-independent.
   Anything in this file that is not in tokens.json is listed as a supplement
   in the generator, which is also the list of portal CSS that has no token. */

:root {
  --token-space-1: 4px;
  --token-space-2: 8px;
  --token-space-3: 12px;
  --token-space-4: 16px;
  --token-space-5: 20px;
  --token-space-6: 24px;
  --token-space-8: 32px;
  --token-space-10: 40px;
  --token-space-12: 48px;
  --token-space-16: 64px;
  --token-space-24: 96px;

  --token-radius-sm: 8px;
  --token-radius-md: 12px;
  --token-radius-lg: 16px;
  --token-radius-pill: 999px;
  --token-radius-seg: 10px;
  --token-radius-seg-item: 7px;
  --token-radius-chip: 6px;
  --token-radius-check: 5px;

  --token-fs-2xs: 0.6875rem;
  --token-fs-xs: 0.75rem;
  --token-fs-xs-plus: 0.8125rem;
  --token-fs-sm: 0.875rem;
  --token-fs-md: 1rem;
  --token-fs-brand: 1.1875rem;
  --token-fs-lg: 1.25rem;
  --token-fs-h3: 1.3125rem;
  --token-fs-h2: 1.5rem;
  --token-fs-xl: 1.625rem;
  --token-fs-h1: 1.75rem;
  --token-fs-2xl: 2.75rem;

  --token-lh-tight: 1.1;
  --token-lh-snug: 1.3;
  --token-lh-normal: 1.55;
  --token-lh-relaxed: 1.65;

  --token-dur-fast: 120ms;
  --token-dur-base: 200ms;
  --token-dur-slow: 400ms;

  --token-z-base: 0;
  --token-z-content: 1;
  --token-z-sticky: 10;

  --token-layout-sidebar: 248px;
  --token-layout-max: 1280px;
  --token-layout-side-pad-y: 18px;
  --token-layout-side-pad-x: 12px;
  --token-layout-item-pad-x: 10px;
  --token-layout-brand-gap: 10px;
  --token-layout-brand-pad-bottom: 20px;
  --token-layout-dot: 10px;
  --token-layout-label-pad-top: 18px;
  --token-layout-label-pad-bottom: 6px;
  --token-layout-sub-indent: 26px;
  --token-layout-hair-gap: 2px;
  --token-layout-avatar: 30px;
  --token-layout-page-pad-y: 30px;
  --token-layout-page-pad-x: 40px;
  --token-layout-block-gap: 18px;
  --token-layout-control-h: 36px;
  --token-layout-control-h-sm: 30px;
  --token-layout-control-pad-x: 14px;
  --token-layout-control-pad-x-sm: 10px;
  --token-layout-seg-inset: 3px;
  --token-layout-seg-item-h: 30px;
  --token-layout-seg-item-pad-x: 12px;
  --token-layout-pill-h: 24px;
  --token-layout-pill-h-sm: 20px;
  --token-layout-pill-pad-x: 10px;
  --token-layout-pill-gap: 6px;
  --token-layout-row-h: 50px;
  --token-layout-cell-pad-x: 12px;
  --token-layout-head-pad-y: 10px;
  --token-layout-card-pad-y: 10px;
  --token-layout-card-pad-x: 16px;
  --token-layout-tab-gap: 24px;
  --token-layout-tab-pad-y: 10px;
  --token-layout-aside: 420px;
  --token-layout-aside-pad-y: 24px;
  --token-layout-aside-pad-x: 28px;
  --token-layout-timecode: 58px;
  --token-layout-chip-pad-x: 9px;
  --token-layout-search: 240px;
  --token-layout-col-tick: 44px;
  --token-layout-col-when: 150px;
  --token-layout-col-duration: 100px;
  --token-layout-col-state: 170px;
  --token-layout-col-action: 190px;

  --token-font-display: "E UkraineHead", "E Ukraine", "IBM Plex Sans", Arial, sans-serif;
  --token-font-body: "IBM Plex Sans", Arial, sans-serif;
  --token-font-mono: ui-monospace, "SF Mono", SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace;

  --token-weight-regular: 400;
  --token-weight-medium: 500;

  /* border widths — the portal writes 1px/2px/3px inline */
  --token-border-hair: 1px;
  --token-border-thick: 2px;
  --token-border-accent: 3px;
  --token-border-check: 1.5px;

  /* sub-space values below space-1, used by chips and segmented controls */
  --token-inset-chip: 3px;
  --token-gap-hair: 2px;

  /* control sizes — no size scale exists in tokens.json */
  --token-size-dot: 9px;
  --token-size-dot-sm: 7px;
  --token-size-avatar: 26px;
  --token-size-checkbox: 18px;
  --token-size-caret: 5px;
  --token-size-nav-row: 34px;
  --token-size-badge: 22px;
  --token-size-badge-icon: 12px;
  --token-size-icon-sm: 14px;
  --token-size-icon: 16px;
  --token-size-icon-lg: 20px;
  --token-size-icon-xl: 32px;
  --token-size-hidden: 1px;

  /* layout widths — grid minimums */
  --token-layout-card-min: 250px;
  --token-layout-sidebar-collapsed: 64px;
  --token-layout-toast: 380px;
  --token-layout-panel-min: 300px;
  --token-layout-stat-min: 140px;
  --token-layout-field-basis: 220px;
  --token-layout-field-max: 340px;
  --token-layout-offscreen: -9999px;

  /* measures — line length in characters, so they follow the font, not the viewport */
  --token-measure-lede: 60ch;
  --token-measure-note: 34ch;
  --token-measure-prose: 44ch;
  --token-measure-cell: 7ch;
  --token-measure-col-when: 22ch;
  --token-measure-col-duration: 12ch;
  --token-measure-col-action: 23ch;

  /* one-off scale gaps */
  --token-fs-hero-min: 2rem;
  --token-z-skip: 100;
}

/* Dark by default: strim.co is dark, and an unset preference should not flash
   a light page at someone who never asked for one. */
:root,
:root[data-theme='dark'] {
  color-scheme: dark;
  --token-color-surface: #111111;
  --token-color-surface-raised: #181818;
  --token-color-surface-inset: #1f1f1f;
  --token-color-surface-sunken: #0c0c0c;
  --token-color-text-primary: #f5f5f5;
  --token-color-text-secondary: #b8b8b8;
  --token-color-text-tertiary: #9c968b;
  --token-color-text-meta: #858179;
  --token-color-border-subtle: #2a2a2a;
  --token-color-border-strong: #3b3b3b;
  --token-color-accent-fill: #573caf;
  --token-color-accent-text: #c0c0fa;
  --token-color-on-accent: #ffffff;
  --token-color-accent-wash: #241a3d;
  --token-color-state-crit-text: #ff9b8f;
  --token-color-state-crit-bg: #3a1714;
  --token-color-state-warn-text: #ffc46b;
  --token-color-state-warn-bg: #3a2a10;
  --token-color-state-ok-text: #7fd6a6;
  --token-color-state-ok-bg: #12301f;
  --token-color-state-info-text: #c0c0fa;
  --token-color-state-info-bg: #241a3d;
  --token-color-state-neutral-text: #d2d2d2;
  --token-color-state-neutral-bg: #2a2a2a;
  --token-color-state-run: #c0c0fa;
  --token-color-state-fail: #ff9b8f;
  --token-color-state-ghost: #9c968b;
}

:root[data-theme='light'] {
  color-scheme: light;
  --token-color-surface: #f5f5f5;
  --token-color-surface-raised: #ffffff;
  --token-color-surface-inset: #fafafa;
  --token-color-surface-sunken: #ececec;
  --token-color-text-primary: #111111;
  --token-color-text-secondary: #3b3b3b;
  --token-color-text-tertiary: #626262;
  --token-color-text-meta: #626262;
  --token-color-border-subtle: #e2e2e2;
  --token-color-border-strong: #d2d2d2;
  --token-color-accent-fill: #573caf;
  --token-color-accent-text: #46309a;
  --token-color-on-accent: #ffffff;
  --token-color-accent-wash: #ece9f7;
  --token-color-state-crit-text: #b42318;
  --token-color-state-crit-bg: #fdecea;
  --token-color-state-warn-text: #8a4b00;
  --token-color-state-warn-bg: #fff1dc;
  --token-color-state-ok-text: #1b6e45;
  --token-color-state-ok-bg: #e3f3ea;
  --token-color-state-info-text: #46309a;
  --token-color-state-info-bg: #ece9f7;
  --token-color-state-neutral-text: #3b3b3b;
  --token-color-state-neutral-bg: #ececec;
  --token-color-state-run: #46309a;
  --token-color-state-fail: #b42318;
  --token-color-state-ghost: #626262;
}

/* System preference, until the reader picks a theme explicitly. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    color-scheme: light;
    --token-color-surface: #f5f5f5;
    --token-color-surface-raised: #ffffff;
    --token-color-surface-inset: #fafafa;
    --token-color-surface-sunken: #ececec;
    --token-color-text-primary: #111111;
    --token-color-text-secondary: #3b3b3b;
    --token-color-text-tertiary: #626262;
    --token-color-text-meta: #626262;
    --token-color-border-subtle: #e2e2e2;
    --token-color-border-strong: #d2d2d2;
    --token-color-accent-fill: #573caf;
    --token-color-accent-text: #46309a;
    --token-color-on-accent: #ffffff;
    --token-color-accent-wash: #ece9f7;
    --token-color-state-crit-text: #b42318;
    --token-color-state-crit-bg: #fdecea;
    --token-color-state-warn-text: #8a4b00;
    --token-color-state-warn-bg: #fff1dc;
    --token-color-state-ok-text: #1b6e45;
    --token-color-state-ok-bg: #e3f3ea;
    --token-color-state-info-text: #46309a;
    --token-color-state-info-bg: #ece9f7;
    --token-color-state-neutral-text: #3b3b3b;
    --token-color-state-neutral-bg: #ececec;
    --token-color-state-run: #46309a;
    --token-color-state-fail: #b42318;
    --token-color-state-ghost: #626262;
  }
}

/* People export the quota and cost tables to PDF. Printed from the dark theme
   that is light text on white paper — a blank sheet — so print forces the light
   values here rather than making app.css restate them as literals. */
@media print {
  :root {
    color-scheme: light;
    --token-color-surface: #f5f5f5;
    --token-color-surface-raised: #ffffff;
    --token-color-surface-inset: #fafafa;
    --token-color-surface-sunken: #ececec;
    --token-color-text-primary: #111111;
    --token-color-text-secondary: #3b3b3b;
    --token-color-text-tertiary: #626262;
    --token-color-text-meta: #626262;
    --token-color-border-subtle: #e2e2e2;
    --token-color-border-strong: #d2d2d2;
    --token-color-accent-fill: #573caf;
    --token-color-accent-text: #46309a;
    --token-color-on-accent: #ffffff;
    --token-color-accent-wash: #ece9f7;
    --token-color-state-crit-text: #b42318;
    --token-color-state-crit-bg: #fdecea;
    --token-color-state-warn-text: #8a4b00;
    --token-color-state-warn-bg: #fff1dc;
    --token-color-state-ok-text: #1b6e45;
    --token-color-state-ok-bg: #e3f3ea;
    --token-color-state-info-text: #46309a;
    --token-color-state-info-bg: #ece9f7;
    --token-color-state-neutral-text: #3b3b3b;
    --token-color-state-neutral-bg: #ececec;
    --token-color-state-run: #46309a;
    --token-color-state-fail: #b42318;
    --token-color-state-ghost: #626262;
  }
}

/* The component layer: where a new component or a third theme is bent in one
   place instead of forking a rule. */
:root {
  --token-button-primary-bg: var(--token-color-accent-fill);
  --token-button-primary-fg: var(--token-color-on-accent);
  --token-badge-ok-fg: var(--token-color-state-ok-text);
  --token-badge-ok-bg: var(--token-color-state-ok-bg);
  --token-badge-run-fg: var(--token-color-state-run);
  --token-badge-fail-fg: var(--token-color-state-fail);
  --token-badge-ghost-fg: var(--token-color-state-ghost);
  --token-badge-crit-fg: var(--token-color-state-crit-text);
  --token-badge-crit-bg: var(--token-color-state-crit-bg);
  --token-badge-warn-fg: var(--token-color-state-warn-text);
  --token-badge-warn-bg: var(--token-color-state-warn-bg);
  --token-badge-info-fg: var(--token-color-state-info-text);
  --token-badge-info-bg: var(--token-color-state-info-bg);
  --token-badge-neutral-fg: var(--token-color-state-neutral-text);
  --token-badge-neutral-bg: var(--token-color-state-neutral-bg);
  --token-nav-current-bg: var(--token-color-accent-wash);
  --token-nav-current-fg: var(--token-color-accent-text);
  --token-focus-ring: var(--token-color-text-primary);
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin-400-normal.3b646991d300.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-cyrillic-400-normal.69afad88a074.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-cyrillic-ext-400-normal.e2580ad78906.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin-500-normal.0717336fb31f.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-cyrillic-500-normal.200be3a2a6b1.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-cyrillic-ext-500-normal.08578d906af6.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'E Ukraine';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/e-Ukraine-Regular.e7953d686c52.woff') format('woff');
}
@font-face {
  font-family: 'E UkraineHead';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('/assets/fonts/e-UkraineHead-Regular.ad7a6fa8a4e2.woff') format('woff');
}
/* Component styles for @strim/web.
   Structure mirrors strim-ai-portal/design/design-system.html.

   Not one value is written here. v1 copied the portal's CSS by hand and then
   fixed things in the copy, so the two drifted with nothing to say they had;
   every colour, space, radius, size and duration below is a token from
   src/generated/tokens.css, and scripts/lint-literals.ts fails the build on a
   literal. Only breakpoints stay literal, because custom properties are not
   substituted inside a media query prelude. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
}

/* The @font-face rules are GENERATED, in src/assets/fonts.ts, and prepended to
   this file. They used to sit here pointing at the marketing CDN, which the
   production CSP (`font-src 'self'`) blocked outright — the page rendered in a
   system face and looked merely wrong rather than broken. The faces are served
   from our own origin now, at paths containing their own hash, and a hash is
   not something a static stylesheet can spell. */

html {
  scroll-behavior: smooth;
  /* A little air above an anchor; the header no longer sticks over the page. */
  scroll-padding-top: var(--token-space-4);
  /* The same surface as `body`, so the canvas is never a different colour.
     Only `body` carried one, and anything that repainted past the body box —
     a fast scroll, an overscroll — showed the canvas through as a flash of
     empty background. */
  background: var(--token-color-surface);
}

/* Every scroller, not only the page's: the meeting page scrolls its two
   columns on their own, and they glided to a quoted turn whatever the reader
   had asked of their system. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  * {
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

body {
  /* A long unbroken token in prose — a URL in an analysis, a pasted id — breaks
     rather than widening its box past the page. `break-word` here, not
     `anywhere`: it breaks only what overflows and leaves min-content sizing
     alone, so a button label is never split mid-word to squeeze a row. */
  overflow-wrap: break-word;
  font-family: var(--token-font-body);
  font-weight: var(--token-weight-regular);
  background: var(--token-color-surface);
  color: var(--token-color-text-primary);
  /* 14px, not 16: the interface is tables and lists, and at 16 a ten-column
     row went to two storeys. Prose that needs more gets it where it lives. */
  font-size: var(--token-fs-sm);
  line-height: var(--token-lh-normal);
  -webkit-font-smoothing: antialiased;
  transition: background var(--token-dur-slow) ease, color var(--token-dur-slow) ease;
}

/* Declared on everything that actually changes colour, not just on body:
   otherwise a theme switch repaints the page in pieces. */
.panel,
.badge,
.btn,
.field,
select,
table,
th,
td,
.seg,
.tabs a,
.side,
.side-nav a {
  transition: background var(--token-dur-slow) ease, color var(--token-dur-slow) ease,
    border-color var(--token-dur-slow) ease;
}

h1,
h2,
h3 {
  font-family: var(--token-font-display);
  font-weight: var(--token-weight-regular);
  margin: 0;
  line-height: var(--token-lh-tight);
  text-wrap: balance;
}

p {
  margin: 0;
}

a {
  color: var(--token-color-accent-text);
}

.mono {
  font-family: var(--token-font-mono);
  font-variant-numeric: tabular-nums;
}

/* Visually hidden, still announced. */
.sr {
  position: absolute;
  width: var(--token-size-hidden);
  height: var(--token-size-hidden);
  margin: calc(var(--token-size-hidden) * -1);
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: var(--token-layout-offscreen);
  top: 0;
  /* Above the sticky header, or the first Tab focuses something invisible. */
  z-index: var(--token-z-skip);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  padding: var(--token-space-3) var(--token-space-4);
  border-radius: 0 0 var(--token-radius-sm) 0;
}

.skip:focus {
  left: 0;
}

:where(a, button, input, select, summary, [tabindex]):focus-visible {
  /* text-primary, not the accent: on a segment already filled with the accent
     an accent ring disappeared into its own background in the light theme. */
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-thick);
  border-radius: var(--token-radius-sm);
}

/* ------------------------------------------------------------- app chrome */

/* «Робочий стіл»: the navigation down the side, the page at full width beside it.

   The header bar it replaces held the page to 1080px and stacked a second row
   for a product's own pages, so every page began a hundred pixels down and a
   ten-column table wrapped every cell. The side column holds the brand, the
   platform's items with the current section's pages nested under its item, and
   at the foot the theme, the language and the account. */
.app {
  display: grid;
  grid-template-columns: var(--token-layout-sidebar) minmax(0, 1fr);
  min-height: 100vh;
}

.side {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  padding: var(--token-space-4) var(--token-space-3);
  background: var(--token-color-surface-raised);
  border-right: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.brand {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  text-decoration: none;
  color: var(--token-color-text-primary);
  padding: 0 var(--token-space-2) var(--token-space-4);
}

.brand .dot {
  width: var(--token-size-dot);
  height: var(--token-size-dot);
  border-radius: 50%;
  background: var(--token-color-accent-fill);
}

.side-nav {
  display: flex;
  flex-direction: column;
  gap: var(--token-gap-hair);
}

.side-nav a {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  min-height: var(--token-size-nav-row);
  padding: 0 var(--token-space-2);
  border-radius: var(--token-radius-sm);
  color: var(--token-color-text-secondary);
  text-decoration: none;
}

/* A product's glyph before its name. */
.side-icon {
  width: var(--token-space-4);
  height: var(--token-space-4);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.side-nav a:hover {
  background: var(--token-color-surface-inset);
  color: var(--token-color-text-primary);
}

/* Current by colour and ground, never by weight: a medium item in a column of
   regular ones shifted the whole list's rhythm and read as a heading. */
.side-nav a[aria-current='page'] {
  background: var(--token-nav-current-bg);
  color: var(--token-nav-current-fg);
}

/* The section's name heading its pages — a product, under the catalogue. */
.side-nav .side-product {
  color: var(--token-color-text-primary);
  margin-top: var(--token-space-2);
}

.side-sub {
  display: flex;
  flex-direction: column;
  gap: var(--token-gap-hair);
  padding-left: var(--token-space-5);
}

/* «ПРОДУКТИ»: the small caps label over the products group, as the approved
   layout draws it. */
.side-label {
  margin: var(--token-space-5) 0 var(--token-space-1);
  padding: 0 var(--token-space-2);
  font-size: var(--token-fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

/* A labelled group of pages (the admin area) sits flush, not indented. */
.side-sub-flat {
  padding-left: 0;
}

/* The product whose pages are open: its name in the text colour, its pages
   nested under it. */
.side-nav .side-product-current {
  color: var(--token-color-text-primary);
}

/* A product announced and not built: drawn, dimmed, not a link. */
.side-soon {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  min-height: var(--token-size-nav-row);
  padding: 0 var(--token-space-2);
  color: var(--token-color-text-tertiary);
}

.side-count {
  margin-left: auto;
  padding: 0 var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-state-neutral-bg);
  color: var(--token-color-state-neutral-text);
  font-size: var(--token-fs-xs);
}

/* The admin area, at the foot of the column above theme and account — on the
   same left edge as the items above, not indented by the foot's own inset. */
.side-foot-nav {
  margin: 0 calc(var(--token-space-2) * -1) var(--token-space-1);
}

/* Theme, language and account sit at the bottom, out of the way: they are
   changed once, and in the old header they had the prime spot on every page. */
.side-foot {
  margin-top: auto;
  padding: var(--token-space-3) var(--token-space-2) 0;
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
}

.side-foot .ctrl {
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-1);
}

/* Three theme options across the column's width, not wrapped onto two lines. */
.side-foot .seg {
  display: flex;
  flex-wrap: nowrap;
}

.side-foot .seg button,
.side-foot .seg a {
  flex: 1 1 auto;
  padding: var(--token-space-1) var(--token-space-2);
  text-align: center;
}

/* The signed-in account.
 *
 * `min-width: 0` is what lets a long address give way instead of pushing the
 * sign-out link out of the column; the whole value stays in `title`. */
.acct {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  min-width: 0;
}

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

.acct .linkish,
.acct form {
  flex: none;
}

.avatar {
  width: var(--token-size-avatar);
  height: var(--token-size-avatar);
  flex: none;
  border-radius: 50%;
  background: var(--token-color-accent-fill);
  color: var(--token-color-on-accent);
  display: grid;
  place-items: center;
  font-size: var(--token-fs-xs);
}

.linkish {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--token-color-accent-text);
}

/* In-page tabs: an underline under the current one, the count beside the name.
   Current by colour and rule, not by weight. */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-6);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tabs a {
  color: var(--token-color-text-secondary);
  text-decoration: none;
  padding: var(--token-space-3) 0;
  margin-bottom: calc(var(--token-border-hair) * -1);
  border-bottom: var(--token-border-thick) solid transparent;
}

.tabs a:hover {
  color: var(--token-color-text-primary);
}

.tabs a[aria-current='page'] {
  color: var(--token-color-text-primary);
  border-bottom-color: var(--token-color-accent-fill);
}

/* A phone or a narrow window: the side column becomes a block above the page
   rather than squeezing it. Nothing is hidden behind a menu button — the
   frame's script only adds (the fold, the toasts, the current item scrolled
   into view), and a nav that needs a script to open is a nav the keyboard
   cannot reach when the script fails. Only under 760px: at a narrow
   laptop window (820) the column still fits beside a 570px page. */
/* The phone layout of the frame is at the END of this file, so the
   later base rules for `.side` and its parts cannot override it. */

/* -------------------------------------------------------- choose-exactly-one */

.ctrl {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

/* ONE rule, unscoped. It was declared three times — `.ctrl > .lbl`,
   `.radios > .lbl`, `.control > .lbl, .field > .lbl` — and a label anywhere
   else matched none of them: four in the admin area rendered at body size in
   the primary colour, beside identical-looking labels at fs-xs. A shared class
   that only works under certain parents is not a shared class. */
.lbl {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
  padding: 0;
}

.seg {
  display: inline-flex;
  /* Wraps rather than running off a narrow screen: the result tabs on a meeting
     grow with every analysis, and one row of them was wider than a phone. */
  flex-wrap: wrap;
  max-width: 100%;
  background: var(--token-color-surface-sunken);
  border-radius: var(--token-radius-sm);
  padding: var(--token-inset-chip);
  gap: var(--token-gap-hair);
}

.seg button,
.seg a {
  font: inherit;
  font-size: var(--token-fs-xs);
  /* Transparent rather than absent, so lifting the chosen one below does not
     move every other segment by a hairline. */
  border: var(--token-border-hair) solid transparent;
  background: transparent;
  color: var(--token-color-text-secondary);
  padding: var(--token-space-1) var(--token-space-3);
  border-radius: var(--token-radius-sm);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}

.seg button:hover,
.seg a:hover {
  color: var(--token-color-text-primary);
}

/* The chosen segment is RAISED OUT of the track, not painted over it.
 *
 * The metaphor the control already has is a groove with a tile sliding along
 * it, and an accent-filled tile reads as a button instead — two of them side by
 * side looked like one lozenge cut in half rather than a choice with one option
 * taken. Lifting the surface colour keeps the accent for things that are
 * actions. */
.seg button[aria-pressed='true'],
.seg a[aria-current='true'] {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  border-color: var(--token-color-border-subtle);
}

/* The same choice, made inside a form somebody else opened. A fieldset carries
   the grouping, so its default border and padding are removed rather than
   styled — the row of options is the affordance, not a box around them. */
.radios {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.pick {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  cursor: pointer;
}

/* Native, and visible. A drawn pill with the input hidden is a control nothing
   announces and nobody can tell is selected — the same lesson the access
   matrix's checkboxes are there for. */
input[type='radio'] {
  accent-color: var(--token-color-accent-fill);
  width: var(--token-size-checkbox);
  height: var(--token-size-checkbox);
  cursor: pointer;
  margin: 0;
}

/* ------------------------------------------------------------------ frame */

.wrap {
  /* Full width up to the frame's maximum, left-aligned beside the side column:
     centred, a wide screen put a gutter of nothing between navigation and page. */
  max-width: var(--token-layout-max);
  min-width: 0;
  padding: var(--token-space-8) var(--token-layout-page-pad-x) var(--token-space-24);
}

@media (max-width: 640px) {
  .wrap {
    padding: var(--token-space-5) var(--token-space-4) var(--token-space-16);
  }
}

/* The page's vertical rhythm, in one rule.
 *
 * Every block on a page — a heading, a nav, a card, a table — was responsible
 * for its own bottom margin, which meant most of them had none and a page read
 * as one stuck-together column. Spacing BETWEEN siblings belongs to the thing
 * that owns the sequence, and the last child adds nothing, so a page never ends
 * in a gap. */
.wrap > * + * {
  margin-top: var(--token-space-6);
}

/* The heading already carries its own generous padding; a second gap under it
 * pushes the first block of the page too far down. */
.wrap > .hero + * {
  margin-top: 0;
}

/* A named trail above the title, in place of a bare arrow. The arrow said
   nothing about where it went and left a gap under it the height of a card. */
.crumbs {
  padding: 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.crumbs span[aria-hidden] {
  margin: 0 var(--token-space-2);
}

/* Label above value, in a row that wraps. A buyer and a date printed as two
   bare spans read as one string — «WHO CO Ukraine 2026-09-23T17:00» — and
   neither said which it was. */
.kv {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-4) var(--token-space-8);
  margin: 0;
}

.kv dt {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.kv dd {
  margin: 0;
}

.hero {
  /* Compact. The title was 44px and repeated on every tab of a tender, taking
     about 40% of the first screen before any content; the page's own frame now
     starts at the top, so the heading needs no padding above it at all. */
  padding: 0 0 var(--token-space-2);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--token-space-6);
  flex-wrap: wrap;
}

/* The action stays with the title on a wide screen and drops below it on a
 * narrow one, where a button squeezed beside a wrapping heading is worse than
 * a button underneath. */
.hero-action {
  flex: none;
  padding-top: var(--token-space-1);
}

.hero h1 {
  font-size: var(--token-fs-xl);
}

.lede {
  margin-top: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
  max-width: var(--token-measure-lede);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  margin-top: var(--token-space-3);
  padding: var(--token-space-1) var(--token-space-3);
  border-radius: var(--token-radius-pill);
  background: var(--token-badge-info-bg);
  font-size: var(--token-fs-xs);
  color: var(--token-badge-info-fg);
}

.pill .dot {
  width: var(--token-size-dot-sm);
  height: var(--token-size-dot-sm);
  border-radius: 50%;
  background: var(--token-color-accent-text);
}

section {
  padding-top: var(--token-space-10);
}

.sec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-2) var(--token-space-4);
  margin-bottom: var(--token-space-4);
}

/* Inside a grid the gap already provides the space below a heading; the
   margin was adding a second helping, so a group heading sat noticeably
   further from its table than every other heading on the page. */
.grid > .sec-head {
  margin-bottom: 0;
}

.sec-head .num {
  font-size: var(--token-fs-xs);
  color: var(--token-color-accent-text);
}

.sec-head h2 {
  font-size: var(--token-fs-lg);
}

/* The explanation goes UNDER the heading, on the left, at reading width.

   Right-aligned beside it, a three-line sentence was a ragged block that the
   eye met from the wrong side on every section; left-aligned but still beside
   the heading, its four lines each started at a different x while the heading,
   the filters and the table under them all started at the same one. Under the
   heading it starts where they do. */
.sec-head .note {
  order: 10;
  /* The full row, so it always drops under the heading — a max-width here would
     cap the basis and let it sit beside the title again — with the reading
     measure kept by padding on the right instead. */
  flex: 0 0 100%;
  padding-right: max(0%, calc(100% - var(--token-measure-lede)));
  text-align: left;
}

.foot {
  margin-top: var(--token-space-24);
  padding-top: var(--token-space-5);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* ------------------------------------------------------------- containers */

.grid {
  display: grid;
  gap: var(--token-space-4);
}

/* `min(…, 100%)` is what stops a grid overflowing its container.
 *
 * `minmax(300px, 1fr)` is not a maximum of 300px — it is a FLOOR, so on a
 * viewport narrower than one column the track keeps its 300px and the row runs
 * off the side of the page. Capping the floor at the container's own width
 * lets the last column shrink instead. */
.grid-card {
  grid-template-columns: repeat(auto-fit, minmax(min(var(--token-layout-card-min), 100%), 1fr));
}

.grid-panel {
  grid-template-columns: repeat(auto-fit, minmax(min(var(--token-layout-panel-min), 100%), 1fr));
  /* Each panel takes its own height. Stretched to the tallest in the row, a
     short one — the readiness score is a number and a line — became a large
     empty plate beside the executive summary. Tiles keep stretching; they hold
     one figure each and look wrong ragged. */
  align-items: start;
}

/* Stat tiles are not panels: at the panel minimum four tiles fell into three
   columns and the fourth was orphaned on its own row. */
.grid-stat {
  grid-template-columns: repeat(auto-fit, minmax(min(var(--token-layout-stat-min), 100%), 1fr));
}

/* Inside a panel on a phone the full minimum left room for one tile per row, so
   five figures became five screen-wide boxes; two to a row is still readable. */
@media (max-width: 640px) {
  .grid-stat {
    grid-template-columns: repeat(auto-fit, minmax(min(calc(var(--token-layout-stat-min) * 0.75), 100%), 1fr));
  }
}

.panel {
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  padding: var(--token-space-5);
}

/* A panel's own vertical rhythm, the same rule `.wrap` has for the page.
 *
 * Panels hold paragraphs, and `p` has no margin, so a description and the
 * button under it, or a status line and the sentence after it, sat flush
 * against each other — the stuck-together look the import panel was reported
 * for. The caption brings its own space below, so the block after it adds none. */
.panel > * + * {
  margin-top: var(--token-space-3);
}

.panel > .cap + * {
  margin-top: 0;
}

/* A headline figure (the design system's `.stat`): the number large, its name
   under it. A tile is a smaller box than a panel, so it gets less padding. */
.stat {
  padding: var(--token-space-4);
}

/* A figure that is the point of its card, for a panel that is not a `.stat`.
 *
 * The tenders counters draw their own panels and set the number in the mono
 * body face — the smallest thing on the page, under a heading several times
 * its size. `.stat .n` is the same treatment and only works inside a stat
 * tile; this is that treatment, available to anything. */
.figure {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-xl);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
  margin: 0;
}

.stat .n {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-xl);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
}

.panel.stat > .l {
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* Declared standalone, not as `.panel > .cap`. The design system scopes these
   to a parent, so used anywhere else they did nothing at all and every piece of
   secondary text rendered as full-size body copy. */
.cap {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  margin-bottom: var(--token-space-3);
}

/* The same label INSIDE a row keeps no block margin.

   `.kit` centres its children, so the margin-bottom above pushed the label up
   off the baseline of everything beside it: the analysis panel read «Рішення»
   sitting visibly higher than the time next to it, and the protocol panel did
   the same with its format name. The margin is for a label stacked above the
   thing it names, which is the other half of what `.cap` is used for. */
.kit > .cap {
  margin-bottom: 0;
}

/* A generated document read in place: the protocol, as its own markdown says it.

   Its headings start at h3 — the page owns h1 and the section owns h2 — so they
   are sized here rather than inheriting the document-outline sizes, which would
   have made a protocol's first heading look like a second page title. */
.doc {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
}

.doc h3 {
  font-size: var(--token-fs-lg);
  margin: var(--token-space-2) 0 0;
}

.doc h4,
.doc h5,
.doc h6 {
  font-size: var(--token-fs-md);
  margin: var(--token-space-2) 0 0;
}

.doc p {
  margin: 0;
}

.doc ul {
  margin: 0;
  padding-inline-start: var(--token-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
}

.note {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
}

.desc {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

/* Something went wrong on OUR side, said as one line rather than a table of
   reasons: the import's «не вдалося обробити». Louder than a note, and marked
   at the edge so it is not read as one more figure. */
.warn-line {
  font-size: var(--token-fs-sm);
  color: var(--token-color-state-warn-text);
  background: var(--token-color-state-warn-bg);
  border-radius: var(--token-radius-sm);
  padding: var(--token-space-2) var(--token-space-3);
}

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--token-space-3);
  text-align: center;
  padding: var(--token-space-10) var(--token-space-4);
}

.empty h3 {
  font-size: var(--token-fs-lg);
}

.empty p {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  max-width: var(--token-measure-prose);
}

/* ----------------------------------------------------------------- status */

/* State is colour, icon and word together (badge.ts says why). The pill shape
   belongs to state alone: buttons are `radius-sm`, so a chip and an action are
   never the same shape. Regular weight — the colour is the emphasis. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  min-height: var(--token-size-badge);
  font-size: var(--token-fs-xs);
  line-height: var(--token-lh-tight);
  padding: 0 var(--token-space-2);
  border-radius: var(--token-radius-pill);
  white-space: nowrap;
}

.badge-icon {
  width: var(--token-size-badge-icon);
  height: var(--token-size-badge-icon);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.b-crit {
  background: var(--token-badge-crit-bg);
  color: var(--token-badge-crit-fg);
}

.b-warn {
  background: var(--token-badge-warn-bg);
  color: var(--token-badge-warn-fg);
}

.b-ok {
  background: var(--token-badge-ok-bg);
  color: var(--token-badge-ok-fg);
}

.b-info {
  background: var(--token-badge-info-bg);
  color: var(--token-badge-info-fg);
}

.b-neutral {
  background: var(--token-badge-neutral-bg);
  color: var(--token-badge-neutral-fg);
}

/* The page's verdict, not a state in a list.
 *
 * `badge.ts` is right that a chip carries state by treatment rather than hue,
 * and it gives the fill to success on purpose. This is a different thing: one
 * sentence saying whether a proposal can be submitted at all, which was drawn
 * as the same small dashed outline as every severity below it. */
.verdict {
  border-radius: var(--token-radius-md);
  padding: var(--token-space-5) var(--token-space-6);
  margin: var(--token-space-6) 0;
  background: var(--token-color-surface-inset);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.verdict-title {
  margin: 0 0 var(--token-space-1);
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  font-weight: var(--token-weight-regular);
}

/* A blocked submission is the one thing on the page that should stop the eye,
   so it takes the critical ground, not a grey plate with a coloured edge. */
.verdict-blocked,
.verdict-blocked_pending_verification {
  background: var(--token-color-state-crit-bg);
  border-color: transparent;
}

.verdict-blocked .verdict-title,
.verdict-blocked_pending_verification .verdict-title {
  color: var(--token-color-state-crit-text);
}

.verdict-clear {
  background: var(--token-color-state-ok-bg);
  border-color: transparent;
}

.verdict-clear .verdict-title {
  color: var(--token-color-state-ok-text);
}

/* ----------------------------------------------------------------- tables */

/* Nothing scrolls sideways. Content fits the column it is given instead.

   These boxes used to scroll their overflow, on the reasoning that a table of
   ids, models and timestamps reads worse wrapped than scrolled. In use it read
   worse scrolled: the access matrix and the usage tables were a scrollbar away
   from their last column at ordinary widths, and a table whose right edge you
   have to go and find is a table people stop reading past the middle.

   So the table is made to fit: headers may wrap, and a cell's unbroken token —
   an address, a model id, a URL — breaks wherever it has to (`td` below).
   The boxes do not scroll. A bare `.scroller` keeps `overflow` visible, so
   what still does not fit shows past the edge; inside a `.panel` (below,
   «A card that holds a table») the panel hides its overflow to round its
   corners, so there it is CLIPPED — a column cut off with no way to reach it,
   which the 820/1440 sweep in review exists to catch.

   `min-width: 0` lets a box shrink inside a grid or flex parent below the width
   of its widest unbroken content, which is what makes the breaking happen. */
.scroller,
.panel {
  min-width: 0;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--token-fs-sm);
}

caption {
  text-align: left;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  padding-bottom: var(--token-space-3);
}

th {
  text-align: left;
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
  padding: 0 var(--token-space-4) var(--token-space-2) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  /* Headers wrap. A column is as wide as its header when the cells are ticks or
     short numbers, and held to one line, "Пошук по документах" beside
     "Тендери: адмін" made the access matrix wider than the page. A table
     auto-sizes, so a header only breaks when the row genuinely needs the room. */
  white-space: normal;
  /* Bottom, so a header that wraps onto two lines keeps its last line level
     with the one-line headers beside it. */
  vertical-align: bottom;
}

td {
  /* `break-word`, NOT `anywhere`.
     `anywhere` counts toward the column's minimum width — which is what it was
     chosen for, so a long URL could narrow its column instead of pushing the
     table past the page. The cost was every other word: with a one-character
     minimum the browser shrank every column as far as it liked, and ordinary
     words came apart mid-word. A ten-column table read «Prozor / ro»,
     «Націона / льний», «RE / Q- / 00 / 5».
     `break-word` breaks a word only when that word alone does not fit its
     line, and leaves min-content sizing to whole words, so the columns keep
     their natural width. The cells that really do hold unbreakable strings —
     ids, addresses, provider messages — ask for `anywhere` by class below. */
  overflow-wrap: break-word;
  padding: var(--token-space-3) var(--token-space-4) var(--token-space-3) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  vertical-align: middle;
}

tr:last-child td {
  border-bottom: 0;
}

th:last-child,
td:last-child {
  padding-right: 0;
}

/* A numeric column: the CELL gets tabular figures so digits line up down the
 * column, the HEADER gets only the alignment.
 *
 * Giving the header the cell's typeface too is what made a header row read as
 * ragged — three words in the body font and one in mono, at the top of a table
 * whose whole job is to be scanned across. */
/* Tabular figures in the body face, not mono: a column of mono numbers beside
   Plex text was the ragged look the design review called out. */
td.num {
  font-variant-numeric: tabular-nums;
}

/* The row's name — the first column's link — is the one medium thing in a row.
   Ink rather than accent: a column of purple titles read as a list of links to
   somewhere else rather than as the rows themselves. */
tbody td:first-child a:not(.btn),
tbody td:first-child .row-title {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
  text-decoration: none;
}

tbody td:first-child a:not(.btn):hover {
  color: var(--token-color-accent-text);
  text-decoration: underline;
}

td.num,
th.num {
  text-align: right;
}

/* Kept whole, against the `anywhere` every other cell has: "123 456" broken into
   "123 45 / 6" is a different number to anyone scanning the column, and a tick
   cell holds nothing that could break anyway. These columns are narrow; the
   text and id columns beside them give up the width instead. */
td.num,
td.tick {
  overflow-wrap: normal;
  white-space: nowrap;
}

/* A note under a tick ("частково") keeps its own line; on one line with the box
   it read as the box's label. */
td.tick .note {
  display: block;
}

/* Allowed to wrap, like every cell: a nowrap mono column was the widest thing in
   the access matrix as soon as one address was long.

   And `break-word` here too, like every other cell: `anywhere` on the mono
   column is what broke «REQ-005» into «RE / Q- / 00 / 5» — the ids it was meant
   to protect are exactly the strings it took apart. A genuinely unbreakable
   address now widens the table; nothing scrolls it (see «Nothing scrolls
   sideways» above). */
td.mono {
  font-family: var(--token-font-mono);
}

/* The row under a row: a failure reason, a quote, an empty state. A cell inside
   the row would either widen the table past the viewport or clip the one string
   the page exists to show. Ids and provider messages have no spaces to break
   on, hence `anywhere`. */
td.detail {
  padding-top: 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  white-space: normal;
  overflow-wrap: anywhere;
}

/* LEFT, like every other column on the table it appears in.

   Both the heading and the box were centred, so they lined up with each other
   and with nothing else: a wide heading («Адмін платформи») with a small box
   under its middle, in a row of columns that all start at their own left edge.
   The values read as shifted against their headings — which is exactly what it
   was. Centring is right when a column is a narrow tick under a narrow word;
   this one is neither. */
td.tick,
th.tick {
  text-align: left;
}

/* Widths from the columns, not from their content, so every table on a page
   with the same columns lines up: the meetings list draws one table per group,
   and each used to size itself, leaving «Коли» and «Стан» a few characters to
   one side in one group and to the other in the next. */
table.fixed {
  table-layout: fixed;
}

/* Not on a phone: a fixed table there squeezed the one free column — the
   meeting's title — to a letter or two per line. A fixed table stacks into
   cards on a narrow screen instead, so its widths have nothing to do. */
@media (max-width: 640px) {
  table.fixed {
    table-layout: auto;
  }
}

col.w-when {
  width: var(--token-measure-col-when);
}

col.w-duration {
  width: var(--token-measure-col-duration);
}

col.w-action {
  width: var(--token-measure-col-action);
}

/* accent-color tints the native control with the brand and keeps the platform's
   own affordance — obviously clickable, obviously ticked — instead of drawing a
   replacement that only looks like one. */
input[type='checkbox'] {
  accent-color: var(--token-color-accent-fill);
  width: var(--token-size-checkbox);
  height: var(--token-size-checkbox);
  cursor: pointer;
  margin: 0;
}

.tickbox {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  cursor: pointer;
}

/* A visible label in a matrix column still has to be readable, so it gets a
   floor. The hidden variant is excluded: it is out of the flow already, and a
   width on it would be a claim about space nothing occupies. */
td.tick .tickbox .tick-label {
  min-width: var(--token-measure-cell);
  text-align: center;
}

/* ------------------------------------------------------------------ forms */

form.stack {
  display: grid;
  gap: var(--token-space-3);
}

/* inline-flex, not inline: a form holding a control and a button laid them out
   as two blocks, so the select sat above the button instead of beside it. */
form.inline {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

/* A select and its button wrap on a phone: the import control (a depth choice
   and «Підтягнути з Google») was wider than 360px and pushed the whole page
   sideways. Only this shape — a form with a text field wrapped at every width,
   because the field's flex basis is wider than the form's own content size. */
form.inline:has(> .control) {
  flex-wrap: wrap;
  max-width: 100%;
}

/* A field that belongs to ONE radio, hidden while that radio is unchecked.

   The analysis form has five lenses and one question box, and only «Своє
   питання» reads it: under the other four the box was typeable and its contents
   were dropped. `radioGroup` marks that radio `data-reveals` and the field is
   marked `data-revealed`, so the link is in the markup rather than in a rule
   that would have to know what a lens is.

   No script, on purpose — this app's forms work without one. Where `:has()` is
   not supported nothing matches and the field stays visible, which is exactly
   what every browser did before this rule existed. */
form:has(input[data-reveals]):not(:has(input[data-reveals]:checked)) [data-revealed] {
  display: none;
}

.kit {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-3);
  align-items: center;
}

/* A toolbar standing in for a section's heading gets the heading's space below
   it. Without it the meetings search row sat directly on the first group's
   title, with none of the gap every other heading on the page has. */
section > .kit:first-child {
  margin-bottom: var(--token-space-8);
}

.control {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
}

/* The label ABOVE the input, not beside it.
 *
 * It used to share the line, inside the same bordered box and under the same
 * `max-width`, so a long label left the input a few characters: the tender
 * settings showed «260923_WHO_Technical Assi» and «https://zakupivli.pro/c»,
 * and New Tender cut its own placeholder to «e.g. Provis». `.field-tall`
 * already stacked for exactly this reason; single-line fields have the same
 * problem whenever their value is longer than the leftovers. */
.field {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-1);
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  padding: var(--token-space-2) var(--token-space-3);
  /* A minimum rather than a fixed width: pinned, it slid off a 320px screen. */
  min-width: 0;
  flex: 1 1 var(--token-layout-field-basis);
  max-width: var(--token-layout-field-max);
}

/* A field holding a textarea stacks instead of sitting on one line, and takes
   the width it is given rather than the single-line basis. */
.field-tall {
  flex-direction: column;
  align-items: stretch;
  flex-basis: auto;
  max-width: none;
}

.field-tall textarea {
  font: inherit;
  font-size: var(--token-fs-sm);
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--token-color-text-primary);
  width: 100%;
  min-width: 0;
  resize: vertical;
}

.field-tall textarea::placeholder {
  color: var(--token-color-text-tertiary);
}

.field:focus-within {
  border-color: var(--token-color-accent-text);
}

.field input {
  font: inherit;
  font-size: var(--token-fs-sm);
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--token-color-text-primary);
  width: 100%;
  min-width: 0;
}

.field input::placeholder {
  color: var(--token-color-text-tertiary);
}

/* A bare <select> brings its own border and background from the platform, so
   putting one inside .field draws two boxes around one control. It is styled
   directly instead, caret included. */
select {
  font: inherit;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  padding: var(--token-space-2) var(--token-space-8) var(--token-space-2) var(--token-space-3);
  appearance: none;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-size: var(--token-size-caret) var(--token-size-caret),
    var(--token-size-caret) var(--token-size-caret);
  background-position: right var(--token-space-4) center,
    right calc(var(--token-space-4) - var(--token-size-caret)) center;
  background-repeat: no-repeat;
}

.btn {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-regular);
  line-height: var(--token-lh-snug);
  padding: var(--token-space-2) var(--token-space-4);
  /* radius-sm, not a pill: the pill is state's shape, and a button that looked
     like a chip was a thing people did not press. */
  border-radius: var(--token-radius-sm);
  border: var(--token-border-hair) solid transparent;
  cursor: pointer;
  /* A label split mid-word ("Збер / егти") stops reading as a button. A table
     cell that may break anywhere will otherwise squeeze one to do exactly that. */
  white-space: nowrap;
  overflow-wrap: normal;
}

/* Every .btn in the design system is a <button>, so underlines never came up.
   Here some of them have to be links, and links arrive underlined. */
a.btn {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}

.btn-primary {
  background: var(--token-button-primary-bg);
  color: var(--token-button-primary-fg);
  /* The one medium control on a page: the thing to do. */
  font-weight: var(--token-weight-medium);
}

/* Mixing towards text-primary self-corrects per theme: hover always moves
   towards the foreground, dark or light. */
.btn-primary:hover {
  background: color-mix(in srgb, var(--token-button-primary-bg) 84%, var(--token-color-text-primary));
}

.btn-ghost {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  border-color: var(--token-color-border-strong);
}

.btn-ghost:hover {
  background: var(--token-color-surface-inset);
}

.btn-quiet {
  background: transparent;
  color: var(--token-color-accent-text);
}

.btn[disabled] {
  color: var(--token-color-text-tertiary);
  border-color: var(--token-color-border-subtle);
  cursor: not-allowed;
}

.btn-block {
  width: 100%;
  justify-content: center;
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  margin-top: var(--token-space-5);
}

/* -------------------------------------------------------------- secondary */

/* Wanted rarely, so not a heading and not a panel: a line you see only when
   you are looking for it. */
.log {
  display: grid;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
}

.log > summary {
  cursor: pointer;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  padding: var(--token-space-2) 0;
  list-style: none;
}

/* The arrow is drawn here: ::marker cannot be styled in Safari, and
   ::-webkit-details-marker leaves its own in place, so without list-style:none
   there would be two. */
.log > summary::before {
  content: '▸ ';
}

.log[open] > summary::before {
  content: '▾ ';
}

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

.log > summary:hover {
  color: var(--token-color-text-primary);
}

.log[open] > summary {
  color: var(--token-color-text-secondary);
}

.pager {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  margin-top: var(--token-space-4);
}

/* Where you are in the whole list goes at the end of the row, away from the
   controls that move you through it. */
.pager .note {
  margin-left: auto;
}

/* ------------------------------------------------------------- responsive */

/* A table that opts in (`stackOnNarrow`, table.ts) becomes a list of cards on a
 * narrow screen.
 *
 * Each row stacks, and every cell shows its column's name from `data-label`
 * beside its value. The header row stays for assistive tech and is hidden from
 * sight the way `.sr` hides text, since the labels now repeat it per cell.
 *
 * 900px, not 640: the threshold was one number for every table, and these run
 * from three columns to ten. Ten columns at 814px — a laptop with the side
 * panel open — was still a table, so it left its card and its cells were
 * crushed to a syllable each: `Requirement Text` at ~150px, one requirement
 * thirty lines tall, and a mono `REQ-005` broken between its letters.
 *
 * Cards rather than a sideways scroll, because this file already tried the
 * scroll and took it back out (see the tables section): a table whose right
 * edge you have to go and find is one people stop reading past the middle. */
@media (max-width: 900px) {
  .stack table,
  .stack caption,
  .stack tbody,
  .stack tr,
  .stack td {
    display: block;
    width: 100%;
  }
  .stack thead {
    position: absolute;
    width: var(--token-size-hidden);
    height: var(--token-size-hidden);
    overflow: hidden;
    clip-path: inset(50%);
  }
  .stack tr {
    padding: var(--token-space-3) 0;
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }
  .stack td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--token-space-4);
    padding: var(--token-space-1) 0;
    border-bottom: 0;
  }
  .stack td[data-label]::before {
    content: attr(data-label);
    flex: none;
    max-width: 50%;
    /* A number cell is mono; its label is not a number. */
    font-family: var(--token-font-body);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }
  .stack td > .cv {
    min-width: 0;
    text-align: right;
  }
  .stack td.detail {
    display: block;
  }
}

/* The same cards by the TABLE's own width, not only the window's. With the
   side panel open a 1024px laptop gives a card about 700px wide, the window is
   still «wide», and an eight- or ten-column table either left its card (the
   last columns cut off by the card's edge) or squeezed a column to 16px with
   its words a letter a line. Under 860px of its own the table is cards. */
.scroller.stack {
  container-type: inline-size;
}

@container (max-width: 860px) {
  .stack table,
  .stack caption,
  .stack tbody,
  .stack tr,
  .stack td {
    display: block;
    width: 100%;
  }
  .stack thead {
    position: absolute;
    width: var(--token-size-hidden);
    height: var(--token-size-hidden);
    overflow: hidden;
    clip-path: inset(50%);
  }
  .stack tr {
    padding: var(--token-space-3) 0;
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }
  .stack td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--token-space-4);
    padding: var(--token-space-1) 0;
    border-bottom: 0;
  }
  .stack td[data-label]::before {
    content: attr(data-label);
    flex: none;
    max-width: 50%;
    /* A number cell is mono; its label is not a number. */
    font-family: var(--token-font-body);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }
  .stack td > .cv {
    min-width: 0;
    text-align: right;
  }
  .stack td.detail {
    display: block;
  }
}

@media (max-width: 640px) {
  .sec-head {
    flex-wrap: wrap;
  }
  .sec-head .note {
    margin-left: 0;
    text-align: left;
    max-width: none;
    flex-basis: 100%;
  }
}

/* People export the quota and cost tables to PDF. The generated tokens force
   the light palette for print; what is left is hiding the parts of the page
   that are navigation rather than content. */
@media print {
  .chrome,
  .side,
  .skip,
  .seg,
  .ctrl,
  .kit,
  .pager,
  .btn,
  .log > summary {
    display: none !important;
  }
  a {
    text-decoration: underline;
  }
  .app {
    display: block;
  }
}

/* A sortable column header.
 *
 * It is a link, so it inherits the focus ring and the keyboard behaviour every
 * other link already has — a header that only responded to a click would be
 * unreachable without a mouse. It stays the colour of the header text rather
 * than the accent, because a whole row of accent-coloured headings reads as a
 * navigation bar. */
th .sort {
  color: inherit;
  text-decoration: none;
}

th .sort:hover {
  color: var(--token-color-text-primary);
  text-decoration: underline;
}

/* The bar behind a score.
 *
 * A `<meter>` would style itself differently in every browser, so it is two
 * elements with a token-driven width. The number stays next to it in the markup:
 * the bar is the comparison, the number is the value, and a bar alone cannot be
 * read out. */
.meter {
  display: block;
  width: 100%;
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

.meter > span {
  display: block;
  height: 100%;
  background: var(--token-color-accent-fill);
}

/* A section's action sits at the end of the heading row, after the note that
 * may or may not be there. */
.sec-action {
  margin-left: auto;
  flex: none;
}

/* The sign-in card is as wide as what it holds.

   It stretched the whole content column for one button and one line, so the
   panel's own padding read as a hairline against a very wide block — reported
   as the button being pressed against the left edge. The padding did not
   change; the block did. */
.login-card {
  max-width: var(--token-measure-note);
  padding: var(--token-space-6);
}

.login-card > * + * {
  margin-top: var(--token-space-4);
}

/* =====================================================================
   THE APPROVED LAYOUT, TO THE PIXEL.

   Every value below is read off the approved canvas (UvVSBD5ZToUcp375uaE3Te)
   and named in tokens.json (scale.layout, radius.seg*, font-size 2xs…h1), so
   the application and the mockup are the same drawing. It sits last and uses
   the same selectors as the rules above, which it supersedes: the earlier
   rules carry the reasons, these carry the measurements.
   ===================================================================== */

/* ---- the side column ---- */
.side {
  padding: var(--token-layout-side-pad-y) var(--token-layout-side-pad-x);
  gap: 0;
}

.brand {
  font-size: var(--token-fs-brand);
  gap: var(--token-layout-brand-gap);
  padding: 0 var(--token-layout-item-pad-x) var(--token-layout-brand-pad-bottom);
  line-height: var(--token-lh-tight);
}

.brand .dot {
  width: var(--token-layout-dot);
  height: var(--token-layout-dot);
}

.side-nav {
  gap: var(--token-layout-hair-gap);
}

.side-nav a,
.side-soon {
  min-height: 0;
  height: var(--token-size-nav-row);
  padding: 0 var(--token-layout-item-pad-x);
  gap: var(--token-layout-brand-gap);
  font-size: var(--token-fs-sm);
  border-radius: var(--token-radius-sm);
}

.side-label {
  margin: 0;
  padding: var(--token-layout-label-pad-top) var(--token-layout-item-pad-x) var(--token-layout-label-pad-bottom);
  font-size: var(--token-fs-2xs);
  letter-spacing: 0.06em;
}

/* The product one is inside: its name in ink, medium — the one heading in the
   column — and its pages indented under it. */
.side-nav .side-product-current {
  color: var(--token-color-text-primary);
  font-weight: var(--token-weight-medium);
}

.side-nav .side-product-current:hover {
  background: var(--token-color-surface-inset);
}

.side-sub {
  gap: var(--token-layout-hair-gap);
  padding-left: var(--token-layout-sub-indent);
  margin-left: 0;
}

.side-sub-flat {
  padding-left: 0;
}

/* An announced product is named and dimmed, nothing more. */
.side-soon {
  display: flex;
  align-items: center;
  color: var(--token-color-text-tertiary);
}

/* «скоро» as the board draws it: a small neutral pill at the row's far end. */
.side-soon .side-count {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
  height: var(--token-layout-pill-h-sm);
  padding: 0 var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-state-neutral-bg);
  color: var(--token-color-state-neutral-text);
  font-size: var(--token-fs-2xs);
  line-height: 1;
  flex: none;
}

.side-foot {
  padding: 0;
  border-top: 0;
  gap: 0;
}

.side-foot-nav {
  margin: 0 0 var(--token-layout-brand-gap);
}

.acct {
  gap: var(--token-layout-brand-gap);
  padding: var(--token-space-3) var(--token-layout-item-pad-x) 0;
  margin-top: var(--token-layout-brand-gap);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.acct-who {
  color: var(--token-color-text-primary);
  font-weight: var(--token-weight-medium);
}

.avatar {
  width: var(--token-layout-avatar);
  height: var(--token-layout-avatar);
}

/* ---- the page ---- */
.wrap {
  max-width: none;
  padding: var(--token-layout-page-pad-y) var(--token-layout-page-pad-x) var(--token-space-16);
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
}

.wrap > * + *,
.wrap > .hero + * {
  margin-top: 0;
}

.hero {
  padding: 0;
  align-items: flex-end;
  gap: var(--token-space-4);
}

.hero h1 {
  font-size: var(--token-fs-h1);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.hero-action {
  padding-top: 0;
}

.lede {
  margin: calc(var(--token-space-1) * 1.5) 0 0;
  font-size: var(--token-fs-sm);
  line-height: var(--token-lh-normal);
}

/* A section on the page is one more block in the column, not a page of its own. */
section {
  padding-top: 0;
}

section > .kit:first-child {
  margin-bottom: var(--token-layout-block-gap);
}

/* ---- surfaces ---- */
.panel {
  border-radius: var(--token-radius-md);
}

/* A card that holds a table is the table's frame: no inset, the rows reach
   its edges, and its foot is a bar of its own. */
.panel:has(> .scroller),
.panel:has(> .cap + .scroller) {
  padding: 0;
  overflow: hidden;
}

.panel > .scroller + * {
  margin-top: 0;
}

.panel > .pager,
.panel > nav.pager {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-space-3) var(--token-layout-card-pad-x);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

/* ---- controls ---- */
.btn,
a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--token-space-2);
  height: var(--token-layout-control-h);
  padding: 0 var(--token-layout-control-pad-x);
  border-radius: var(--token-radius-sm);
  font-size: var(--token-fs-sm);
  line-height: 1;
}

.btn-ghost {
  border-color: var(--token-color-border-strong);
}

.btn-quiet {
  height: auto;
  padding: 0;
}

/* The small button: a card's own action beside its content — «Копіювати»
   under an answer — the size a row's action is (below). */
.btn.btn-sm {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

/* A row's own action is the small one. */
td .btn,
td a.btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

td .btn-quiet {
  height: auto;
  padding: 0;
}

.seg {
  padding: var(--token-layout-seg-inset);
  border-radius: var(--token-radius-seg);
  gap: var(--token-layout-hair-gap);
}

.seg button,
.seg a {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  height: var(--token-layout-seg-item-h);
  padding: 0 var(--token-layout-seg-item-pad-x);
  border-radius: var(--token-radius-seg-item);
  border: 0;
  font-size: var(--token-fs-xs-plus);
}

.seg button[aria-pressed='true'],
.seg a[aria-current='true'] {
  border: 0;
  box-shadow: 0 var(--token-border-hair) var(--token-layout-hair-gap) color-mix(in srgb, var(--token-color-text-primary) 8%, transparent);
}

/* The count beside a segment's name, one step quieter than the name. */
.seg b {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
}

/* A single-line field is one box the height of a button, label kept for
   assistive tech; a field whose label shows keeps it above. */
.field:has(> .sr) {
  flex-direction: row;
  align-items: center;
  height: var(--token-layout-control-h);
  padding: 0 var(--token-space-3);
  border-color: var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
}

select {
  height: var(--token-layout-control-h);
  border-radius: var(--token-radius-sm);
  font-size: var(--token-fs-sm);
}

/* ---- state ---- */
.badge {
  min-height: 0;
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  gap: var(--token-layout-pill-gap);
  font-size: var(--token-fs-xs);
  line-height: 1;
}

.badge-icon {
  width: var(--token-space-3);
  height: var(--token-space-3);
}

/* ---- tables ---- */
table {
  font-size: var(--token-fs-sm);
}

th {
  padding: var(--token-layout-head-pad-y) var(--token-layout-cell-pad-x);
  font-size: var(--token-fs-xs);
  white-space: nowrap;
}

td {
  height: var(--token-layout-row-h);
  padding: 0 var(--token-layout-cell-pad-x);
  vertical-align: middle;
}

th:first-child,
td:first-child {
  padding-left: var(--token-layout-card-pad-x);
}

th:last-child,
td:last-child {
  padding-right: var(--token-layout-card-pad-x);
}

/* A row's title in the text colour and regular weight; medium is kept for
   the rows there is something to do with (`.row-act`), as the layout has it. */
.scroller td > a:first-child:not(.btn),
.scroller td .cv > a:first-child:not(.btn),
.row-title {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-primary);
}

.row-act,
.scroller td a.row-act {
  font-weight: var(--token-weight-medium);
}

/* ---- tabs ---- */
.tabs {
  gap: var(--token-layout-tab-gap);
}

.tabs a {
  padding: var(--token-layout-tab-pad-y) 0;
  font-size: var(--token-fs-sm);
}

/* ---- crumbs ---- */
.crumbs {
  font-size: var(--token-fs-xs-plus);
}

/* The account menu: the row is the summary; the menu opens above it. */
.acct-menu {
  position: relative;
}

.acct-menu > summary {
  list-style: none;
  cursor: pointer;
}

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

/* A dropdown with no room under it opens upwards (the script decides): the
   last rows of a card that hides its overflow cut a menu opening down. */
.dropdown.menu-flip > .menu {
  top: auto;
  bottom: calc(100% + var(--token-space-1));
}

/* `[data-tip]` and its tooltip, the element after it: shown on hover and on
   keyboard focus, kept while the pointer crosses onto it, hidden by Escape
   (`data-tip-off`). Under the trigger here; the script places it on the
   window, so a card that hides its overflow does not cut it. */
[data-tip] + [role='tooltip'] {
  position: absolute;
  z-index: var(--token-z-skip);
  visibility: hidden;
  opacity: 0;
  transition:
    opacity var(--token-dur-fast) ease,
    visibility 0s linear var(--token-dur-base);
}

[data-tip]:hover + [role='tooltip'],
[data-tip]:focus-visible + [role='tooltip'],
[data-tip] + [role='tooltip']:hover {
  visibility: visible;
  opacity: 1;
  transition-delay: 0s;
}

[data-tip][data-tip-off] + [role='tooltip'] {
  visibility: hidden;
  opacity: 0;
}

.menu-up {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + var(--token-space-1));
  z-index: var(--token-z-sticky);
  display: grid;
  gap: var(--token-space-3);
  padding: var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
}

/* ------------------------------------------------------------ own pickers
   No control looks like the operating system's. The approved board draws a
   checkbox as a rounded box that fills with the accent, a file input as a drop
   area with a button inside, and a select whose open list is a card like every
   other menu. Every one of them is still the NATIVE element — announced,
   focusable and posted as before — only drawn by us. */

input[type='checkbox'],
input[type='radio'] {
  appearance: none;
  flex-shrink: 0;
  display: inline-grid;
  place-content: center;
  width: var(--token-size-checkbox);
  height: var(--token-size-checkbox);
  margin: 0;
  border: var(--token-border-check) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-check);
  background: var(--token-color-surface-raised);
  color: var(--token-color-on-accent);
  cursor: pointer;
  transition: background-color 0.12s, border-color 0.12s;
}

input[type='radio'] {
  border-radius: var(--token-radius-pill);
}

input[type='checkbox']:hover,
input[type='radio']:hover {
  border-color: var(--token-color-accent-fill);
}

input[type='checkbox']:checked,
input[type='checkbox']:indeterminate {
  background-color: var(--token-color-accent-fill);
  border-color: var(--token-color-accent-fill);
}

/* The tick is a mask over the accent's own ink, so it follows the theme
   instead of carrying a colour of its own. */
input[type='checkbox']::before {
  content: '';
  width: var(--token-space-3);
  height: var(--token-space-3);
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")
    center / contain no-repeat;
  transform: scale(0);
  transition: transform 0.12s;
}

input[type='checkbox']:checked::before {
  transform: scale(1);
}

input[type='checkbox']:indeterminate::before {
  mask: linear-gradient(currentColor, currentColor) center / 70% var(--token-border-thick) no-repeat;
  transform: scale(1);
}

input[type='radio']::before {
  content: '';
  width: var(--token-space-2);
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-fill);
  transform: scale(0);
  transition: transform 0.12s;
}

input[type='radio']:checked {
  border-color: var(--token-color-accent-fill);
}

input[type='radio']:checked::before {
  transform: scale(1);
}

input[type='checkbox']:focus-visible,
input[type='radio']:focus-visible {
  outline: var(--token-border-thick) solid var(--token-color-accent-fill);
  outline-offset: var(--token-border-thick);
}

input[type='checkbox']:disabled,
input[type='radio']:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* A file input is a drop area: dashed, inset, the button inside it. Dropping a
   file on it works because it is still the browser's own input. */
input[type='file'] {
  width: 100%;
  min-height: calc(var(--token-layout-control-h) + 2 * var(--token-space-4));
  padding: var(--token-space-4);
  border: var(--token-border-check) dashed var(--token-color-border-strong);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-inset);
  font: inherit;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
  cursor: pointer;
  transition: border-color 0.12s, background-color 0.12s;
}

input[type='file']:hover,
input[type='file']:focus-visible {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  outline: none;
}

input[type='file']::file-selector-button {
  height: var(--token-layout-control-h-sm);
  margin-right: var(--token-space-3);
  padding: 0 var(--token-layout-control-pad-x-sm);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font: inherit;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-primary);
  cursor: pointer;
}

/* A file field's own box would draw a second frame around the drop area. */
.field:has(> input[type='file']) {
  border: 0;
  padding: 0;
  background: none;
}

/* Where the browser can draw the open list itself (the customisable select),
   it is a card like the dropdown menu; elsewhere the closed control above is
   already ours and the list is the platform's. */
@supports (appearance: base-select) {
  select,
  select::picker(select) {
    appearance: base-select;
  }

  select {
    display: inline-flex;
    align-items: center;
    gap: var(--token-space-2);
    background-image: none;
    padding: 0 var(--token-layout-control-pad-x-sm) 0 var(--token-space-3);
  }

  select::picker-icon {
    content: '▾';
    color: var(--token-color-text-tertiary);
    font-size: var(--token-fs-xs);
  }

  select::picker(select) {
    margin-top: var(--token-space-1);
    padding: var(--token-space-1);
    border: var(--token-border-hair) solid var(--token-color-border-subtle);
    border-radius: var(--token-radius-md);
    background: var(--token-color-surface-raised);
    box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  }

  select option {
    display: flex;
    align-items: center;
    gap: var(--token-space-2);
    min-height: var(--token-layout-control-h-sm);
    padding: 0 var(--token-layout-control-pad-x-sm);
    border-radius: var(--token-radius-sm);
    font-size: var(--token-fs-sm);
    color: var(--token-color-text-secondary);
    cursor: pointer;
  }

  select option:hover,
  select option:focus-visible {
    background: var(--token-color-surface-sunken);
    color: var(--token-color-text-primary);
    outline: none;
  }

  select option:checked {
    color: var(--token-color-accent-text);
    background: var(--token-color-accent-wash);
  }

  select option::checkmark {
    display: none;
  }
}

/* The search box of a list toolbar: one line, the board's width. */
input[type='search'] {
  appearance: none;
}

.kit .field:has(> input[type='search']) {
  width: var(--token-layout-search);
  flex: 0 0 auto;
}

/* ------------------------------------------------------------ selection
   Rows ticked in a list gather in a bar above it: how many, what it costs, and
   the one action. The bar is part of the page from the first render and shows
   only while something is ticked, so it works before the script arrives; the
   script only fills in the count and the sum. */
.select-bar {
  display: none;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-space-2) var(--token-space-2) var(--token-space-2) var(--token-space-4);
  border-radius: var(--token-radius-seg);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
  font-size: var(--token-fs-sm);
}

.wrap:has(input[data-select]:checked) .select-bar {
  display: flex;
}

.select-bar .select-count {
  font-weight: var(--token-weight-medium);
}

.select-bar .select-sum {
  font-size: var(--token-fs-xs-plus);
}

.select-bar .grow {
  flex: 1 1 auto;
}

.select-bar .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.select-bar .btn-quiet {
  color: var(--token-color-accent-text);
}

tr:has(input[data-select]:checked) > td {
  background: var(--token-color-accent-wash);
}

/* A row with nothing to do reads quieter than one with an action. */
tr.row-dim > td {
  color: var(--token-color-text-tertiary);
}

tr.row-dim > td a:not(.btn) {
  color: var(--token-color-text-primary);
}


/* Column widths of a fixed table, as the approved list draws them. */
table.fixed col.w-tick {
  width: var(--token-layout-col-tick);
}

table.fixed col.w-when {
  width: var(--token-layout-col-when);
}

table.fixed col.w-duration {
  width: var(--token-layout-col-duration);
}

table.fixed col.w-state {
  width: var(--token-layout-col-state);
}

table.fixed col.w-action {
  width: var(--token-layout-col-action);
}

td.tick,
th.tick {
  padding-right: 0;
  text-align: left;
}

td.tick input {
  vertical-align: middle;
}

/* ------------------------------------------------------------ list bar
   The row above a list: its state segments on the left, the search and the
   one menu on the right, all on one line — the approved board. */
.list-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
}

.grow {
  flex: 1 1 auto;
}

.list-bar form.inline {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
}

/* The search keeps its width where there is room and gives way on a phone,
   where a fixed box and its button ran 50px past the screen. */
.list-bar form.inline > .field {
  flex: 0 1 var(--token-layout-search);
  width: var(--token-layout-search);
  min-width: 0;
}

/* A pager whose first word is the count reads left to right: where you are,
   then the way on at the far end. */
.pager > .note:first-child {
  margin-left: 0;
}

/* The import as one card-line above the list. */
.import-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-layout-card-pad-y) var(--token-layout-card-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
}

.import-line .note {
  color: var(--token-color-text-secondary);
}

.import-line .meta {
  color: var(--token-color-text-tertiary);
}

/* The legend's chips are the small ones, and «Є текст» is drawn as an outline —
   text that exists but has not been worked on yet. */
.legend {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.legend .badge {
  height: var(--token-layout-pill-h-sm);
}

.legend .legend-item {
  gap: var(--token-layout-pill-gap);
}

.legend .legend-item:nth-child(2) .badge {
  background: transparent;
  box-shadow: inset 0 0 0 var(--token-border-hair) var(--token-color-state-ok-text);
}

.legend .note {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* ------------------------------------------------------------ links
   The board draws links in the accent without a line, underlined on hover;
   running prose keeps its underline, where a link has to stand out of text. */
a {
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

.prose a,
.md a,
.desc a {
  text-decoration: underline;
}

a.btn:hover,
.seg a:hover,
.side a:hover,
.tabs a:hover,
.menu a:hover {
  text-decoration: none;
}

/* A row's title: in the text colour, one line, cut with an ellipsis — the
   table is fixed, so a long name gives up its end rather than the row its
   height. Medium only for the rows with something to do. */
.scroller td a.cl1,
.cl1 {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-primary);
  font-weight: var(--token-weight-regular);
}

.scroller td > a.row-act:first-child,
.scroller td .cv > a.row-act:first-child,
.scroller td a.cl1.row-act {
  font-weight: var(--token-weight-medium);
}

.legend .badge-icon {
  display: none;
}

/* A glyph before a button's words — «⟳ Підтягнути з Google». */
.btn {
  gap: var(--token-space-2);
}

.btn-icon {
  width: var(--token-fs-md);
  height: var(--token-fs-md);
  flex: none;
}

/* The meetings list: bar, card and legend spaced like the board's column. */
.list-bar {
  margin-bottom: var(--token-layout-block-gap);
}

[data-live='meetings'] {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
}

[data-live='meetings'] > .panel,
[data-live='meetings'] > .legend {
  margin: 0;
}

/* The account: the address and, under it, what its menu holds. */
.acct-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: var(--token-lh-snug);
}

.acct-who {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.acct-hint {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* A glyph inside a button is not the icon-only button of the same name
   (views.css): no minimum width, no centring box of its own. */
svg.btn-icon {
  min-width: 0;
  padding: 0;
}

/* A figure at the end of a navigation row, as the board draws it. */
.side-nav a .side-count {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
  height: var(--token-layout-pill-h-sm);
  padding: 0 calc(var(--token-space-2) - var(--token-border-hair));
  border-radius: var(--token-radius-pill);
  font-size: var(--token-fs-2xs);
  line-height: 1;
  font-weight: var(--token-weight-regular);
  flex: none;
}

.side-count-warning {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.side-count-info {
  background: var(--token-color-state-info-bg);
  color: var(--token-color-state-info-text);
}

.side-count-neutral {
  background: var(--token-color-state-neutral-bg);
  color: var(--token-color-state-neutral-text);
}

/* ------------------------------------------------------------ fill widths
   A bar's fill as a class, one per whole percent. The CSP allows no inline
   style, so `style="width:71%"` was dropped and every bar drew full: the
   readiness in the tenders list, the criteria weights, the meters. */
.pct-0 {
  width: 0%;
}

.pct-1 {
  width: 1%;
}

.pct-2 {
  width: 2%;
}

.pct-3 {
  width: 3%;
}

.pct-4 {
  width: 4%;
}

.pct-5 {
  width: 5%;
}

.pct-6 {
  width: 6%;
}

.pct-7 {
  width: 7%;
}

.pct-8 {
  width: 8%;
}

.pct-9 {
  width: 9%;
}

.pct-10 {
  width: 10%;
}

.pct-11 {
  width: 11%;
}

.pct-12 {
  width: 12%;
}

.pct-13 {
  width: 13%;
}

.pct-14 {
  width: 14%;
}

.pct-15 {
  width: 15%;
}

.pct-16 {
  width: 16%;
}

.pct-17 {
  width: 17%;
}

.pct-18 {
  width: 18%;
}

.pct-19 {
  width: 19%;
}

.pct-20 {
  width: 20%;
}

.pct-21 {
  width: 21%;
}

.pct-22 {
  width: 22%;
}

.pct-23 {
  width: 23%;
}

.pct-24 {
  width: 24%;
}

.pct-25 {
  width: 25%;
}

.pct-26 {
  width: 26%;
}

.pct-27 {
  width: 27%;
}

.pct-28 {
  width: 28%;
}

.pct-29 {
  width: 29%;
}

.pct-30 {
  width: 30%;
}

.pct-31 {
  width: 31%;
}

.pct-32 {
  width: 32%;
}

.pct-33 {
  width: 33%;
}

.pct-34 {
  width: 34%;
}

.pct-35 {
  width: 35%;
}

.pct-36 {
  width: 36%;
}

.pct-37 {
  width: 37%;
}

.pct-38 {
  width: 38%;
}

.pct-39 {
  width: 39%;
}

.pct-40 {
  width: 40%;
}

.pct-41 {
  width: 41%;
}

.pct-42 {
  width: 42%;
}

.pct-43 {
  width: 43%;
}

.pct-44 {
  width: 44%;
}

.pct-45 {
  width: 45%;
}

.pct-46 {
  width: 46%;
}

.pct-47 {
  width: 47%;
}

.pct-48 {
  width: 48%;
}

.pct-49 {
  width: 49%;
}

.pct-50 {
  width: 50%;
}

.pct-51 {
  width: 51%;
}

.pct-52 {
  width: 52%;
}

.pct-53 {
  width: 53%;
}

.pct-54 {
  width: 54%;
}

.pct-55 {
  width: 55%;
}

.pct-56 {
  width: 56%;
}

.pct-57 {
  width: 57%;
}

.pct-58 {
  width: 58%;
}

.pct-59 {
  width: 59%;
}

.pct-60 {
  width: 60%;
}

.pct-61 {
  width: 61%;
}

.pct-62 {
  width: 62%;
}

.pct-63 {
  width: 63%;
}

.pct-64 {
  width: 64%;
}

.pct-65 {
  width: 65%;
}

.pct-66 {
  width: 66%;
}

.pct-67 {
  width: 67%;
}

.pct-68 {
  width: 68%;
}

.pct-69 {
  width: 69%;
}

.pct-70 {
  width: 70%;
}

.pct-71 {
  width: 71%;
}

.pct-72 {
  width: 72%;
}

.pct-73 {
  width: 73%;
}

.pct-74 {
  width: 74%;
}

.pct-75 {
  width: 75%;
}

.pct-76 {
  width: 76%;
}

.pct-77 {
  width: 77%;
}

.pct-78 {
  width: 78%;
}

.pct-79 {
  width: 79%;
}

.pct-80 {
  width: 80%;
}

.pct-81 {
  width: 81%;
}

.pct-82 {
  width: 82%;
}

.pct-83 {
  width: 83%;
}

.pct-84 {
  width: 84%;
}

.pct-85 {
  width: 85%;
}

.pct-86 {
  width: 86%;
}

.pct-87 {
  width: 87%;
}

.pct-88 {
  width: 88%;
}

.pct-89 {
  width: 89%;
}

.pct-90 {
  width: 90%;
}

.pct-91 {
  width: 91%;
}

.pct-92 {
  width: 92%;
}

.pct-93 {
  width: 93%;
}

.pct-94 {
  width: 94%;
}

.pct-95 {
  width: 95%;
}

.pct-96 {
  width: 96%;
}

.pct-97 {
  width: 97%;
}

.pct-98 {
  width: 98%;
}

.pct-99 {
  width: 99%;
}

.pct-100 {
  width: 100%;
}

/* ------------------------------------------------------------ form fields
   A field with a visible label, as the boards' forms draw it: the label above
   in the secondary ink, medium, and the control its own 40px box. The single-
   line toolbar field (label kept for assistive tech) stays one box. */
.field:not(:has(> .sr)) {
  gap: calc(var(--token-space-1) * 1.5);
  padding: 0;
  border: 0;
  background: none;
  border-radius: 0;
}

.field:not(:has(> .sr)) > .lbl,
.control > .lbl {
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  letter-spacing: 0;
  text-transform: none;
  color: var(--token-color-text-secondary);
}

.field:not(:has(> .sr)) > input:not([type='file']),
.field:not(:has(> .sr)) > textarea {
  box-sizing: border-box;
  width: 100%;
  min-height: calc(var(--token-layout-control-h) + var(--token-space-1));
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font: inherit;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

.field:not(:has(> .sr)) > textarea {
  padding: var(--token-space-2) var(--token-space-3);
  min-height: calc(var(--token-layout-control-h) * 3);
  resize: vertical;
}

.field:not(:has(> .sr)):focus-within {
  border-color: transparent;
}

.field:not(:has(> .sr)) > input:not([type='file']):focus,
.field:not(:has(> .sr)) > textarea:focus {
  outline: 0;
  border-color: var(--token-color-accent-fill);
  box-shadow: 0 0 0 calc(var(--token-border-thick) + var(--token-border-hair)) var(--token-color-accent-wash);
}

.control {
  display: inline-flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) * 1.5);
}

.control > select {
  height: calc(var(--token-layout-control-h) + var(--token-space-1));
}

/* An announced product's name stays on one line in the side column. */
.side-soon {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* =====================================================================
   Icons, notices, toasts and the folding side column (@strim/web 2.41).
   ===================================================================== */

/* A Lucide glyph (components/icon.ts): stroke only, in the colour of the text
   it sits in, so a badge's tone or a link's hover reaches it with no rule of
   its own. `vertical-align` seats it on the text line where it is inline;
   inside a flex row it is ignored and the row's own alignment decides. */
.ic {
  width: var(--token-size-icon);
  height: var(--token-size-icon);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.15em;
}

.ic-sm {
  width: var(--token-size-icon-sm);
  height: var(--token-size-icon-sm);
}

.ic-lg {
  width: var(--token-size-icon-lg);
  height: var(--token-size-icon-lg);
}

.ic-xl {
  width: var(--token-size-icon-xl);
  height: var(--token-size-icon-xl);
}

/* Loader2, turning; still for a reader who asked for less motion. */
.ic-spin {
  animation: ic-spin 1s linear infinite;
}

@keyframes ic-spin {
  to {
    transform: rotate(360deg);
  }
}

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

/* Controls the script reveals. `hidden` loses to any `display` a class sets,
   so these say it again for the elements that have one. */
.side-toggle[hidden],
.toast-close[hidden],
.btn[data-history-back][hidden] {
  display: none;
}

/* ---- in components ---- */

/* The badge's own glyph is 12px and bolder, so it reads at chip size. */
.badge .ic {
  width: var(--token-size-badge-icon);
  height: var(--token-size-badge-icon);
  stroke-width: 2.4;
}

/* An icon-only button: a square the height of the control, its name in
   aria-label and title. */
.btn-glyph,
a.btn-glyph {
  width: var(--token-layout-control-h);
  padding: 0;
}

td .btn-glyph,
td a.btn-glyph {
  width: var(--token-layout-control-h-sm);
  padding: 0;
}

td .btn .ic {
  width: var(--token-size-icon-sm);
  height: var(--token-size-icon-sm);
}

/* A glyph before a switcher's label. */
.seg .ic {
  width: var(--token-size-icon-sm);
  height: var(--token-size-icon-sm);
}

/* Sort marks: ArrowUpDown quiet on every sortable column, the arrow in force
   in the heading's own colour. */
th .sort {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

th .sort .ic {
  color: var(--token-color-text-tertiary);
}

th[aria-sort] .sort .ic,
th .sort:hover .ic {
  color: currentColor;
}

.sec-head h2 > .ic,
.cap > .ic {
  margin-right: var(--token-space-2);
}

.cap > .ic {
  margin-right: var(--token-space-1);
}

/* A KPI tile's glyph in its corner, quieter than the figure. */
.panel.stat {
  position: relative;
}

.stat-icon {
  position: absolute;
  top: var(--token-space-4);
  right: var(--token-space-4);
  color: var(--token-color-text-tertiary);
  line-height: 0;
}

.empty-icon {
  color: var(--token-color-text-tertiary);
  line-height: 0;
}

/* A head's actions grew glyphs, and a switcher with three of them beside a
   button no longer fit a narrow page on one line: never wider than the head,
   so its controls wrap instead of running into the page's margin. */
.hero-action {
  max-width: 100%;
}

/* The page head's glyph — AlertCircle over a 404, in the tone it states. */
.hero-icon {
  display: inline-flex;
  vertical-align: middle;
  margin-right: var(--token-space-3);
  line-height: 0;
}

.hero-icon.tone-critical {
  color: var(--token-color-state-crit-text);
}

.hero-icon.tone-warning {
  color: var(--token-color-state-warn-text);
}

.hero-icon.tone-info {
  color: var(--token-color-state-info-text);
}

.hero-icon.tone-ok {
  color: var(--token-color-state-ok-text);
}

/* The refusal's reason: its own line across the card, above the actions. */
.err-reason {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  overflow-wrap: anywhere;
}

.err-reason .lbl {
  color: var(--token-color-text-tertiary);
}

/* ---- banner ---- */

/* A page-wide condition above the page. Wraps at 820 rather than pushing the
   actions off the side. */
.banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-3);
  padding: var(--token-space-3) var(--token-space-4);
  border-radius: var(--token-radius-md);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-sm);
}

.banner-body {
  flex: 1 1 var(--token-layout-field-basis);
  min-width: 0;
  overflow-wrap: break-word;
}

.banner-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-3);
}

.banner-critical {
  background: var(--token-color-state-crit-bg);
  border-color: color-mix(in srgb, var(--token-color-state-crit-text) 30%, transparent);
}

.banner-critical > .ic {
  color: var(--token-color-state-crit-text);
}

.banner-warning {
  background: var(--token-color-state-warn-bg);
}

.banner-warning > .ic {
  color: var(--token-color-state-warn-text);
}

.banner-info {
  background: var(--token-color-state-info-bg);
}

.banner-info > .ic {
  color: var(--token-color-state-info-text);
}

.banner-ok {
  background: var(--token-color-state-ok-bg);
}

.banner-ok > .ic {
  color: var(--token-color-state-ok-text);
}

/* ---- toasts ---- */

/* In the page's flow by default: without the script the message is read at
   the top of the page and covers nothing. The script floats the stack. */
.toasts {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.toasts[data-float] {
  position: fixed;
  right: var(--token-space-6);
  bottom: var(--token-space-6);
  z-index: var(--token-z-skip);
  width: min(var(--token-layout-toast), calc(100vw - var(--token-space-4) * 2));
  margin: 0;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: var(--token-space-3) var(--token-space-4);
  border-radius: var(--token-radius-md);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  font-size: var(--token-fs-sm);
  transition: opacity var(--token-dur-base);
}

.toasts[data-float] .toast {
  box-shadow: 0 var(--token-space-1) var(--token-space-4) color-mix(in srgb, var(--token-color-text-primary) 14%, transparent);
}

.toast[data-leaving] {
  opacity: 0;
}

.toast > .ic {
  margin-top: var(--token-gap-hair);
}

.toast-ok > .ic {
  color: var(--token-color-state-ok-text);
}

.toast-info > .ic {
  color: var(--token-color-state-info-text);
}

.toast-warning > .ic {
  color: var(--token-color-state-warn-text);
}

.toast-critical {
  border-color: color-mix(in srgb, var(--token-color-state-crit-text) 40%, transparent);
}

.toast-critical > .ic {
  color: var(--token-color-state-crit-text);
}

.toast-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: break-word;
}

.toast-title {
  margin: 0;
  font-weight: var(--token-weight-medium);
}

.toast-body {
  margin: var(--token-space-1) 0 0;
  color: var(--token-color-text-secondary);
}

.toast-close {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: var(--token-layout-pill-h);
  height: var(--token-layout-pill-h);
  padding: 0;
  border: 0;
  border-radius: var(--token-radius-sm);
  background: transparent;
  color: var(--token-color-text-tertiary);
  cursor: pointer;
}

.toast-close:hover {
  background: var(--token-color-surface-inset);
  color: var(--token-color-text-primary);
}

@media (max-width: 640px) {
  .toasts[data-float] {
    right: var(--token-space-4);
    bottom: var(--token-space-4);
  }
}

/* ---- the side column: glyphs, brand tile, sign-out, fold ---- */

.side-nav a .ic,
.side-soon .ic {
  color: inherit;
}

/* The original's brand tile: the glyph on the accent. */
.brand-icon {
  display: inline-grid;
  place-items: center;
  width: var(--token-layout-avatar);
  height: var(--token-layout-avatar);
  flex: none;
  border-radius: var(--token-radius-sm);
  background: var(--token-color-accent-fill);
  color: var(--token-color-on-accent);
}

.signout {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

.side-toggle {
  display: flex;
  align-items: center;
  gap: var(--token-layout-brand-gap);
  width: 100%;
  height: var(--token-size-nav-row);
  margin-bottom: var(--token-space-1);
  padding: 0 var(--token-layout-item-pad-x);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: transparent;
  color: var(--token-color-text-secondary);
  font: inherit;
  font-size: var(--token-fs-sm);
  cursor: pointer;
  text-align: left;
}

.side-toggle:hover {
  background: var(--token-color-surface-inset);
  color: var(--token-color-text-primary);
}

.side-toggle [data-icon='PanelLeftOpen'] {
  display: none;
}

/* Folded: the column narrows to its glyphs and every name goes to the row's
   tooltip (set by the script).
 *
 * The names are taken out of the picture by `font-size: 0`, not removed: the
 * row keeps its text, so it is still announced by its name, and the glyphs are
 * sized by tokens rather than by the font, so they stay. A row that has no
 * glyph is laid out as a block for the length of the fold, which is what lets
 * `::first-letter` bring back its initial at a readable size — «Д» for
 * «Доступи» — instead of leaving an empty square. The account keeps its
 * initials; its menu opens wider than the column, so the column stops
 * clipping what overflows it. */
@media (min-width: 761px) {
  .app[data-side='collapsed'] {
    grid-template-columns: var(--token-layout-sidebar-collapsed) minmax(0, 1fr);
  }

  .app[data-side='collapsed'] .side {
    overflow: visible;
  }

  .app[data-side='collapsed'] .side-nav a,
  .app[data-side='collapsed'] .side-soon,
  .app[data-side='collapsed'] .side-toggle,
  .app[data-side='collapsed'] .brand {
    font-size: 0;
    gap: 0;
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }

  .app[data-side='collapsed'] .side-nav a:not(:has(svg)),
  .app[data-side='collapsed'] .side-soon:not(:has(svg)) {
    display: block;
    text-align: center;
    line-height: var(--token-size-nav-row);
    overflow: hidden;
  }

  .app[data-side='collapsed'] .side-nav a:not(:has(svg))::first-letter,
  .app[data-side='collapsed'] .side-soon:not(:has(svg))::first-letter {
    font-size: var(--token-fs-xs);
  }

  .app[data-side='collapsed'] .side-label,
  .app[data-side='collapsed'] .side-count,
  .app[data-side='collapsed'] .acct-text {
    display: none;
  }

  .app[data-side='collapsed'] .side-sub {
    padding-left: 0;
  }

  .app[data-side='collapsed'] .acct {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }

  .app[data-side='collapsed'] .menu-up {
    right: auto;
    width: var(--token-layout-sidebar);
  }

  .app[data-side='collapsed'] .side-toggle [data-icon='PanelLeftClose'] {
    display: none;
  }

  .app[data-side='collapsed'] .side-toggle [data-icon='PanelLeftOpen'] {
    display: inline;
  }
}

/* A phone: the column is a block above the page, and there is nothing to
   fold. */
@media (max-width: 760px) {
  .side-toggle {
    display: none;
  }
}

/* ------------------------------------------------ the frame on a phone */

@media (max-width: 760px) {
  .app {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Two rows, not a column: the brand and the account on the first, every
     item on one row under it that scrolls sideways. As a column the menu was
     the whole first screen of a phone on every page, the page itself starting
     on the second. Still no script: every item is a plain link in view or one
     swipe away. */
  .side {
    position: static;
    height: auto;
    overflow: visible;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      'brand foot'
      'nav nav';
    align-items: center;
    gap: var(--token-space-2) var(--token-space-3);
    padding: var(--token-space-3) var(--token-space-4) var(--token-space-2);
    border-right: 0;
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }
  .side > .brand {
    grid-area: brand;
    padding: 0;
  }
  .side > .side-nav {
    grid-area: nav;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: var(--token-space-1);
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 calc(-1 * var(--token-space-4));
    padding: 0 var(--token-space-4);
  }
  .side > .side-nav::-webkit-scrollbar {
    display: none;
  }
  .side > .side-nav a,
  .side > .side-nav .side-soon {
    flex: none;
    white-space: nowrap;
  }
  /* The current product's pages sit in the same row, after its name. */
  .side > .side-nav .side-sub {
    display: contents;
  }
  .side > .side-nav .side-label {
    display: none;
  }
  .side > .side-nav .side-product,
  .side > .side-nav .side-product-current {
    margin-top: 0;
  }
  .side-foot {
    grid-area: foot;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--token-space-2);
    margin-top: 0;
    padding: 0;
    border-top: 0;
  }
  .side-foot .side-foot-nav {
    flex-direction: row;
  }
  .side-foot .acct {
    margin: 0;
    padding: 0;
    border-top: 0;
  }
  .side-foot .acct-text {
    display: none;
  }
  /* Opens downwards from the top bar, not upwards off the screen. */
  .side-foot .menu-up {
    top: calc(100% + var(--token-space-1));
    bottom: auto;
    right: 0;
    left: auto;
    width: max-content;
    max-width: calc(100vw - var(--token-space-8));
  }
}

/* Google's folder picker. Its script injects these rules as a <style> element,
 * which our CSP (`style-src 'self'`) refuses — so the dialog fell to the foot
 * of the page with a frame of no height. Shipped here instead, in tokens; the
 * positions and sizes the script sets on the elements themselves still apply. */
.picker-dialog-frame {
  width: 100%;
  height: 100%;
  border: 0;
  overflow: hidden;
}
.picker-dialog-bg {
  position: absolute;
  top: 0;
  left: 0;
  background-color: var(--token-color-surface-raised);
  z-index: 1000;
}
.picker-dialog {
  position: absolute;
  top: 0;
  left: 0;
  background-color: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  width: auto;
  padding: 0;
  z-index: 1001;
  overflow: auto;
}
.picker-dialog-content {
  height: 100%;
  font-size: 0;
  padding: 0;
}
.picker-dialog-buttons,
.picker-dialog-title {
  display: none;
}

/* Styles the views need and the component library does not have.

   Everything here is a shape that only makes sense inside a page: a
   transcript turn, a filter chip, a menu of links. Nothing that belongs to a component lives
   here — a rule for .panel or .badge in this file would be the second copy that
   drifts, which is the whole reason app.css declares no values of its own.

   Same rule as app.css: not one literal. Every value is a token, and
   scripts/lint-literals.ts fails the build on a colour or a px. */

/* ------------------------------------------------------------- transcript */

/* The longest page in the product, so the mechanics that only matter at length
   all matter here.

   The sticky chrome STAYS. On a two-hour transcript it is the difference
   between a way back that is always to hand and one that is forty thousand
   words above you; the header is a single row, and `scroll-padding-top` in
   app.css already keeps anchor targets clear of it. */
.transcript {
  display: grid;
  gap: var(--token-space-6);
}

.turn {
  display: grid;
  gap: var(--token-space-2);
}

/* Who spoke, and where in the recording. Small and quiet: it is the label on
   the block, not part of what was said. */
.turn-who {
  display: flex;
  align-items: baseline;
  gap: var(--token-space-3);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.turn-at {
  color: var(--token-color-text-meta);
  text-decoration: none;
}

.turn-at:hover {
  color: var(--token-color-accent-text);
}

/* The reading measure is the whole point of a transcript page: 40 000 words set
   to the full width of a desktop window is unreadable however good the type is.
   `overflow-wrap` because a transcript is machine-produced text and a single
   unbroken token — a pasted URL, a run-together artefact of recognition — would
   otherwise push the measure wider than the window. */
.turn-text {
  display: grid;
  gap: var(--token-space-3);
  max-width: var(--token-measure-prose);
  color: var(--token-color-text-primary);
  line-height: var(--token-lh-relaxed);
  overflow-wrap: break-word;
}

/* ----------------------------------------------------------------- rhythm */

/* A live region holds whatever its view put there — on the meeting page, the
   progress panel AND the result under it. As a plain block the two sat flush,
   the running panel's border touching the result tabs; as a stack they get the
   gap every other pair of blocks on the page has. */
[data-live] {
  display: grid;
  /* One column that is the region's width and never its content's. Without
     it the implicit track is `auto`, which sizes to the widest child's
     max-content: on the audit page (live since @tenders 0.69.0) one unbroken
     requirement reference made the whole page 3,500px wide. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--token-space-4);
  min-width: 0;
}

/* A state chip and the words beside it: a time, a lens. Spaced by a gap, not a
   typed space, which left the chip's border touching the next word. */
.meta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-3);
}

/* A chip at the end of a sentence (a meeting's date line) stands apart from
   its last word; a typed space alone left the pill's border touching it. */
.lede .badge {
  margin-left: var(--token-space-2);
}

/* A note under a table cell's main value — a failure reason under its chip, the
   archive depth under a window — on its own line rather than run on after it. */
.cell-note {
  display: block;
  margin-top: var(--token-space-1);
}

/* One clause per line in a cell that lists several (an import's window per source). */
.cell-line {
  display: block;
}

/* The meetings list's groups. At the grid's ordinary gap a group's «Показати
   всі» button sat directly on the next group's heading, and the two read as one
   block; a group is a section of the list and is spaced like one. The stack
   of groups is the region's only child (meetingsRegion). */
[data-live='meetings'] > .grid {
  gap: var(--token-space-12);
}

/* A cell holding a reason and the button to act on it: one under the other,
   spaced, rather than a sentence with a button glued to its last word. */
.cell-stack {
  display: grid;
  justify-items: start;
  gap: var(--token-space-2);
}

/* In a stacked (card) row the value side is right-aligned; the pair follows it. */
@media (max-width: 640px) {
  .stack .cell-stack {
    justify-items: end;
  }
}

[data-live='meetings'] > .panel {
  margin-bottom: var(--token-space-6);
}

/* The row whose requirement the panel shows, marked from the link's own
   `aria-current` so what a screen reader announces and what is highlighted
   cannot disagree. */
tr:has(a[aria-current='true']) > td {
  background: var(--token-color-accent-wash);
}

tr:has(a[aria-current='true']) > td:first-child {
  box-shadow: inset calc(var(--token-border-hair) * 3) 0 0 var(--token-color-accent-fill);
}

/* The meetings list's colour legend: chip and gloss side by side, the pairs
   spaced apart so a gloss never reads as the next chip's. */
.legend {
  gap: var(--token-space-2) var(--token-space-6);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

/* A filter chip: a state and its count, pressed to narrow a list to it
   (the requirements' «За аудитом №N»). The one in force carries the state's
   own border, so what is filtered reads from the chip rather than a legend. */
.fchip {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  padding: var(--token-space-1) var(--token-space-3) var(--token-space-1) var(--token-space-1);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-secondary);
  text-decoration: none;
  font-size: var(--token-fs-sm);
}

.fchip b {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
  font-variant-numeric: tabular-nums;
}

.fchip:hover {
  border-color: var(--token-color-text-tertiary);
}

.fchip[aria-current='true'] {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
}

/* A tender's head: the trail, a one-line title with its status control, one
   line of facts, and the tab strip — the approved layout's compact page head.
   The title was a two-line hero over a label-and-value list, and the first
   tab's content began half a screen down. */
.ws-head {
  display: grid;
  gap: var(--token-space-2);
  margin-bottom: var(--token-space-6);
}

.ws-title-row {
  display: flex;
  align-items: center;
  gap: var(--token-space-4);
  min-width: 0;
}

.ws-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--token-fs-lg);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ws-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-4);
  margin: 0;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.ws-head .tabs {
  margin-top: var(--token-space-2);
}

.tabs b {
  font-weight: var(--token-weight-regular);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  margin-left: var(--token-space-1);
}

/* A readiness figure in a list: the display face, larger than the row,
   coloured by its value as the original's (`> 80` ok, `> 50` warn, else
   crit) — never by the gate. */
.score-figure {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  font-variant-numeric: tabular-nums;
}

.score-figure.is-ok {
  color: var(--token-color-state-ok-text);
}

.score-figure.is-warn {
  color: var(--token-color-state-warn-text);
}

.score-figure.is-crit {
  color: var(--token-color-state-crit-text);
}

/* The list's import line as the approved layout draws it: a compact card
   directly under the page head, and the filters close under it. */
[data-live='import'] > .panel {
  padding: var(--token-space-3) var(--token-space-4);
}

/* A field inside a row of filters keeps a field's width instead of growing
   to the row's maximum: grown, it pushed its own button onto a line of its own. */
form.inline > .field {
  flex: 0 1 var(--token-layout-field-basis);
}

/* «Google підключено»: a small ok dot before the words, the connection's state. */
.dot-ok {
  width: var(--token-space-2);
  height: var(--token-space-2);
  border-radius: 50%;
  background: var(--token-color-state-ok-text);
  flex: none;
}

/* A person in the access list: initials, the address, and the platform-admin
   chip under it — the approved layout's first column. */
.person {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.person-who {
  display: grid;
  justify-items: start;
  gap: var(--token-space-1);
  min-width: 0;
}

/* «30 днів ▾»: a short menu of links under a button, open while the
   <details> is. The menu floats over the page rather than pushing it. */
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown > summary {
  list-style: none;
  cursor: pointer;
  gap: var(--token-space-2);
}

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

.dropdown-caret {
  width: var(--token-fs-sm);
  height: var(--token-fs-sm);
  flex: none;
}

.dropdown .menu {
  position: absolute;
  right: 0;
  top: calc(100% + var(--token-space-1));
  z-index: 5;
  min-width: calc(var(--token-layout-field-basis) * 0.9);
  padding: var(--token-space-1);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
}

.menu-group + .menu-group {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  margin-top: var(--token-space-1);
  padding-top: var(--token-space-1);
}

.menu a {
  display: block;
  padding: var(--token-space-2) var(--token-space-3);
  border-radius: var(--token-radius-sm);
  color: var(--token-color-text-primary);
  text-decoration: none;
  font-size: var(--token-fs-sm);
  white-space: nowrap;
}

.menu a:hover {
  background: var(--token-color-surface-inset);
}

.menu a[aria-current='true'] {
  background: var(--token-color-accent-wash);
  color: var(--token-nav-current-fg);
}

/* A menu item that is a button — a submit of the menu's own form, like the
   import's depths under «Підтягнути з Google ▾» — drawn as the link items
   are, not with the browser's grey button face. */
.menu .menu-item {
  display: block;
  width: 100%;
  padding: var(--token-space-2) var(--token-space-3);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: none;
  color: var(--token-color-text-primary);
  font: inherit;
  font-size: var(--token-fs-sm);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.menu .menu-item:hover {
  background: var(--token-color-surface-inset);
}

.menu .menu-item[aria-current='true'] {
  background: var(--token-color-accent-wash);
  color: var(--token-nav-current-fg);
}

/* The transcript as a raised column beside the protocol, scrolling on its
   own, so the decision being checked stays in view while the turn that backs
   it is found (the meeting page's `.mt-pane` settles its frame). */
.transcript-pane {
  position: sticky;
  top: var(--token-space-6);
  max-height: calc(100dvh - 2 * var(--token-space-6));
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-pill-gap);
  padding: var(--token-layout-aside-pad-y) var(--token-layout-aside-pad-x);
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  scroll-behavior: smooth;
}

.transcript-pane > .cap {
  margin: 0;
  font-size: var(--token-fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.transcript-pane .transcript {
  gap: 0;
}

/* One turn: its timecode in a column of its own, then who and what. The
   `who` line is flattened into the grid so the timecode can sit beside both. */
.transcript-pane .turn {
  grid-template-columns: var(--token-layout-timecode) minmax(0, 1fr);
  column-gap: var(--token-space-3);
  row-gap: 0;
  padding: var(--token-layout-tab-pad-y) 0;
  border-radius: var(--token-radius-sm);
  scroll-margin-top: var(--token-space-6);
}

.transcript-pane .turn-who {
  display: contents;
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.transcript-pane .turn-at {
  grid-column: 1;
  grid-row: 1 / span 2;
  font-family: inherit;
  font-weight: var(--token-weight-regular);
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-tertiary);
}

.transcript-pane .turn-text {
  grid-column: 2;
  gap: var(--token-space-1);
  max-width: none;
  color: var(--token-color-text-secondary);
}

.transcript-pane .turn-text p {
  margin: 0;
}

/* The turn a quote opened: washed in the accent, and its words at reading size
   — the board's highlighted segment. */
.transcript-pane .turn:target {
  background: var(--token-color-accent-wash);
  padding-inline: var(--token-layout-cell-pad-x);
  margin-inline: calc(-1 * var(--token-layout-cell-pad-x));
}

.transcript-pane .turn:target .turn-who,
.transcript-pane .turn:target .turn-at {
  color: var(--token-color-accent-text);
}

.transcript-pane .turn:target .turn-text {
  font-size: var(--token-fs-md);
  color: var(--token-color-text-primary);
}

.transcript-pane > .note {
  margin: var(--token-space-2) 0 0;
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

@media (max-width: 1100px) {
  .transcript-pane {
    position: static;
    max-height: 60vh;
  }
}

/* Screen-shaped rules for the meeting screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   The meeting page and its transcript, as the approved Protocol board draws
   them (ProtocolA): a raised head band across the page — trail, title, facts,
   the document's controls, the tabs on its lower edge — and under it the
   protocol as cards on the left with the transcript in a raised column on the
   right. The two columns scroll on their own under a head that stays, which is
   what the board's fixed-height frame shows: a quote on the left opens its turn
   on the right without the page jumping away from the decision being checked.

   Values the tokens do not name are composed from them; each such sum says
   what it adds up to. */

/* ------------------------------------------------------------------ frame */

.wrap:has(> .mt-head) {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  padding: 0;
  gap: 0;
  line-height: 1.5;
}

/* ------------------------------------------------------------------- head */

.mt-head {
  flex: none;
  padding: var(--token-space-6) var(--token-layout-page-pad-x) 0;
  background: var(--token-color-surface-raised);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.mt-head .crumbs {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.mt-head .crumbs span[aria-hidden] {
  margin: 0;
}

/* 6px under the trail and under the title: space-1 × 1.5. */
.mt-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--token-space-4);
  margin-top: calc(var(--token-space-1) * 1.5);
}

/* The title keeps a readable measure. With `flex: 1 1 auto` and the actions
   unshrinkable, four controls took the row and squeezed the name into a
   column of syllables («Stri / mco / Mon / thly») and the facts into one word
   a line. Now the actions go under the title before the title goes narrower
   than this. */
.mt-titles {
  flex: 1 1 var(--token-layout-aside);
  min-width: min(var(--token-layout-aside), 100%);
}

.mt-title {
  font-size: var(--token-fs-xl);
  line-height: 1.15;
  letter-spacing: -0.01em;
  /* Wraps, as the approved ProtocolA board sets a long name over two lines:
     cutting it to one line hid most of the name behind the actions. */
  text-wrap: pretty;
  overflow-wrap: break-word;
}

/* 14px between the facts: space-3 + a hair gap. */
.mt-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) calc(var(--token-space-3) + var(--token-gap-hair));
  margin-top: calc(var(--token-space-1) * 1.5);
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.mt-sep {
  color: var(--token-color-text-tertiary);
}

.mt-actions {
  flex: 0 1 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-4);
}

.mt-actions .btn,
.mt-actions .dropdown > summary {
  height: var(--token-layout-control-h);
  padding: 0 var(--token-layout-control-pad-x);
}

.mt-actions .dropdown .menu {
  min-width: 100%;
}

/* The copy link says it worked, for the moment the script marks it. */
.mt-actions a[data-copy][data-done] {
  border-color: var(--token-color-state-ok-text);
  color: var(--token-color-state-ok-text);
}

/* The tabs sit on the band's lower edge: no rule of their own, and the
   current tab's underline lies over the band's border. */
.mt-tabs {
  margin-top: var(--token-layout-block-gap);
  border-bottom: 0;
}

.mt-tabs a {
  padding: var(--token-layout-tab-pad-y) 0;
}

/* ------------------------------------------------------------------- body */

.mt-body {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.mt-body.has-pane {
  grid-template-columns: minmax(0, 1fr) var(--token-layout-aside);
}

/* 28px above and below (space-6 + space-1), 36px towards the column
   (space-8 + space-1), the page's 40px on the outer edge; 26px between blocks
   (space-6 + two hair gaps). */
/* Positioned, so the visually hidden labels inside (`.sr` is absolute) are
   clipped by this column's scroll rather than stretching the document under
   the fixed frame. */
.mt-main {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-6) + var(--token-gap-hair));
  padding: calc(var(--token-space-6) + var(--token-space-1)) var(--token-layout-page-pad-x);
  scroll-behavior: smooth;
}

.mt-body.has-pane > .mt-main {
  padding-right: calc(var(--token-space-8) + var(--token-space-1));
}

.mt-main > [data-live] {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-6) + var(--token-gap-hair));
}

.mt-main > [data-live]:empty {
  display: none;
}

/* ----------------------------------------------------------------- blocks */

.pr-doc {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-6) + var(--token-gap-hair));
}

.pr-head {
  display: flex;
  align-items: baseline;
  gap: var(--token-layout-brand-gap);
}

.pr-head h2 {
  font-size: var(--token-fs-lg);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.pr-count {
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* 10px between a heading and its card. */
.pr-head + * {
  margin-top: var(--token-layout-brand-gap);
}

/* A card of rows: 4px above and below the rows, 22px at the sides
   (space-5 + a hair gap). */
.pr-card {
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  padding: var(--token-space-1) calc(var(--token-space-5) + var(--token-gap-hair));
  min-width: 0;
  overflow-wrap: break-word;
}

/* A card of prose, with its small label: 20px × 22px. */
.pr-card.pr-note {
  padding: var(--token-space-5) calc(var(--token-space-5) + var(--token-gap-hair));
}

/* A card holding a table: the table's own cells carry the inset. */
.pr-card.pr-card-table {
  padding: calc(var(--token-space-1) * 1.5) var(--token-space-3);
}

/* «ПІДСУМОК»: the label a prose card is headed by. */
.pr-lbl {
  margin: 0;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-2xs);
  font-weight: var(--token-weight-regular);
  line-height: 1.5;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
  /* Wraps: the label of a prose section is the model's heading, and a long
     one held on one line ran the protocol 150px past a phone's edge. */
  text-wrap: pretty;
}

/* Reading size for what the document says — 15px, fs-sm and a hair. */
.pr-note > p,
.pr-note > form > p:not(.note),
.pr-text,
.pr-para,
.pr-lead {
  font-size: calc(var(--token-fs-sm) + var(--token-border-hair));
}

.pr-note > * + * {
  margin-top: var(--token-space-2);
}

.pr-note > p {
  line-height: 1.6;
  color: var(--token-color-text-secondary);
}

.pr-note > .pr-lead,
.pr-lead {
  color: var(--token-color-text-primary);
}

/* A «who was there» line, collapsed: the native disclosure, toned like a note. */
.pr-who {
  color: var(--token-color-text-secondary);
}

.pr-who > summary {
  cursor: pointer;
  font-size: calc(var(--token-fs-sm) + var(--token-border-hair));
}

.pr-who > p {
  margin-top: var(--token-space-2);
  line-height: 1.6;
}

.pr-note > .pr-lbl + * {
  margin-top: var(--token-space-2);
}

.pr-note > * + form,
.pr-note > * + .kit {
  margin-top: var(--token-space-4);
}

.pr-note .note {
  font-size: var(--token-fs-xs-plus);
}

.pr-sub {
  margin: 0;
  padding: var(--token-space-4) 0 0;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-2xs);
  font-weight: var(--token-weight-regular);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.pr-note > .pr-sub {
  padding-top: var(--token-space-2);
}

.pr-para {
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

/* ------------------------------------------------------------------ rows */

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

/* 14px between marker and claim, and above and below a row. */
.pr-item {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.pr-items:last-child > .pr-item:last-child {
  border-bottom: 0;
}

.pr-n {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--token-layout-pill-h);
  height: var(--token-layout-pill-h);
  border-radius: 50%;
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs);
  font-variant-numeric: tabular-nums;
}

.pr-item > .badge {
  flex: none;
  margin-top: var(--token-border-hair);
}

/* The board's «Питання» chip is the colour and the word: no dash glyph. */
.pr-item > .b-neutral .badge-icon {
  display: none;
}

.pr-body {
  flex: 1 1 auto;
  min-width: 0;
}

.pr-text {
  margin: 0;
  color: var(--token-color-text-primary);
}

.pr-meta {
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.pr-act {
  flex: none;
  align-self: center;
}

.pr-lead-block {
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.pr-lead-block:last-child {
  border-bottom: 0;
}

.pr-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-1) var(--token-space-3);
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.pr-card-head strong {
  font-weight: var(--token-weight-regular);
  font-size: calc(var(--token-fs-sm) + var(--token-border-hair));
}

.pr-card-head .note {
  font-size: var(--token-fs-xs-plus);
}

.pr-state .meta-row {
  gap: var(--token-space-3);
}

/* ----------------------------------------------------------------- tasks */

.pr-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: var(--token-fs-sm);
}

/* The board's cells: 8px × 10px in the head, 12px × 10px in the rows. */
.pr-table th,
.pr-table th:first-child,
.pr-table th:last-child {
  height: auto;
  padding: var(--token-space-2) var(--token-layout-brand-gap);
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
  text-align: left;
  vertical-align: bottom;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.pr-table td,
.pr-table td:first-child,
.pr-table td:last-child {
  height: auto;
  padding: var(--token-space-3) var(--token-layout-brand-gap);
  vertical-align: top;
  color: var(--token-color-text-primary);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  overflow-wrap: break-word;
}

.pr-table tr:last-child td {
  border-bottom: 0;
}

/* Хто 170px, Термін and Звідки 120px (space-10 × 3). */
.pr-table col.pr-w-who {
  width: var(--token-layout-col-state);
}

.pr-table col.pr-w-when,
.pr-table col.pr-w-from {
  width: calc(var(--token-space-10) * 3);
}

.pr-when {
  font-variant-numeric: tabular-nums;
}

.pr-none {
  color: var(--token-color-text-tertiary);
}

/* ------------------------------------------------------------ asking, rest */

.pr-ask form.stack {
  gap: var(--token-space-3);
}

.pr-ask > .note {
  margin-top: var(--token-space-3);
}

.pr-results {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
}

/* 10px between the result's heading, its state, its switcher and its card. */
.pr-results > [data-live='analysis'] {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-brand-gap);
}

.pr-results > [data-live='analysis'] > .pr-head + * {
  margin-top: 0;
}

.pr-results > [data-live='attempts']:empty {
  display: none;
}

/* The switcher is as wide as its answers, not the column. */
.pr-results .seg {
  align-self: flex-start;
}

.pr-results .log .pr-card {
  margin-top: var(--token-space-2);
}

.pr-results .log .pr-item {
  align-items: center;
}

/* The protocol's own controls — the format, the copy, the downloads, the
   Google Doc — over the document they act on, not beside the call's title. */
.pr-toolbar {
  margin-bottom: var(--token-space-4);
}

/* ----------------------------------------------------------- transcript */

/* The column beside the protocol: the full height under the head, a border
   on its inner edge only, and its own scroll. */
.mt-pane {
  position: relative;
  top: auto;
  max-height: none;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-pill-gap);
  padding: var(--token-layout-aside-pad-y) var(--token-layout-aside-pad-x);
  background: var(--token-color-surface-raised);
  border: 0;
  border-left: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: 0;
}

.pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--token-space-3);
}

/* The column's label and its footnote stay while the turns scroll between
   them, as the board's fixed column shows both. */
.mt-pane > .pane-head {
  position: sticky;
  z-index: var(--token-z-content);
  top: calc(-1 * var(--token-layout-aside-pad-y));
  margin-top: calc(-1 * var(--token-layout-aside-pad-y));
  padding-top: var(--token-layout-aside-pad-y);
  /* A clean edge for the turns scrolling under it, taken back from the first
     turn's own top padding so an unscrolled column sits where the board has it. */
  padding-bottom: var(--token-space-2);
  margin-bottom: calc(-1 * var(--token-space-2));
  background: var(--token-color-surface-raised);
}

.pane-count {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.mt-pane .transcript,
.tr-card .transcript {
  gap: var(--token-layout-pill-gap);
}

/* Two turns of context stay above the one a quote opens: 176px, space-16 × 2
   + space-12 — where the board draws the highlighted turn under its column's
   label. */
.mt-pane .turn,
.tr-card .turn {
  scroll-margin-top: calc(var(--token-space-16) * 2 + var(--token-space-12));
}

.mt-pane .turn-text,
.tr-card .turn-text {
  line-height: 1.5;
}

.mt-pane .turn:target .turn-text,
.tr-card .turn:target .turn-text {
  font-size: calc(var(--token-fs-sm) + var(--token-border-hair));
}

.mt-pane .turn:target .turn-text > p:first-child::before,
.tr-card .turn:target .turn-text > p:first-child::before {
  content: '«';
}

.mt-pane .turn:target .turn-text > p:last-child::after,
.tr-card .turn:target .turn-text > p:last-child::after {
  content: '»';
}

.pane-foot {
  margin-top: auto;
}

.mt-pane > .pane-foot {
  position: sticky;
  z-index: var(--token-z-content);
  bottom: calc(-1 * var(--token-layout-aside-pad-y));
  margin-top: auto;
  margin-bottom: calc(-1 * var(--token-layout-aside-pad-y));
  padding-top: var(--token-space-3);
  padding-bottom: var(--token-layout-aside-pad-y);
  background: var(--token-color-surface-raised);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* The transcript page: the same turns in a card, at a reading width. */
.tr-card {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-pill-gap);
  max-width: calc(var(--token-layout-aside) * 2);
  padding: var(--token-layout-aside-pad-y) var(--token-layout-aside-pad-x);
}

.tr-card > .pr-lead {
  margin-top: var(--token-space-2);
}

.tr-card > p:not(.note) {
  color: var(--token-color-text-secondary);
}

.tr-card .turn {
  display: grid;
  grid-template-columns: var(--token-layout-timecode) minmax(0, 1fr);
  column-gap: var(--token-space-3);
  row-gap: 0;
  padding: var(--token-layout-tab-pad-y) 0;
  border-radius: var(--token-radius-sm);
}

.tr-card .turn-who {
  display: contents;
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.tr-card .turn-at {
  grid-column: 1;
  grid-row: 1 / span 2;
  font-weight: var(--token-weight-regular);
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-tertiary);
}

.tr-card .turn-text {
  grid-column: 2;
  gap: var(--token-space-1);
  max-width: none;
  color: var(--token-color-text-secondary);
}

.mt-pane .turn:target,
.tr-card .turn:target {
  background: var(--token-color-accent-wash);
  padding-inline: var(--token-layout-cell-pad-x);
  margin-inline: calc(-1 * var(--token-layout-cell-pad-x));
}

.mt-pane .turn:target .turn-who,
.mt-pane .turn:target .turn-at,
.tr-card .turn:target .turn-who,
.tr-card .turn:target .turn-at {
  color: var(--token-color-accent-text);
}

.mt-pane .turn:target .turn-text,
.tr-card .turn:target .turn-text {
  color: var(--token-color-text-primary);
}

.tr-card > .pane-foot {
  margin-top: var(--token-space-3);
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
}

/* ------------------------------------------------------------- narrower */

/* Below the two columns the page scrolls as a page again: the column drops
   under the document and keeps a scroll of its own. */
@media (max-width: 1100px) {
  .wrap:has(> .mt-head) {
    height: auto;
    overflow: visible;
  }

  .mt-body.has-pane {
    grid-template-columns: minmax(0, 1fr);
  }

  .mt-main {
    overflow: visible;
  }

  .mt-body.has-pane > .mt-main {
    padding-right: var(--token-layout-page-pad-x);
  }

  /* The side column has nowhere to stand here, and dropped under the page it
     read as the transcript spilling out under the protocol, opened at whatever
     turn it was scrolled to. The «Транскрипт» tab is the transcript on a narrow
     screen; the column comes back only when a citation in the protocol is
     pressed, with that turn in view. */
  .mt-pane {
    display: none;
    max-height: 70vh;
    border-left: 0;
    border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .mt-pane:has(:target) {
    display: flex;
  }
}

@media (max-width: 640px) {
  .mt-head {
    padding: var(--token-space-5) var(--token-space-4) 0;
  }

  .mt-actions {
    gap: var(--token-space-2);
  }

  .mt-main,
  .mt-body.has-pane > .mt-main {
    padding: var(--token-space-5) var(--token-space-4);
  }

  .mt-pane {
    padding: var(--token-space-5) var(--token-space-4);
  }

  .pr-card.pr-card-table {
    overflow-x: auto;
  }

  .pr-table {
    min-width: calc(var(--token-layout-aside) * 1.4);
  }
}

/* ================================================================ p-misc: the meeting before its protocol
   The page with no document yet — no text, text and nothing asked, answers,
   something running, something failed — and the transcript page, in the
   Protocol board's language: the band's buttons right of the title, the
   board's citation chip for a quoted line, its 36px controls, and no
   disclosure triangles. */

/* No tab strip (nothing but this view to show): the band ends under the facts
   line with the 24px it starts with. */
.mt-head.mt-head-bare {
  padding-bottom: var(--token-space-6);
}

/* ---- the band's buttons: renaming and hiding ---- */
.mt-actions > form.inline {
  display: flex;
  margin: 0;
}

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

.mt-rename[open] > summary {
  border-color: var(--token-color-accent-fill);
  color: var(--token-color-accent-text);
}

/* The rename form under its button: one field and «Зберегти», and the line
   about where the name comes from. 364px: the panel minimum and 64px. */
.mt-rename > .menu {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  width: calc(var(--token-layout-panel-min) + var(--token-space-16));
  padding: var(--token-space-3);
  z-index: var(--token-z-sticky);
}

.mt-rename > .menu > form.inline {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  margin: 0;
}

.mt-rename > .menu .field {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--token-layout-control-h);
}

.mt-rename > .menu .field input {
  width: 100%;
}

.mt-rename > .menu > .note {
  margin: 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  line-height: 1.5;
  white-space: normal;
}

/* «Закрити текст»: the rename dropdown's panel — the consequences in a note,
   then «Так, закрити текст» (Q1). Only the confirm sits at the panel's end. */
.mt-access > .menu > form.inline {
  justify-content: flex-end;
}

/* «Поділились з N людьми чи групами» on the head's state line, beside the
   chips, for whoever holds the organiser's powers: a way to the share page
   that lists who, never a bare figure (Q3). */
.mt-shared {
  font-size: var(--token-fs-xs);
  color: var(--token-color-accent-text);
  white-space: nowrap;
}

/* ---- the protocol card before a protocol: the format and the button on
   one baseline, both the board's 36px, the label above on the left ---- */
.pr-note form .kit {
  align-items: flex-end;
  gap: var(--token-space-3);
}

.pr-note form .control {
  align-items: flex-start;
}

.pr-note form .control > .lbl {
  align-self: flex-start;
  text-align: left;
}

.pr-note form .control > select {
  height: var(--token-layout-control-h);
}

.pr-note form > .note {
  margin: 0;
}

/* ---- a quoted line under a lens's claim — the transcript's own words,
   quoted, not concluded: the board's citation chip (`.q`), as wide as its
   words and wrapping inside itself when they run long. Every lens quote is
   inside an answer's card. ---- */
.pr-card .lens-quote {
  display: flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  min-height: var(--token-layout-pill-h);
  margin-top: var(--token-space-2);
  padding: calc(var(--token-space-1) - var(--token-border-hair)) calc(var(--token-space-2) + var(--token-border-hair));
  box-sizing: border-box;
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-left-width: var(--token-border-hair);
  border-radius: calc(var(--token-radius-sm) - var(--token-gap-hair));
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

.pr-card .lens-quote::before {
  content: '“';
  flex: none;
  margin-right: calc(var(--token-space-1) * 1.5);
}

.pr-card .lens-quote::after {
  content: none;
}

/* ---- «Видалити відповідь»: the board's small button, not a fold marker;
   open, it holds the sentence about what deleting costs and the confirm ---- */
.pr-card-foot {
  padding: var(--token-space-3) 0 var(--token-space-4);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--token-space-3);
}

.pr-card-foot > .log {
  gap: var(--token-space-3);
}

.pr-card-foot > .log > summary {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.pr-card-foot > .log > summary::before,
.pr-card-foot > .log[open] > summary::before {
  content: none;
}

.pr-card-foot > .log[open] > summary {
  border-color: var(--token-color-state-crit-text);
  color: var(--token-color-state-crit-text);
}

/* A <details> lays its content out in its own box, so the gaps are margins. */
.pr-card-foot > .log > p {
  margin: var(--token-space-3) 0 0;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.pr-card-foot > .log > form.inline {
  display: flex;
  margin: var(--token-space-3) 0 0;
}

/* ---- the attempts: a line with the board's chevron, not a triangle ---- */
.pr-results > [data-live='attempts'] > .log > summary {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  padding: var(--token-space-1) 0;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.pr-results > [data-live='attempts'] > .log > summary::before {
  content: none;
}

.pr-results > [data-live='attempts'] > .log > summary::after {
  content: '';
  width: calc(var(--token-space-3) + var(--token-gap-hair));
  height: calc(var(--token-space-3) + var(--token-gap-hair));
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
    center / contain no-repeat;
}

.pr-results > [data-live='attempts'] > .log[open] > summary::after {
  transform: rotate(180deg);
}

/* The state beside a running or failed request is the chip; the lens it was
   asked through is the line's quiet label. */
.pr-state .meta-row .note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* ---- the meetings list with no rows (board MeetListA-Plex): the list's own
   card, its sentence and the way out, where the rows would stand ---- */
.panel.list-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-1);
  padding: var(--token-space-5) calc(var(--token-space-5) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
}

.panel.list-empty > * {
  margin: 0;
}

.list-empty-h {
  font-size: calc(var(--token-fs-sm) + var(--token-border-hair));
  color: var(--token-color-text-primary);
}

.list-empty-d {
  max-width: var(--token-measure-lede);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
  line-height: 1.5;
}

.panel.list-empty > .btn {
  margin-top: var(--token-space-3);
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

/* On a phone the rename button is third in its row, so a menu hung from the
   button's own left edge ran 200px past the screen (`left: 0` there is the
   button's x). Hung from the row of actions instead, the menu takes the row's
   width — which is the page's, inside its padding. */
@media (max-width: 640px) {
  .mt-actions {
    position: relative;
  }

  .mt-actions > .mt-rename {
    position: static;
  }

  .mt-rename > .menu {
    left: 0;
    right: 0;
    width: auto;
  }
}

/* A narrow window stacks the side column over the page; the rows keep their
   own heights rather than sharing out the window's. */
@media (max-width: 900px) {
  .app:has(.mt-head),
  .app:has(.list-empty) {
    align-content: start;
  }
}

/* ------------------------------------------------------------ citations */

/* A citation is the claim's small print: the time it was said, after the
   claim on the same line. Bordered «“ цитата · 00:21:35» chips on a row of
   their own under every item made the protocol twice as tall and the
   citations louder than what they cite. */
.pr-at {
  display: inline-block;
  margin-left: var(--token-space-2);
  padding: 0 var(--token-space-1);
  border-radius: var(--token-radius-chip);
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-tertiary);
  text-decoration: none;
  white-space: nowrap;
  vertical-align: baseline;
}

.pr-at::before {
  content: '“\00a0';
}

.pr-from .pr-at {
  margin-left: 0;
}

a.pr-at:hover {
  color: var(--token-color-accent-text);
  text-decoration: underline;
}

/* The one just opened stays marked, and so does the claim it backs, so the
   reader sees which line of the protocol the highlighted turn beside it is
   evidence for. */
a.pr-at:focus,
a.pr-at:target {
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
  outline: none;
}

a.pr-at:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-hair);
}

.pr-item.pr-cited,
.pr-table tr.pr-cited,
.pr-item:has(a.pr-at:focus),
.pr-table tr:has(a.pr-at:focus) {
  background: var(--token-color-accent-wash);
  box-shadow: 0 0 0 var(--token-space-2) var(--token-color-accent-wash);
  border-radius: var(--token-radius-chip);
}

a.pr-at.pr-cited {
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

/* ------------------------------------------------------------- sessions */

/* «Сесії цього дзвінка: 08:48 · 3 хв  09:33 · 4 хв» — the conferences Google
   split one call into, the open one marked as the current tab is. */
.mt-sessions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
}

.mt-session {
  padding: var(--token-gap-hair) var(--token-space-2);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-chip);
  color: var(--token-color-text-secondary);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.mt-session:hover {
  color: var(--token-color-text-primary);
}

.mt-session[aria-current='page'] {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

/* «+ нова папка» beside the line saying where a Google document goes: the
   rename's fold, opened from a link-like word rather than a button. */
.gdoc-new-folder {
  display: inline-block;
  vertical-align: baseline;
}

.gdoc-new-folder > summary {
  display: inline;
  cursor: pointer;
}

/* «+ нова папка» on a category's folder card: under the folder's buttons. */
.cat-new-folder {
  display: inline-block;
  margin-top: var(--token-space-2);
}

.cat-new-folder > summary {
  display: inline;
  cursor: pointer;
}

/* Screen-shaped rules for the meet-pages screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   Four screens of «Зустрічі»: the calendar (CalendarA), the protocol formats
   (FormatsA), the domain coverage (CoverageA) and «Джерела й імпорт», which has
   no board of its own and is drawn in the other three's vocabulary — cards
   with a head bar, tables to the card's edge, notes in the tertiary ink.
   Every class here is prefixed by its screen (cal-, fm-, cov-, sy-), because
   the shared sheets already own `.day`, `.ev` and `.legend` for other pages. */

/* ================================================================ shared */

/* A card that frames what it holds: the board's `.card`. */
.mp-card {
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  overflow: hidden;
  min-width: 0;
}

/* The card's own head: a medium title, a quieter note after it, and the
   card's one action at the far end. */
.mp-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  padding: calc(var(--token-space-3) + var(--token-layout-hair-gap)) var(--token-layout-card-pad-x);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.mp-card-title {
  font-weight: var(--token-weight-medium);
}

.mp-card-head .note {
  font-size: var(--token-fs-xs-plus);
}

.mp-card-head .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

/* The bar at the foot of a card: a sentence, and its way on at the far end. */
.mp-card-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-space-3) var(--token-layout-card-pad-x);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.mp-card-foot .note {
  font-size: var(--token-fs-xs-plus);
}

/* A table drawn to the card's edges, as every board draws one. */
.mp-card > .scroller table,
.mp-card table {
  font-size: var(--token-fs-sm);
}

/* The page's closing line under a card: 13px, tertiary. */
.mp-foot-note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* A page head whose control is on the title's row, bottom-aligned with the
   lede — «Формати протоколів» and «Покриття домену». */
.mp-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--token-space-4);
}

.mp-hero-text {
  flex: 1 1 var(--token-layout-aside);
  min-width: min(var(--token-layout-aside), 100%);
}

.mp-hero h1 {
  font-size: var(--token-fs-h1);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.mp-hero .mp-lede {
  margin: calc(var(--token-space-1) * 1.5) 0 0;
  color: var(--token-color-text-tertiary);
  font-size: var(--token-fs-sm);
  line-height: 1.5;
}

/* Shrinks and wraps rather than running off a phone: the import form is a
   select and a button, wider together than 390px. */
.mp-hero-action {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
}

/* The way back above a page's title — «До зустрічей» on the import page — as
   the meeting page draws its trail: 13px, tertiary, on the title's own left
   edge, 6px above it (space-1 × 1.5), rather than a quiet button whose
   padding set it in from the edge. */
.mp-hero .mp-crumbs {
  margin: 0 0 calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* The boards set every page in 14/1.5; the frame's body is 1.55. */
.wrap:has(> .mp-hero),
.wrap:has(> .cal-head) {
  line-height: 1.5;
}

/* ============================================================== calendar */

/* The month's page starts two pixels higher than the others, as the board. */
.wrap:has(> .cal-head) {
  padding-top: calc(var(--token-layout-page-pad-y) - var(--token-layout-hair-gap));
}

.cal-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
}

.cal-head h1 {
  font-size: var(--token-fs-h1);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-right: var(--token-space-3);
}

.cal-head .btn {
  font-size: var(--token-fs-sm);
}

.cal-legend,
.cal-sum {
  line-height: 1.5;
}

/* The square arrow: a button the height of the row, one glyph in it. */
.cal-nav {
  width: var(--token-layout-control-h);
  padding: 0;
}

.cal-arrow {
  width: var(--token-space-4);
  height: var(--token-space-4);
  flex: none;
}

/* At the edge of what the journal holds the arrow stays in its place, inert. */
.cal-nav[aria-disabled='true'] {
  color: var(--token-color-text-tertiary);
  border-color: var(--token-color-border-subtle);
  cursor: default;
}

.cal-head span.btn[aria-current] {
  cursor: default;
}

/* The legend is the head's give: it takes the room the spacer took, set to
   the right, and folds its own keys onto a second line before anything else
   in the head moves down. A week's title — «21–27 вересня 2026» — is longer
   than a month's, and with the legend as rigid as the buttons it pushed the
   import menu under the title while the month kept one row. */
.cal-head > .grow {
  display: none;
}

.cal-legend {
  display: flex;
  flex: 1 1 0;
  flex-wrap: wrap;
  justify-content: flex-end;
  /* No gap between the two lines: 2 × 18 is the row's 36, so a folded
     legend does not make the head taller than the buttons beside it. */
  gap: 0 var(--token-space-4);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
}

.cal-legend > span {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
}

.cal-legend .cal-dot {
  margin: 0;
}

/* Five working days and a narrow weekend, the lines between cells drawn by
   the grid's own background showing through a hairline gap. */
.cal {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr)) repeat(2, minmax(0, 0.42fr));
  gap: var(--token-border-hair);
  background: var(--token-color-border-subtle);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

/* Rounded corners without `overflow: hidden` on the grid: a day's «+N ще»
   opens over its neighbours and must not be cut by the frame. */
.cal > :first-child {
  border-top-left-radius: calc(var(--token-radius-md) - var(--token-border-hair));
}

.cal > :nth-child(7) {
  border-top-right-radius: calc(var(--token-radius-md) - var(--token-border-hair));
}

.cal > :nth-last-child(7) {
  border-bottom-left-radius: calc(var(--token-radius-md) - var(--token-border-hair));
}

.cal > :last-child {
  border-bottom-right-radius: calc(var(--token-radius-md) - var(--token-border-hair));
}

.cal-h {
  background: var(--token-color-surface-raised);
  padding: var(--token-space-2) var(--token-layout-item-pad-x);
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

/* A fixed height: the month stays a grid of equal weeks, three calls and a
   count per day (DAY_LIMIT), the rest one press away. */
.cal-day {
  position: relative;
  background: var(--token-color-surface-raised);
  height: calc(var(--token-layout-stat-min) + var(--token-space-1) + var(--token-layout-hair-gap));
  padding: var(--token-space-2) var(--token-space-2) calc(var(--token-space-1) * 1.5);
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) - var(--token-gap-hair) / 2);
  min-width: 0;
}

.cal-day.cal-we {
  background: var(--token-color-surface-inset);
}

.cal-day.cal-today {
  box-shadow: inset 0 0 0 var(--token-border-thick) var(--token-color-accent-fill);
}

.cal-dn {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  padding: 0 var(--token-layout-hair-gap) var(--token-layout-hair-gap);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

.cal-today .cal-dn {
  color: var(--token-color-accent-text);
}

/* «3 · сьогодні» broke into «сьогод / ні» in a day 29px wide (WebKit, 1024px
   with the side panel): under a day's width that fits it, the word goes and
   the accent ring alone marks today. */
.cal-day {
  container-type: inline-size;
}

@container (max-width: 80px) {
  .cal-dn-today {
    display: none;
  }
}

.cal-out .cal-dn {
  color: var(--token-color-border-strong);
}

/* The calls clip inside the day; the count under them never does. */
.cal-evs {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) - var(--token-gap-hair) / 2);
  min-height: 0;
  overflow: hidden;
}

.cal-ev {
  display: flex;
  gap: calc(var(--token-space-1) * 1.5);
  align-items: flex-start;
  flex: none;
  font-size: var(--token-fs-xs);
  line-height: var(--token-lh-snug);
  padding: calc(var(--token-space-1) - var(--token-gap-hair) / 2) var(--token-space-1);
  border-radius: var(--token-radius-check);
  color: var(--token-color-text-primary);
  text-decoration: none;
  min-width: 0;
}

a.cal-ev:hover {
  text-decoration: none;
  background: var(--token-color-surface-sunken);
}

/* «Лише запис» sits on the accent's wash, as the board marks the calls that
   have something to open. */
.cal-ev.cal-recording {
  background: var(--token-color-accent-wash);
}

a.cal-ev.cal-recording:hover {
  background: color-mix(in srgb, var(--token-color-accent-wash) 80%, var(--token-color-accent-fill));
}

/* One line per call in a month, cut with «…»: the day has a fixed height for
   three calls, and a title that took two lines pushed the third out of the
   cell with no «+N ще» to say it was there — neither visible nor reachable.
   The full name is the link's title; the week view, which has room, keeps two
   lines of whole words. */
.cal-t {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.cal-t b {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.cal-dot {
  width: var(--token-size-dot-sm);
  height: var(--token-size-dot-sm);
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: var(--token-space-1);
  background: var(--token-color-border-strong);
}

.cal-recording .cal-dot {
  background: var(--token-color-accent-fill);
}

.cal-protocol .cal-dot {
  background: var(--token-color-state-ok-text);
}

/* Text that exists and has not been worked on: the protocol's hue, as a ring. */
.cal-text .cal-dot {
  background: transparent;
  box-shadow: inset 0 0 0 var(--token-border-thick) var(--token-color-state-ok-text);
}

/* «+2 ще»: the rest of the day, opened over the grid. */
.cal-more {
  position: relative;
  flex: none;
}

.cal-more > summary {
  display: inline-block;
  list-style: none;
  cursor: pointer;
  font-size: var(--token-fs-xs);
  line-height: var(--token-lh-snug);
  color: var(--token-color-accent-text);
  padding: 0 var(--token-space-1);
}

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

.cal-more > summary:hover {
  text-decoration: underline;
}

.cal-more-list {
  position: absolute;
  z-index: var(--token-z-sticky);
  left: calc(var(--token-space-1) * -1);
  top: calc(100% + var(--token-space-1));
  width: max(100%, var(--token-layout-card-min) * 0.8);
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) - var(--token-gap-hair) / 2);
  padding: var(--token-space-1);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.cal-sum {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* Below this the seven columns are unreadable, so the month becomes the days
   that have something in them, one under another. */
@media (max-width: 640px) {
  .cal {
    grid-template-columns: minmax(0, 1fr);
  }

  .cal > * {
    border-radius: 0;
  }

  .cal-h,
  .cal-out,
  .cal-empty {
    display: none;
  }

  .cal-day {
    height: auto;
  }

  .cal-head h1 {
    flex-basis: 100%;
  }
}

/* ============================================================== formats */

/* The formats, coverage and import pages space their blocks by 20, the
   calendar by the frame's 18. */
.wrap:has(> .mp-hero) {
  gap: var(--token-space-5);
}

.fm-lede {
  max-width: calc(var(--token-layout-panel-min) * 2 + var(--token-space-5));
}

/* At the personal-format limit the hero says why in place of «Додати» (Q9):
   a note as wide as a panel, not a full-width paragraph beside the title. */
.fm-limit {
  margin: 0;
  max-width: var(--token-layout-panel-min);
  font-size: var(--token-fs-sm);
}

/* The menu under «···» opens over the rows below, so the card does not clip. */
.fm-card {
  overflow: visible;
}

.fm-card caption,
.cov-card caption,
.sy-card caption {
  position: absolute;
  width: var(--token-size-hidden);
  height: var(--token-size-hidden);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  padding: 0;
}

.fm-card th {
  padding: var(--token-layout-head-pad-y) var(--token-layout-card-pad-x);
}

.fm-card td {
  height: calc(var(--token-layout-row-h) + var(--token-layout-item-pad-x));
  padding: 0 var(--token-layout-card-pad-x);
}

.fm-card th:last-child {
  width: calc(var(--token-layout-col-action) + var(--token-layout-item-pad-x));
}

.fm-card td:last-child {
  text-align: right;
  padding-left: 0;
}

.fm-card .row-title {
  font-weight: var(--token-weight-medium);
}

.fm-sample {
  font-size: calc((var(--token-fs-xs) + var(--token-fs-xs-plus)) / 2);
  color: var(--token-color-text-secondary);
}

/* The sample's file name is the way into it, coloured as a link, as the
   approved FormatsA table sets it. */
a.fm-sample {
  text-decoration: none;
  color: var(--token-color-accent-text);
}

a.fm-sample:hover,
.fm-card a.row-title:hover {
  color: var(--token-color-accent-text);
}

.fm-card a.row-title {
  color: inherit;
  text-decoration: none;
}

/* A sample is read, not filled in: the drawer takes twice the form's width. */
.fm-drawer-wide {
  width: min(100%, calc(var(--token-layout-aside) * 2));
}

.fm-sample-text {
  flex-grow: 1;
  margin: 0;
  padding: var(--token-space-4);
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  line-height: 1.55;
  background: var(--token-color-surface-sunken);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

.fm-date {
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

/* Who sees a format: a word on a plate, not a state — no glyph. */
.fm-pill {
  display: inline-flex;
  align-items: center;
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  border-radius: var(--token-radius-pill);
  font-size: var(--token-fs-xs);
  line-height: 1;
  white-space: nowrap;
}

.fm-pill-org {
  color: var(--token-color-state-info-text);
  background: var(--token-color-state-info-bg);
}

.fm-pill-personal {
  color: var(--token-color-state-neutral-text);
  background: var(--token-color-state-neutral-bg);
}

.fm-acts {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--token-space-1);
}

.fm-acts form.inline {
  display: inline-flex;
}

/* «···»: a quiet square beside the row's button, opening a card of two links. */
.fm-more > summary.fm-dots {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  background: transparent;
  border-color: transparent;
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs-plus);
  letter-spacing: 0;
}

.fm-more > summary.fm-dots:hover,
.fm-more[open] > summary.fm-dots {
  background: var(--token-color-surface-sunken);
}

.fm-more .menu {
  min-width: calc(var(--token-layout-field-basis) * 0.7);
  text-align: left;
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

/* ---- the drawer ---- */

/* The scrim is the board's ink at 28%; the dark theme darkens instead of
   lightening. (A `--token-color-scrim` would say this once.) */
.fm-sheet {
  --mp-scrim: color-mix(in srgb, var(--token-color-text-primary) 28%, transparent);
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--token-z-skip);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .fm-sheet {
    --mp-scrim: color-mix(in srgb, var(--token-color-surface-sunken) 70%, transparent);
  }
}

:root[data-theme='dark'] .fm-sheet {
  --mp-scrim: color-mix(in srgb, var(--token-color-surface-sunken) 70%, transparent);
}

.fm-sheet:target {
  display: block;
}

.fm-scrim {
  position: absolute;
  inset: 0;
  background: var(--mp-scrim);
  cursor: default;
}

.fm-drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(100%, calc(var(--token-layout-aside) + var(--token-space-12) + var(--token-space-3)));
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-5);
  padding: var(--token-layout-aside-pad-x) var(--token-layout-page-pad-y);
  background: var(--token-color-surface-raised);
  border-left: var(--token-border-hair) solid var(--token-color-border-subtle);
  box-shadow: calc(var(--token-space-3) * -1) 0 var(--token-space-10) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  line-height: 1.5;
}

.fm-drawer-head {
  display: flex;
  align-items: center;
}

.fm-drawer-head h2 {
  flex-grow: 1;
  font-size: calc(var(--token-fs-lg) + var(--token-layout-hair-gap));
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.fm-close {
  width: auto;
  background: transparent;
  border-color: transparent;
  color: var(--token-color-text-secondary);
}

.fm-close:hover {
  background: var(--token-color-surface-sunken);
}

.fm-field,
.fm-group {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) * 1.5);
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.fm-group {
  gap: var(--token-space-2);
}

.fm-lbl {
  padding: 0;
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
}

/* A fieldset's legend does not take part in the column's gap. */
.fm-group > legend.fm-lbl {
  margin-bottom: var(--token-space-2);
}

.fm-inp {
  height: calc(var(--token-layout-control-h) + var(--token-space-1));
  width: 100%;
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  font: inherit;
}

.fm-inp::placeholder {
  color: var(--token-color-text-tertiary);
}

.fm-inp:focus {
  outline: none;
  border-color: var(--token-color-accent-fill);
  box-shadow: 0 0 0 var(--token-border-hair) var(--token-color-accent-fill);
}

/* A choice is a card: the chosen one takes the accent's border and wash. */
.fm-radio {
  display: flex;
  gap: var(--token-space-3);
  align-items: flex-start;
  padding: var(--token-space-3) calc(var(--token-space-3) + var(--token-layout-hair-gap));
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-seg);
  cursor: pointer;
}

.fm-radio:has(input:checked) {
  border: var(--token-border-thick) solid var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
}

.fm-radio:has(input:disabled) {
  cursor: not-allowed;
}

.fm-radio:has(input:disabled) .fm-radio-t {
  color: var(--token-color-text-tertiary);
}

.fm-radio input[type='radio'] {
  margin-top: var(--token-border-hair);
}

.fm-radio input[type='radio']::before {
  width: var(--token-size-dot);
  height: var(--token-size-dot);
}

/* A disabled choice keeps its outline readable: it says who may, not «broken». */
.fm-radio input[type='radio']:disabled {
  opacity: 1;
  background: var(--token-color-surface-inset);
}

.fm-radio-text {
  display: flex;
  flex-direction: column;
}

.fm-radio-t {
  font-weight: var(--token-weight-medium);
}

.fm-radio-d {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* The sample: the browser's own file input, stretched invisibly over a drop
   area we draw. Dropping a file on it and clicking it are the input's own
   behaviour, so both work with scripting off. */
.fm-drop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--token-space-2);
  padding: calc(var(--token-space-6) + var(--token-layout-hair-gap));
  border: var(--token-border-check) dashed var(--token-color-border-strong);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-inset);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--token-dur-fast), background-color var(--token-dur-fast);
}

.fm-drop:hover,
.fm-drop:has(.fm-file:focus-visible) {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
}

.fm-drop:has(.fm-file:focus-visible) {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-thick);
}

.fm-drop input.fm-file {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}

.fm-drop-icon {
  width: calc(var(--token-space-5) + var(--token-layout-hair-gap));
  height: calc(var(--token-space-5) + var(--token-layout-hair-gap));
  color: var(--token-color-text-tertiary);
}

.fm-drop b {
  font-weight: var(--token-weight-medium);
}

.fm-link {
  color: var(--token-color-accent-text);
}

.fm-drop-h,
.fm-hint {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* Chosen: the area says so in the accent, and offers the other file. */
.fm-drop-ok {
  display: none;
}

.fm-drop:has(.fm-file:valid) {
  border-style: solid;
  border-color: var(--token-color-accent-fill);
}

.fm-drop:has(.fm-file:valid) .fm-drop-t {
  display: none;
}

.fm-drop:has(.fm-file:valid) .fm-drop-ok {
  display: inline;
}

.fm-drop:has(.fm-file:valid) .fm-drop-icon {
  color: var(--token-color-accent-fill);
}

.fm-grow {
  flex-grow: 1;
}

.fm-actions {
  display: flex;
  gap: var(--token-layout-item-pad-x);
  justify-content: flex-end;
}

/* One button per endpoint, shown by the audience chosen above them. */
.fm-drawer:has(input[name='scope'][value='org']:checked) .fm-sub-personal,
.fm-drawer:not(:has(input[name='scope'][value='org']:checked)) .fm-sub-org {
  display: none;
}

.fm-remove-name {
  font-weight: var(--token-weight-medium);
}

.fm-remove-d {
  color: var(--token-color-text-secondary);
}

/* A glyph before a button's words, the board's 16px. */
.mp-icon {
  width: var(--token-space-4);
  height: var(--token-space-4);
  flex: none;
}

/* ============================================================= coverage */

/* Four figures a row where they fit, fewer where they do not — never a
   figure's line cut at its card's edge. */
.cov-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(calc(var(--token-layout-panel-min) / 2), 100%), 1fr));
  gap: calc(var(--token-space-3) + var(--token-layout-hair-gap));
}

.cov-kpi {
  padding: calc(var(--token-space-4) + var(--token-layout-hair-gap)) var(--token-space-5);
}

.cov-kpi-l {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.cov-kpi-v {
  margin-top: calc(var(--token-space-1) * 1.5);
  font-family: var(--token-font-display);
  font-size: var(--token-fs-hero-min);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
}

.cov-kpi-crit {
  color: var(--token-color-state-crit-text);
}

.cov-kpi-of {
  font-size: calc(var(--token-fs-md) + var(--token-layout-hair-gap));
  color: var(--token-color-text-tertiary);
}

.cov-kpi-s {
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

@media (max-width: 900px) {
  .cov-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.cov-card th {
  padding: var(--token-layout-head-pad-y) calc(var(--token-space-3) + var(--token-layout-hair-gap));
}

.cov-card td {
  height: calc(var(--token-space-10) + var(--token-space-1) + var(--token-layout-hair-gap));
  padding: 0 calc(var(--token-space-3) + var(--token-layout-hair-gap));
}

.cov-card th.num,
.cov-card td.cov-rank {
  text-align: left;
}

.cov-card th.cov-rank {
  width: var(--token-space-10);
}

.cov-card td.cov-rank {
  color: var(--token-color-text-tertiary);
}

.cov-c-count {
  width: calc(var(--token-layout-card-min) + var(--token-layout-item-pad-x));
}

.cov-c-share {
  width: calc(var(--token-layout-field-basis) + var(--token-layout-item-pad-x));
}

.cov-c-state {
  width: calc(var(--token-layout-col-when) - var(--token-space-5));
}

/* 110, the board's: the state pill is a plain word now, as it draws it. */
.cov-c-act {
  width: calc(var(--token-layout-col-duration) + var(--token-layout-item-pad-x));
}

.cov-card td.cov-act {
  text-align: right;
  padding-left: 0;
}

.cov-card td.cov-act > a:not(.btn) {
  color: var(--token-color-accent-text);
  font-weight: var(--token-weight-regular);
}

.cov-who {
  overflow-wrap: anywhere;
}

.cov-count {
  display: flex;
  align-items: center;
  gap: var(--token-layout-item-pad-x);
  min-width: 0;
}

.cov-n {
  width: var(--token-space-6);
  flex: none;
  font-variant-numeric: tabular-nums;
}

.cov-pct {
  font-variant-numeric: tabular-nums;
}

/* The two bars are `<progress>`: the value is an attribute, so no inline
   style is needed for a width the CSP would refuse to apply. */
.cov-count progress {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  /* Gives way before the share beside it does: on a phone a 180px bar pushed
     the «5%» past the card's edge. */
  flex: 0 1 auto;
  min-width: 0;
  border: 0;
  margin: 0;
  padding: 0;
}

/* The count: the accent, as long as the busiest organiser's is the whole
   track, with no track drawn. */
progress.cov-hb {
  width: calc(var(--token-layout-col-state) + var(--token-layout-item-pad-x));
  height: var(--token-space-2);
  background: transparent;
}

progress.cov-hb::-webkit-progress-bar {
  background: transparent;
}

progress.cov-hb::-webkit-progress-value {
  background: color-mix(in srgb, var(--token-color-accent-fill) 80%, transparent);
  border-radius: var(--token-inset-chip);
}

progress.cov-hb::-moz-progress-bar {
  background: color-mix(in srgb, var(--token-color-accent-fill) 80%, transparent);
  border-radius: var(--token-inset-chip);
}

/* The running share: a quiet bar on a sunken track, the accent on the line. */
progress.cov-cb {
  width: calc(var(--token-space-24) + var(--token-space-6));
  height: calc(var(--token-space-1) * 1.5);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

progress.cov-cb::-webkit-progress-bar {
  background: var(--token-color-surface-sunken);
  border-radius: var(--token-radius-pill);
}

progress.cov-cb::-webkit-progress-value {
  background: var(--token-color-text-tertiary);
  border-radius: var(--token-radius-pill);
}

progress.cov-cb::-moz-progress-bar {
  background: var(--token-color-text-tertiary);
  border-radius: var(--token-radius-pill);
}

.cov-mark progress.cov-cb::-webkit-progress-value {
  background: var(--token-color-accent-fill);
}

.cov-mark progress.cov-cb::-moz-progress-bar {
  background: var(--token-color-accent-fill);
}

.cov-mark .cov-pct {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-accent-text);
}

/* The line under the row that crosses half the domain. */
.cov-card tr.cov-mark > td {
  border-bottom: var(--token-border-thick) solid var(--token-color-accent-fill);
}

/* Past the line, folded until «Показати всіх» targets the card. */
.cov-card tr.cov-rest,
.cov-hide {
  display: none;
}

.cov-card:target tr.cov-rest {
  display: table-row;
}

.cov-card:target .cov-show {
  display: none;
}

.cov-card:target .cov-hide {
  display: inline;
}

/* The last visible row has no rule of its own; the foot's border is it. */
.cov-card:not(:target) tbody tr:has(+ .cov-rest) > td {
  border-bottom-width: var(--token-border-thick);
}

.cov-guests {
  margin-top: var(--token-space-2);
}

/* ======================================================= sources & import */

/* The connection, as the meetings list's import line: dot, state, gloss, and
   the one action at the far end — here a small ghost button. */
.sy-conn .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.sy-lede {
  max-width: calc(var(--token-layout-panel-min) * 2 + var(--token-space-5));
}

.sy-form {
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.sy-form select {
  height: var(--token-layout-control-h);
}

/* What the next import does, and how far Meet reaches: the page's small print,
   one paragraph each, at a reading width. */
.sy-notes {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  max-width: calc(var(--token-layout-panel-min) * 3);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.sy-notes-h {
  color: var(--token-color-text-secondary);
  font-weight: var(--token-weight-medium);
}

/* The last import and its sources stack like every other block on the page. */
[data-live='import'] {
  gap: var(--token-space-5);
}

.sy-body {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: calc(var(--token-space-3) + var(--token-layout-hair-gap)) var(--token-layout-card-pad-x);
}

.sy-body .desc {
  color: var(--token-color-text-primary);
}

.sy-card th {
  padding: var(--token-layout-head-pad-y) calc(var(--token-space-3) + var(--token-layout-hair-gap));
}

.sy-card td {
  height: calc(var(--token-space-10) + var(--token-space-1) + var(--token-layout-hair-gap));
  padding: var(--token-space-2) calc(var(--token-space-3) + var(--token-layout-hair-gap));
}

.sy-card th:first-child,
.sy-card td:first-child {
  padding-left: var(--token-layout-card-pad-x);
}

.sy-card th:last-child,
.sy-card td:last-child {
  padding-right: var(--token-layout-card-pad-x);
}

.sy-card .mp-card-foot .note {
  max-width: calc(var(--token-layout-panel-min) * 3);
}

.sy-history .cell-note {
  font-size: var(--token-fs-xs);
}

/* Eleven columns: the headings wrap, as the kit's tables allow, and the
   figures keep one line each. A number column keeps room for two words a line,
   so «Без запису і тексту» is two lines, not four. */
.sy-history th {
  white-space: normal;
}

.sy-card th.num {
  min-width: 6.5em;
}

/* The import tables stack into cards by the CARD's width, not the window's:
   with the side panel the card is far narrower than the window, and nine to
   eleven columns left it — the last ones cut off by the card's edge, the
   headings three words tall. Below what they need, each import is a card of
   label / value lines, as every wide table is on a phone. */
.sy-card {
  container-type: inline-size;
}

@container (max-width: 1100px) {
  .sy-card .stack table,
  .sy-card .stack tbody,
  .sy-card .stack tr,
  .sy-card .stack td {
    display: block;
    width: 100%;
  }

  .sy-card .stack thead {
    position: absolute;
    width: var(--token-size-hidden);
    height: var(--token-size-hidden);
    overflow: hidden;
    clip-path: inset(50%);
  }

  .sy-card .stack tr {
    padding: var(--token-space-3) var(--token-layout-card-pad-x);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .sy-card .stack td,
  .sy-card .stack td:first-child,
  .sy-card .stack td:last-child {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--token-space-4);
    height: auto;
    padding: var(--token-space-1) 0;
    border-bottom: 0;
  }

  .sy-card .stack td[data-label]::before {
    content: attr(data-label);
    flex: none;
    max-width: 50%;
    font-family: var(--token-font-body);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }

  .sy-card .stack td > .cv {
    min-width: 0;
    text-align: right;
  }
}

/* Between a phone and the full table, a stacked import read as a column of
   labels on the left edge and figures on the right one, a card's width apart
   («криво»). With room for it, each import is a grid of small figures —
   label over value, several to a line — like the summary it repeats. */
@container (min-width: 440px) and (max-width: 1100px) {
  .sy-card .stack tr {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(calc(var(--token-space-16) * 2.25), 1fr));
    gap: var(--token-space-2) var(--token-space-4);
  }

  .sy-card .stack td,
  .sy-card .stack td:first-child,
  .sy-card .stack td:last-child {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--token-space-1);
    min-height: 0;
  }

  .sy-card .stack td[data-label]::before {
    max-width: none;
  }

  .sy-card .stack td > .cv {
    text-align: left;
  }
}

.sy-when {
  white-space: nowrap;
}

.sy-body > .grid {
  gap: var(--token-space-2);
}

/* ================================================================= week */
/* A week has the room a month does not: every call of the day, no fold. */
.cal-week .cal-day {
  height: auto;
  min-height: calc(var(--token-layout-stat-min) * 3);
}

.cal-week .cal-evs {
  overflow: visible;
}

.cal-week .cal-t {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal;
  text-overflow: clip;
  /* Whole words, hyphenated where the language allows: `anywhere` cut a title
     into «Архітектура, інфраструкт / ура» in a narrow day. A word longer than
     the day still breaks — there is no other way for it to fit. */
  overflow-wrap: break-word;
  hyphens: auto;
}

.cal-head .seg {
  margin-left: var(--token-space-2);
}

/* The board draws the coverage state as a word on a neutral pill, no glyph. */
.cov-who ~ td .badge-icon {
  display: none;
}

/* The board clips a day's calls at the cell's own edge, not at its padding:
   the last line keeps the 6px under it. */
.cal-evs {
  overflow: clip;
  overflow-clip-margin: calc(var(--token-space-1) * 1.5);
}

/* ======================================================= restored items */

/* The protocol's own title at the head of the document, with its version and
   date beside it in the quiet ink. One step above the sections' headings. */
.pr-doc-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-1) var(--token-space-3);
}

.pr-doc-head .pr-doc-title {
  margin: 0;
  font-size: var(--token-fs-xl);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.pr-doc-head .note {
  font-size: var(--token-fs-xs-plus);
}

/* The import line's second row: why the last import failed, or what it found. */
.import-line > .mp-import-detail {
  flex-basis: 100%;
  color: var(--token-color-text-secondary);
}

.import-line > .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

/* «Підтягнути з Google ▾»: the depth choice as the dropdown's menu, each depth
   a submit button of one form. */
.mp-import .menu {
  z-index: 6;
}

.mp-depth {
  display: grid;
  gap: var(--token-gap-hair);
}

.mp-depth-h {
  margin: 0;
  padding: var(--token-space-1) var(--token-space-3);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
}

/* A hidden row's action and its way back, one under the other, at the
   action column's right edge. */
.mp-row-acts {
  justify-items: end;
}

/* The list row's action, then its «···» with the rename form, at the action
   column's right edge. */
.mp-row-tools {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--token-space-1);
}

.mp-row-rename > .menu {
  text-align: left;
}

/* A .md sample, drawn as the protocol it shapes: the same cards, on the
   sunken ground the plain-text sample sits on, scrolling on its own. */
.fm-sample-doc {
  flex-grow: 1;
  overflow: auto;
  padding: var(--token-space-4);
  background: var(--token-color-surface-sunken);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

/* ======================================================= stacked tables */

/* The meetings screens' tables as cards, below the width where their columns
   fit (app.css's `.stack`, 900). The shared rule stacks the cells; what it
   left to each screen made these unreadable at 820 with the side column
   open: every cell kept its table-row height (50, 60) so a card was a tall
   column of gaps, the empty tick cell of a row with nothing to select drew a
   blank band on top of every card, and the labels sat on the card's edge
   because the row had no inset of its own — only the first and last cells
   did, so «Дії» and «Запущено» started 16 further in than the rest.

   Here the ROW carries the card's inset, the cells lose their row height and
   their own edge padding, a cell with nothing in it is not drawn, a cell with
   no name (the tick, the action) keeps its content at its natural side, and a
   row's detail line joins its row's card instead of starting a new one. */
@media (max-width: 900px) {
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack tr {
    padding: var(--token-space-3) var(--token-layout-card-pad-x);
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td,
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:first-child,
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:last-child {
    height: auto;
    min-height: var(--token-layout-control-h-sm);
    padding: var(--token-space-1) 0;
    border-bottom: 0;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:empty,
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:has(> .cv:empty) {
    display: none;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td[data-label='']::before {
    content: none;
  }

  /* The tick leads its card; an unnamed action closes it at the right. */
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td.tick {
    justify-content: flex-start;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td[data-label='']:not(.tick),
  .cov-card .scroller.stack td.cov-act {
    justify-content: flex-end;
  }

  /* A row and the line under it are one card. */
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack tr:has(+ tr > td.detail) {
    padding-bottom: 0;
    border-bottom: 0;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack tr:has(> td.detail) {
    padding-top: var(--token-space-1);
  }

  /* The half-the-domain line, on the card rather than on each of its cells. */
  .cov-card .scroller.stack tr.cov-mark {
    border-bottom: var(--token-border-thick) solid var(--token-color-accent-fill);
  }

  .cov-card:target .scroller.stack tr.cov-rest {
    display: block;
  }
}

/* The stacked rows above, by the table's own width too (see `.scroller.stack`
   in app.css): a narrow card in a wide window is cards as well. */
@container (max-width: 860px) {
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack tr {
    padding: var(--token-space-3) var(--token-layout-card-pad-x);
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td,
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:first-child,
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:last-child {
    height: auto;
    min-height: var(--token-layout-control-h-sm);
    padding: var(--token-space-1) 0;
    border-bottom: 0;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:empty,
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td:has(> .cv:empty) {
    display: none;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td[data-label='']::before {
    content: none;
  }

  /* The tick leads its card; an unnamed action closes it at the right. */
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td.tick {
    justify-content: flex-start;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack td[data-label='']:not(.tick),
  .cov-card .scroller.stack td.cov-act {
    justify-content: flex-end;
  }

  /* A row and the line under it are one card. */
  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack tr:has(+ tr > td.detail) {
    padding-bottom: 0;
    border-bottom: 0;
  }

  :is([data-live='meetings'], .fm-card, .cov-card, .sy-card) .scroller.stack tr:has(> td.detail) {
    padding-top: var(--token-space-1);
  }

  /* The half-the-domain line, on the card rather than on each of its cells. */
  .cov-card .scroller.stack tr.cov-mark {
    border-bottom: var(--token-border-thick) solid var(--token-color-accent-fill);
  }

  .cov-card:target .scroller.stack tr.cov-rest {
    display: block;
  }
}

/* ============================================== питання й відповіді */

/* The cards stack with the page's own rhythm; each holds one topic. */
.faq-card + .faq-card {
  margin-top: var(--token-space-4);
}

/* One question per row: the question is the row's title, the answer opens
   under it. `<details>`, so it works with scripting off. */
.faq-item {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.mp-card-head + .faq-item {
  border-top: 0;
}

/* The answer starts where the question's words start, not under the arrow:
   both are indented by the same `--faq-indent`, and the arrow sits in it. */
.faq-item {
  --faq-indent: calc(var(--token-layout-card-pad-x) + 1.25em);
}

.faq-item > summary {
  position: relative;
  cursor: pointer;
  list-style: none;
  padding: var(--token-space-3) var(--token-layout-card-pad-x) var(--token-space-3) var(--faq-indent);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

/* The arrow is drawn here for the reason `.log` draws its own: Safari's
   ::marker cannot be styled, and the webkit marker would make two. */
.faq-item > summary::before {
  content: '▸';
  position: absolute;
  left: var(--token-layout-card-pad-x);
  color: var(--token-color-text-tertiary);
}

.faq-item[open] > summary::before {
  content: '▾';
}

/* The ring is drawn inside the row: the card clips nothing, so an outer
   ring would spill past the card's edge. */
.faq-item > summary:focus-visible {
  outline-offset: calc(-1 * var(--token-border-thick));
}

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

.faq-item > summary:hover {
  color: var(--token-color-accent-text);
}

.faq-a {
  padding: 0 var(--token-layout-card-pad-x) var(--token-space-4) var(--faq-indent);
  color: var(--token-color-text-secondary);
  line-height: var(--token-lh-relaxed);
}

.faq-a p {
  margin: 0;
}

.faq-a .faq-link {
  margin-top: var(--token-space-2);
}

/* A question opened from a link is the one the reader came for. */
.faq-item:target > summary {
  color: var(--token-color-accent-text);
}

/* ======================================= категорії, поділитися, Google */

/* The tabs over the list: every call, the shared ones, each category. A row
   that wraps on a narrow screen rather than scrolling sideways. */
.mp-tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-1);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  margin-bottom: var(--token-space-4);
}

.mp-tab {
  padding: var(--token-space-2) var(--token-space-3);
  color: var(--token-color-text-secondary);
  text-decoration: none;
  border-bottom: var(--token-border-thick) solid transparent;
  font-size: var(--token-fs-sm);
}

.mp-tab:hover {
  color: var(--token-color-text-primary);
}

.mp-tab[aria-current='page'] {
  color: var(--token-color-accent-text);
  border-bottom-color: var(--token-color-accent-fill);
}

.mp-tab-count {
  color: var(--token-color-text-tertiary);
  margin-left: var(--token-space-1);
}

.mp-tab-new {
  color: var(--token-color-text-tertiary);
}

.mp-tabs > .grow {
  flex: 1 1 auto;
}

/* «Категорії ▾» on a call: one press per category. */
.mt-cats > summary::-webkit-details-marker {
  display: none;
}

.mt-cats[open] > summary {
  border-color: var(--token-color-accent-fill);
  color: var(--token-color-accent-text);
}

.mt-cats > .menu {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  min-width: var(--token-layout-panel-min);
  padding: var(--token-space-2);
  z-index: var(--token-z-sticky);
}

.mt-cats > .menu > form.inline {
  display: flex;
  margin: 0;
}

.mt-cat-item {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  width: 100%;
  padding: var(--token-space-2) var(--token-space-3);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: transparent;
  color: var(--token-color-text-primary);
  font: inherit;
  font-size: var(--token-fs-sm);
  text-align: left;
  cursor: pointer;
}

.mt-cat-item:hover {
  background: var(--token-color-surface-sunken);
}

.mt-cat-box {
  display: inline-grid;
  place-items: center;
  width: var(--token-fs-md);
  height: var(--token-fs-md);
  flex: none;
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  color: var(--token-color-accent-text);
  font-size: var(--token-fs-xs);
}

.mt-cat-item[aria-pressed='true'] .mt-cat-box {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
}

.mt-cat-empty {
  margin: 0;
  padding: var(--token-space-2) var(--token-space-3);
}

/* «Поділитися» and «Налаштувати категорію»: cards with a body. */
.sh-card + .sh-card,
.cat-card + .cat-card {
  margin-top: var(--token-space-4);
}

.sh-body,
.cat-body {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  padding: var(--token-space-4) var(--token-layout-card-pad-x);
}

.sh-body p,
.cat-body p {
  margin: 0;
}

.sh-add {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--token-space-2);
}

.sh-add .field {
  flex: 1 1 var(--token-layout-field-basis);
  min-width: 0;
}

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

.sh-row {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-space-2) 0;
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.sh-row:first-child {
  border-top: 0;
}

.sh-who {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}

/* «Група Google» under the address is a chip as wide as its word: a column
   stretches its children, and the chip ran the whole width of the row. */
.sh-who > .badge {
  align-self: flex-start;
}

.sh-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.cat-rules {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  margin: 0;
  padding: 0;
  border: 0;
}

.cat-rules > legend {
  padding: 0;
  margin-bottom: var(--token-space-2);
  font-weight: var(--token-weight-medium);
}

.cat-count {
  padding: var(--token-space-3);
  border-radius: var(--token-radius-md);
  background: var(--token-color-accent-wash);
}

.cat-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--token-space-2);
}

.cat-danger {
  flex-direction: row;
  align-items: center;
}

/* The «···» a row without it would have: its width, so the buttons align. */
.mp-row-dots-slot {
  visibility: hidden;
  pointer-events: none;
}

/* Screen-shaped rules for the platform-pages screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   Three pages, each wrapped in its own block so nothing here reaches another
   screen: `.home` (the front page, board Main), `.acc` (Доступи, board AdminA)
   and `.usage` (Витрати — no board of its own, drawn in AdminA's language).
   Values the tokens lack are composed from them with calc(); the report lists
   the tokens these would have been. */

/* ================================================================ shared */

/* The page frame of these three boards: the frame's own sides — the same
   `page-pad-x` as every other page, so the column starts at one x whichever
   page is open — 36px above the front page and 32px above the
   administration pages. */
.wrap:has(> .home) {
  padding-top: calc(var(--token-space-8) + var(--token-space-1));
}

.wrap:has(> .acc),
.wrap:has(> .usage) {
  padding-top: var(--token-space-8);
}

.home,
.acc,
.usage {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.5;
}

.home > *,
.acc > *,
.usage > * {
  margin: 0;
}

/* ================================================================ home */

.home {
  gap: calc(var(--token-space-6) + var(--token-space-1));
}

.home-top h1 {
  font-size: calc(var(--token-fs-h1) + var(--token-gap-hair));
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.home-status {
  margin: var(--token-space-2) 0 0;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.home-date {
  margin: 0 0 calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* As many product cards a row as fit at a panel's width each. Two columns by
   the window's width left a 238px card at 820px with the side panel open, and
   its three figures 58px each — «з протоколом» broken between its letters. */
.home-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--token-layout-panel-min), 100%), 1fr));
  gap: var(--token-space-4);
}

.home-card {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
  padding: calc(var(--token-space-5) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-sm);
}

.home-card > * {
  margin: 0;
}

.home-card-head {
  display: flex;
  align-items: center;
  gap: var(--token-layout-brand-gap);
}

.home-card-head h2 {
  font-size: var(--token-fs-lg);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.home-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--token-layout-control-h);
  height: var(--token-layout-control-h);
  border-radius: var(--token-radius-seg);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.home-icon svg {
  width: calc(var(--token-space-4) + var(--token-gap-hair));
  height: calc(var(--token-space-4) + var(--token-gap-hair));
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.home-desc {
  color: var(--token-color-text-secondary);
}

.home-card > .note {
  font-size: var(--token-fs-xs-plus);
}

.home-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--token-space-2);
  padding: var(--token-space-3) 0;
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

/* The figure above its words; the words come first in the markup, as a term
   comes before its value. */
.home-stats > div {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  min-width: 0;
}

.home-stats dd {
  margin: 0;
  font-family: var(--token-font-display);
  font-size: calc(var(--token-fs-lg) + var(--token-gap-hair));
  line-height: 1.15;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-primary);
}

.home-stats dd.crit {
  color: var(--token-color-state-crit-text);
}

.home-stats dt {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.home-act {
  display: flex;
}

.home-act .btn {
  align-self: flex-start;
}

/* A role or a promise, not a state: the board draws these pills without a glyph. */
.home-act .badge-icon {
  display: none;
}

/* An announced product: dashed, inset and quieter in every part. */
.home-soon {
  background: var(--token-color-surface-inset);
  border-style: dashed;
}

.home-soon .home-icon {
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-tertiary);
}

.home-soon h2 {
  color: var(--token-color-text-secondary);
}

.home-soon .home-desc {
  color: var(--token-color-text-tertiary);
}

.home-soon .grow {
  flex: 1 1 auto;
}

/* ================================================================ access
   Board AdminA: heading and its action, the search and the segments, the
   table in a card, the legend, and the dark bar while anything is unsaved. */

.acc {
  gap: var(--token-space-5);
}

.acc .hero .lede,
.usage .hero .lede {
  max-width: none;
  color: var(--token-color-text-tertiary);
  line-height: 1.5;
}

.acc .hero .btn-icon {
  min-width: 0;
  padding: 0;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  fill: none;
}

/* ---- the strip ---- */
.acc-bar {
  gap: var(--token-space-3);
  margin: 0;
}

/* The board's search is wider than the meetings list's: 300 against 240. */
.acc-bar form.inline > .field {
  flex: 0 1 var(--token-layout-panel-min);
  width: var(--token-layout-panel-min);
  min-width: 0;
}

.acc-bar .field input {
  width: 100%;
  padding: 0;
}

.acc-bar .seg a {
  color: var(--token-color-text-secondary);
}

.acc-bar .seg a[aria-current='true'] {
  color: var(--token-color-text-primary);
}

/* ---- the table ---- */
.acc caption {
  position: absolute;
  width: var(--token-size-hidden);
  height: var(--token-size-hidden);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.acc th {
  padding: var(--token-layout-head-pad-y) var(--token-space-4);
}

.acc td {
  height: auto;
  padding: var(--token-space-3) var(--token-space-4);
  line-height: 1.5;
}

/* The board keeps a column at the right for a row menu («···», 74px with its
   padding). There are no row actions yet, so the column is an empty cell drawn
   by the stylesheet: the other columns keep the board's widths, and nothing
   pretends to be a control. */
@media (min-width: 901px) {
  .acc .scroller tr::after {
    content: '';
    display: table-cell;
    width: calc(var(--token-space-16) + var(--token-space-2) + var(--token-gap-hair));
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .acc .scroller tbody tr:last-child::after {
    border-bottom: 0;
  }
}

.acc th:last-child,
.acc td:last-child {
  padding-right: var(--token-space-4);
}

.acc-seen {
  color: var(--token-color-text-secondary);
}

.acc .person {
  gap: var(--token-space-3);
}

.acc .person-who {
  gap: var(--token-inset-chip);
}

.acc .avatar {
  width: var(--token-layout-avatar);
  height: var(--token-layout-avatar);
  font-size: var(--token-fs-xs);
}

.acc .avatar-other {
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-secondary);
}

.acc .row-title {
  font-weight: var(--token-weight-medium);
}

.acc-you {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
}

/* «Адмін платформи» is a role, drawn as the board's small pill with no glyph. */
.acc .person-who .badge {
  height: var(--token-layout-pill-h-sm);
  font-size: var(--token-fs-2xs);
}

.acc .person-who .badge-icon {
  display: none;
}

/* A level control: the board's 32px select with its chevron, one per product. */
.acc td .control {
  display: inline-flex;
}

.acc select {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--token-space-2);
  height: calc(var(--token-layout-control-h-sm) + var(--token-gap-hair));
  min-width: var(--token-layout-col-when);
  padding: 0 var(--token-layout-control-pad-x-sm);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background-color: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  font: inherit;
  font-size: var(--token-fs-xs-plus);
}

@supports (appearance: base-select) {
  .acc select::picker-icon {
    content: '';
    width: calc(var(--token-space-3) + var(--token-gap-hair));
    height: calc(var(--token-space-3) + var(--token-gap-hair));
    background: currentColor;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
      center / contain no-repeat;
  }

  .acc select option {
    font-size: var(--token-fs-xs-plus);
  }
}

/* Changed and not saved: the accent frame, and what it was under it. The
   control still holds the option the server marked `selected`, so no script
   is needed to tell. */
.acc-was {
  display: none;
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-accent-text);
}

.acc td:has(select option:checked:not([selected])) select {
  border-color: var(--token-color-accent-fill);
  background-color: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.acc td:has(select option:checked:not([selected])) .acc-was {
  display: block;
}

/* ---- cards: the invite ---- */
.acc-card {
  padding: var(--token-space-4) var(--token-space-5);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-sm);
}

.acc-card > * {
  margin: 0;
}

.acc-card-title {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  letter-spacing: 0;
}

.acc-card-note {
  margin-top: var(--token-gap-hair);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* The invite opens from the heading's button and stays open while it says
   why the last one was refused. */
.acc-invite {
  display: none;
  flex-direction: column;
  gap: var(--token-space-3);
  scroll-margin-top: var(--token-space-8);
}

.acc-invite:target,
.acc-invite.acc-open {
  display: flex;
}

.acc-invite > * + * {
  margin-top: 0;
}

.acc-invite-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--token-space-4);
}

.acc-invite-head .btn-quiet {
  color: var(--token-color-text-secondary);
}

.acc-invite-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--token-space-3);
}

.acc-invite-row > .field {
  flex: 0 1 var(--token-layout-panel-min);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-1);
  height: auto;
  padding: 0;
  border: 0;
  background: none;
}

.acc-invite-row > .field > .lbl {
  font-size: var(--token-fs-xs);
}

.acc-invite-row > .field > input {
  height: var(--token-layout-control-h);
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
}

.acc-invite-row > .field > input:focus-visible {
  border-color: var(--token-color-accent-fill);
}

.acc-invite-row .control {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-1);
}

.acc-invite-row .control > .lbl {
  font-size: var(--token-fs-xs);
}

.acc-invite-row select {
  height: var(--token-layout-control-h);
}

.acc-invite .warn-line {
  margin: 0;
}

/* ---- the unsaved bar ---- */
.acc-changes {
  display: none;
  position: fixed;
  left: calc(var(--token-layout-sidebar) + var(--token-layout-page-pad-x));
  right: var(--token-layout-page-pad-x);
  bottom: calc(var(--token-space-6) + var(--token-space-1));
  z-index: var(--token-z-sticky);
  align-items: center;
  gap: var(--token-space-4);
  padding: var(--token-space-3) var(--token-space-3) var(--token-space-3) var(--token-space-5);
  border-radius: var(--token-radius-md);
  background: var(--token-color-text-primary);
  color: var(--token-color-surface);
  font-size: var(--token-fs-sm);
  line-height: 1.5;
}

.acc form:has(select option:checked:not([selected])) .acc-changes {
  display: flex;
}

/* Where `:has` is unknown the bar cannot know it is needed, so it is always
   there: a save that cannot be reached would be worse than one always shown. */
@supports not selector(:has(a)) {
  .acc-changes {
    display: flex;
    position: static;
  }
}

.acc-changes-count {
  font-weight: var(--token-weight-medium);
  white-space: nowrap;
}

.acc-changes-list {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--token-fs-xs-plus);
  opacity: 0.75;
}

.acc-changes .grow {
  flex: 1 1 auto;
}

.acc-changes .btn-ghost {
  background: transparent;
  color: var(--token-color-surface);
  border-color: color-mix(in srgb, var(--token-color-text-tertiary) 70%, transparent);
}

/* Room at the foot of the page for the bar, so it never covers the legend. */
.wrap:has(.acc form select option:checked:not([selected])) {
  padding-bottom: calc(var(--token-space-24) + var(--token-space-4));
}

@media (max-width: 900px) {
  .acc-changes {
    left: var(--token-space-4);
    right: var(--token-space-4);
    bottom: var(--token-space-4);
    flex-wrap: wrap;
  }
}

/* ================================================================ usage
   No board of its own: AdminA's heading and strip, the front page's figures,
   and the table in a card. */

.usage {
  gap: var(--token-space-5);
}

.usage-bar {
  gap: var(--token-space-3);
  margin: 0;
}

.usage-bar .seg a {
  color: var(--token-color-text-secondary);
}

.usage-bar .seg a[aria-current='true'] {
  color: var(--token-color-text-primary);
}

.usage-sum {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--token-space-4);
  margin: 0;
  padding: var(--token-space-4) var(--token-space-5);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
}

.usage-sum > div {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  min-width: 0;
}

.usage-sum dd {
  margin: 0;
  font-family: var(--token-font-display);
  font-size: calc(var(--token-fs-lg) + var(--token-gap-hair));
  line-height: 1.15;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.usage-sum dt {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.usage caption {
  position: absolute;
  width: var(--token-size-hidden);
  height: var(--token-size-hidden);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.usage th {
  padding: var(--token-layout-head-pad-y) var(--token-space-4);
}

.usage td {
  height: auto;
  padding: var(--token-space-3) var(--token-space-4);
  line-height: 1.5;
}

.usage td .badge {
  margin-left: var(--token-space-2);
  vertical-align: middle;
}

.usage-note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* A spend row has nothing to press, so its title is regular, as the rule for
   row titles has it. */
.usage tbody td:first-child .row-title {
  font-weight: var(--token-weight-regular);
}

/* An error page: the page head, then one card with the way on. */
.err-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-4);
  padding: var(--token-layout-card-pad-y) var(--token-layout-card-pad-x);
}

.err-card > .note {
  margin: 0;
}

/* The invite form: one row of board fields, their labels on one line and the
   controls on one baseline — the address, a level per product, the button. */
#invite .kit {
  align-items: flex-end;
  gap: var(--token-space-3);
}

#invite .kit select,
#invite .kit .btn {
  height: calc(var(--token-layout-control-h) + var(--token-space-1));
}


/* ================================================================ p-misc: sign-in and refusal pages
   No board of their own: drawn from board Main. Its frame (36px above, 48px at
   the sides, 28px between blocks), the page's head (the 28px heading and its
   lede, as every page draws it) and one card the size of a product card, with
   the way on as the primary button and a quiet line under it — the request id
   on a failure, who grants access on the sign-in page. The same markup comes
   from the platform and from Tenders, so both products refuse alike. */

.wrap:has(> .login-card),
.wrap:has(> .err-card) {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-6) + var(--token-space-1));
  padding: calc(var(--token-space-8) + var(--token-space-1)) var(--token-layout-page-pad-x);
  line-height: 1.5;
}

.wrap:has(> .login-card) > *,
.wrap:has(> .err-card) > * {
  margin: 0;
}

.wrap:has(> .login-card) > .hero .lede,
.wrap:has(> .err-card) > .hero .lede {
  max-width: var(--token-measure-lede);
  color: var(--token-color-text-secondary);
  line-height: 1.5;
}

/* One column of the front page's three-card grid: (width − 2 × 16px) ÷ 3. */
.login-card,
.err-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  flex-wrap: nowrap;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
  box-sizing: border-box;
  width: calc((100% - var(--token-space-4) * 2) / 3);
  max-width: none;
  padding: calc(var(--token-space-5) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-sm);
}

.login-card > *,
.err-card > *,
.login-card > * + * {
  margin: 0;
}

/* Why the reader is here again (session ended, wrong account): the card's own
   sentence, in the secondary ink the front page's cards describe themselves in. */
.login-card > .note:first-child:not(:last-child) {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.login-card > .note:last-child,
.err-card > .note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
  overflow-wrap: break-word;
}

/* A reference to quote, in the body face: the board has no mono type. */
.err-card .mono {
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
}

@media (max-width: 1100px) {
  .login-card,
  .err-card {
    width: calc((100% - var(--token-space-4)) / 2);
  }
}

/* A narrow window stacks the side column over the page; the rows keep their
   own heights rather than sharing out the window's. */
@media (max-width: 900px) {
  .app:has(.login-card),
  .app:has(.err-card) {
    align-content: start;
  }
}

@media (max-width: 720px) {
  .wrap:has(> .login-card),
  .wrap:has(> .err-card) {
    padding: var(--token-space-6) var(--token-space-4);
  }

  .login-card,
  .err-card {
    width: 100%;
  }
}

/* Signed out, the side column keeps the theme and language switches at its
   foot: choosing how the page looks must not wait for signing in. */

/* Screen-shaped rules for the tenders-dash screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   Two boards: TendersDashA (the tenders overview and, in the same language,
   the full list) and TenderOverviewA (one tender's Overview tab under its
   full head). Values the token set has no name for are composed from the
   nearest tokens with calc(), and each is marked where it happens. */

/* The boards set text at 1.5; the platform's normal is 1.55. Composed from
   `lh-snug` (1.3) because no token is 1.5. */
.tdash,
.ws-full,
.ov {
  line-height: calc(var(--token-lh-snug) + 0.2);
}

/* ================================================================ lists */

.tdash {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-5);
}

.tdash > * {
  margin: 0;
}

.tdash .list-bar {
  margin: 0;
  gap: var(--token-space-3);
}

/* The search box is the board's 260px: the platform's 240 plus a step. */
.tdash .list-bar form.inline > .field {
  flex: 0 0 calc(var(--token-layout-search) + var(--token-space-5));
  width: calc(var(--token-layout-search) + var(--token-space-5));
  max-width: none;
}

.tdash > .note {
  font-size: var(--token-fs-xs-plus);
}

/* «Результат» — the last segment, opening the bucket and its three statuses.
   Drawn as its neighbours are; the menu opens from its left edge. */
.seg > .seg-menu > summary {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  height: var(--token-layout-seg-item-h);
  padding: 0 var(--token-layout-seg-item-pad-x);
  border-radius: var(--token-radius-seg-item);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  white-space: nowrap;
}

.seg > .seg-menu > summary:hover {
  color: var(--token-color-text-primary);
}

.seg > .seg-menu.is-current > summary {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  box-shadow: 0 var(--token-border-hair) var(--token-layout-hair-gap) color-mix(in srgb, var(--token-color-text-primary) 8%, transparent);
}

.seg > .seg-menu > summary .dropdown-caret {
  width: var(--token-space-3);
  height: var(--token-space-3);
}

.seg > .seg-menu .menu {
  left: 0;
  right: auto;
}

/* ---- the table of tenders ---- */

.tender-table th {
  padding: var(--token-layout-head-pad-y) var(--token-space-4);
}

.tender-table td {
  height: auto;
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) var(--token-space-4);
}

/* The board's column widths: deadline 190, stage 160, readiness 290, status 110. */
.tender-table th[data-col="deadline"] {
  width: calc(var(--token-space-10) * 4.75);
}

.tender-table th[data-col="buyer"] {
  width: calc(var(--token-space-10) * 4);
}

.tender-table th[data-col="score"] {
  width: calc(var(--token-space-10) * 7.25);
}

.tender-table th[data-col="status"] {
  width: calc(var(--token-space-10) * 2.75);
}

/* The row's name is medium — it is the row's action — at 15px, half a step
   between the body's 14 and 16. */
.tender-table td a.row-title {
  font-size: calc((var(--token-fs-sm) + var(--token-fs-md)) / 2);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.tender-table .cell-note {
  margin-top: var(--token-gap-hair);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.tender-table .cell-when {
  display: block;
  font-variant-numeric: tabular-nums;
}

.tender-table .cell-sub {
  display: block;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* Five steps of the tender's way, 22 × 6 each, the reached ones in the accent. */
.steps {
  display: flex;
  align-items: center;
  gap: var(--token-space-1);
}

.steps > span {
  width: calc(var(--token-space-5) + var(--token-gap-hair));
  height: calc(var(--token-space-1) * 1.5);
  border-radius: var(--token-inset-chip);
  background: var(--token-color-accent-fill);
}

.steps > span.off {
  background: var(--token-color-surface-sunken);
}

.steps + .cell-sub {
  margin-top: calc(var(--token-space-1) * 1.5);
}

/* The readiness: the figure in the display face and a bar for it, both
   coloured by the value as the original's — above 80 ok, above 50 warn, else
   crit. The gate is not drawn here; the original shows none. */
.ready {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.ready .score-figure {
  flex: none;
  width: var(--token-space-10);
  text-align: center;
  font-size: calc(var(--token-fs-md) * 1.125);
  line-height: var(--token-lh-snug);
}

.ready .score-figure.is-ok {
  color: var(--token-color-state-ok-text);
}

.ready .score-figure.is-warn {
  color: var(--token-color-state-warn-text);
}

.ready .score-figure.is-crit {
  color: var(--token-color-state-crit-text);
}

.ready-side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--token-space-1) * 1.5);
}

.ready-bar {
  display: block;
  width: calc(var(--token-space-10) * 3);
  height: calc(var(--token-space-1) * 1.5);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

.ready-bar > span {
  display: block;
  height: 100%;
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-fill);
}

.ready-bar.is-crit > span {
  background: var(--token-color-state-crit-text);
}

.ready-bar.is-warn > span {
  background: var(--token-color-state-warn-text);
}

.ready-bar.is-ok > span {
  background: var(--token-color-state-ok-text);
}

/* The status column's chip is the word and its colour, as the board draws it;
   the glyph stays on the gate beside it, where the state is a warning. */
.tender-table td:last-child .badge-icon {
  display: none;
}

/* ---- the two cards under the table ---- */

/* Two cards a row where each has an aside's width; one otherwise — at 1024
   with the side panel open two 340px cards left a lead's title 84px. */
.dash-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--token-layout-aside), 100%), 1fr));
  gap: var(--token-space-4);
}

.panel.dash-card {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  padding: calc(var(--token-space-4) + var(--token-gap-hair)) var(--token-space-5);
}

.panel.dash-card > * + * {
  margin-top: 0;
}

.panel.dash-leads {
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
}

.dash-card-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.dash-card-head h2 {
  flex: 1 1 auto;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: inherit;
  text-wrap: wrap;
}

.dash-card-head a {
  font-size: var(--token-fs-xs-plus);
}

.dash-card .note {
  font-size: var(--token-fs-sm);
}

.btn.btn-sm,
a.btn.btn-sm {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.dash-card > .btn {
  align-self: flex-start;
}

.dash-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
}

.dash-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-1) var(--token-space-3);
}

/* The title takes the row; the buyer goes under it when both do not fit,
   rather than the buyer, unshrinkable, leaving the title a word a line. */
.dash-list a.grow {
  flex: 1 1 calc(var(--token-layout-panel-min) / 2);
  min-width: 0;
}

.dash-list li > .badge {
  font-variant-numeric: tabular-nums;
}

.dash-list li > .badge .badge-icon {
  display: none;
}

.dash-list a.grow {
  color: var(--token-color-text-secondary);
}

.dash-when {
  flex: none;
}

.dash-buyer {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
}

.dash-buyer,
.dash-when {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* An upcoming deadline's date, always in the critical colour, as the
   original's card sets every one of them. */
.dash-due {
  color: var(--token-color-state-crit-text);
  font-weight: var(--token-weight-medium);
}

@media (max-width: 900px) {
  .dash-cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ============================================================ the tender */

/* The Overview's head: the raised band across the whole page, from the side
   column to the edge, the tabs at its foot. */
.ws-head.ws-full {
  display: block;
  margin: calc(var(--token-layout-page-pad-y) * -1) calc(var(--token-layout-page-pad-x) * -1) 0;
  padding: var(--token-space-5) var(--token-layout-page-pad-x) 0;
  background: var(--token-color-surface-raised);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.ws-full .crumbs {
  color: var(--token-color-text-tertiary);
}

.ws-full .ws-title-row {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
  min-height: var(--token-layout-control-h-sm);
  margin-top: calc(var(--token-space-1) * 1.5);
}

/* 22px: the display face one step over the tabs' own 20. */
.ws-full .ws-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: calc(var(--token-fs-lg) * 1.1);
  line-height: 1.15;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-full .ws-title-row .btn {
  flex: none;
}

/* The current tab's own buttons — the Overview's two — at the row's end. */
.ws-full .ws-actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
}

/* A narrow page: the title has the row to itself and wraps rather than
   cutting the tender's name to its first word; the actions go under it, as
   the meeting's head does. */
@media (max-width: 1100px) {
  .ws-full .ws-title-row {
    flex-wrap: wrap;
    row-gap: var(--token-space-2);
  }

  .ws-full .ws-title {
    flex-basis: 100%;
    white-space: normal;
    overflow-wrap: break-word;
  }

  .ws-full .ws-actions {
    flex-wrap: wrap;
  }
}

.ws-full .ws-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-4);
  margin-top: var(--token-space-2);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.ws-sep {
  color: var(--token-color-text-tertiary);
}

/* The file the tender came from: one fact of the line, cut with an ellipsis
   (the whole name in its hover) rather than pushing the rest onto a row of
   its own. */
.ws-full .ws-filed {
  min-width: 0;
  max-width: calc(var(--token-layout-search) + var(--token-space-5));
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-tertiary);
}

.ws-score {
  font-weight: var(--token-weight-medium);
}

.ws-score.is-ok {
  color: var(--token-color-state-ok-text);
}

.ws-score.is-warn {
  color: var(--token-color-state-warn-text);
}

.ws-score.is-crit {
  color: var(--token-color-state-crit-text);
}

/* The status chip that opens the status menu. */
.ws-status > summary.badge {
  display: inline-flex;
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  gap: var(--token-layout-pill-gap);
  font-size: var(--token-fs-xs);
}

.ws-status > summary .dropdown-caret {
  width: var(--token-space-3);
  height: var(--token-space-3);
}

.ws-status .menu {
  left: 0;
  right: auto;
}

.ws-status .menu form {
  display: grid;
  gap: var(--token-gap-hair);
}

.menu-item {
  display: block;
  width: 100%;
  padding: var(--token-space-2) var(--token-space-3);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: none;
  font: inherit;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.menu-item:hover {
  background: var(--token-color-surface-inset);
}

.menu-item[aria-current='true'] {
  background: var(--token-color-accent-wash);
  color: var(--token-nav-current-fg);
  cursor: default;
}

/* The tabs sit on the band's own bottom rule, with their counts beside them.
   Wrapped onto a second row on a narrow page, the rows touch: the tab-wide
   gap between them read as two strips. */
.ws-full .tabs {
  margin-top: var(--token-space-3);
  border-bottom: 0;
  gap: 0 var(--token-layout-tab-gap);
}

.ws-full .tabs a,
.ws-band .tabs a {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  margin-bottom: 0;
}

.ws-full .tabs b,
.ws-band .tabs b {
  margin-left: 0;
}

/* ---- the Overview's body ---- */

/* 24px under the band: the page's 18 between blocks plus the difference. */
.ov {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-5);
  margin-top: calc(var(--token-space-6) - var(--token-layout-block-gap));
}

.ov > * {
  margin: 0;
}

.ov h2 {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: inherit;
  text-wrap: wrap;
}

/* The RFP's own title, the body's heading as the original's Overview opens
   with it; the head above carries the name the tender was created under. */
.ov h2.ov-hero {
  font-size: var(--token-fs-lg);
  line-height: 1.25;
  overflow-wrap: break-word;
}

.ov h2.ov-hero.is-empty {
  font-style: italic;
  color: var(--token-color-text-tertiary);
}

.ov-card {
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

.ov-card-head {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
}

.ov .note {
  font-size: var(--token-fs-xs-plus);
}

.ov-n {
  flex: none;
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* What contradicts itself, on the warning ground at the top. */
.ov-warn {
  padding: var(--token-space-4) var(--token-space-5);
  border: var(--token-border-hair) solid transparent;
  border-radius: var(--token-radius-md);
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.ov-warn-title {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  font-weight: var(--token-weight-medium);
}

.ov-warn-icon {
  width: var(--token-space-4);
  height: var(--token-space-4);
  flex: none;
}

.ov-warn ol,
.ov-dl {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.ov-warn ol {
  gap: calc(var(--token-space-1) * 1.5);
  margin-top: calc(var(--token-space-2) + var(--token-gap-hair));
  color: var(--token-color-text-primary);
  font-size: var(--token-fs-sm);
}

.ov-warn li,
.ov-dl li {
  display: flex;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
}

/* The fact sheet: four cells across, each ruled right and below; the sheet's
   own edge swallows the last column's and row's rules. */
.ov-facts {
  overflow: hidden;
}

.facts-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-right: calc(var(--token-border-hair) * -1);
  margin-bottom: calc(var(--token-border-hair) * -1);
}

.fact {
  padding: calc(var(--token-space-3) - var(--token-border-hair)) var(--token-space-4);
  border-right: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  min-width: 0;
}

.fact-k {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.fact-v {
  margin-top: var(--token-space-1);
  color: var(--token-color-text-primary);
  font-variant-numeric: tabular-nums;
}

.fact-v.is-none {
  color: var(--token-color-text-tertiary);
}

/* Every value on one line, as the board's sheet draws it: extracted values
   are often a sentence from the document, and a sheet of paragraphs is no
   longer a sheet. The whole value is in the hover and on its source. */
.fact-v[title] {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.fact-s {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.fact.is-editing form {
  display: grid;
  gap: var(--token-space-2);
}

.ov-mark {
  font-size: var(--token-fs-2xs);
  color: var(--token-color-accent-text);
  cursor: help;
}

.ov-mark.is-unsure {
  color: var(--token-color-state-warn-text);
}

.ov-mark.is-human {
  color: var(--token-color-state-ok-text);
}

.ov-legend {
  padding: var(--token-space-2) var(--token-space-4);
  background: var(--token-color-surface-inset);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* In edit mode each name carries its own «Змінити». */
.ov-edit {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  margin-left: auto;
  font-size: var(--token-fs-xs);
}

.ov-edit form.inline {
  display: inline-flex;
}

.ov-edit .linkish {
  font-size: var(--token-fs-xs);
}

/* Criteria beside deliverables, the same height. */
/* Two columns only where each has an aside's width: at 1024px with the side
   panel open the pair was 354 + 322px and a deliverable's name ran past the
   card's edge. Below that, one column, as on a narrow window. */
.ov-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--token-layout-aside), 100%), 1fr));
  gap: var(--token-space-5);
  align-items: stretch;
}

@media (max-width: 900px) {
  .ov-pair,
  .ov-more {
    grid-template-columns: minmax(0, 1fr);
  }
  .facts-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.ov-crit {
  overflow: hidden;
}

.ov-crit > .ov-card-head {
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.ov-crit > .ov-card-head .note {
  font-weight: var(--token-weight-regular);
}

.ov-card-edit {
  padding: var(--token-space-3) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.ov-table th {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-space-4);
}

.ov-table td {
  height: auto;
  padding: calc(var(--token-space-2) + var(--token-gap-hair)) var(--token-space-4);
}

.ov-table th[data-col="points"] {
  width: calc(var(--token-space-10) * 1.75);
}

.ov-table th[data-col="weight"] {
  width: calc(var(--token-space-10) * 4.25);
}

.ov-table td.num,
.ov-table th.num {
  font-variant-numeric: tabular-nums;
}

.ov-table td.ov-cname {
  font-weight: var(--token-weight-medium);
}

.ov-table tr.sub td {
  background: var(--token-color-surface-inset);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  padding-top: calc(var(--token-space-1) + var(--token-inset-chip));
  padding-bottom: calc(var(--token-space-1) + var(--token-inset-chip));
}

.ov-table tr.sub td:first-child {
  padding-left: var(--token-space-8);
}

.ov-flag {
  height: var(--token-layout-pill-h-sm);
  margin-left: calc(var(--token-space-1) * 1.5);
  font-weight: var(--token-weight-regular);
}

.ov-flag .badge-icon {
  display: none;
}

/* The weight's bar: 150px for the heaviest criterion, the rest in proportion. */
.ov-wtrack {
  display: block;
  width: calc(var(--token-space-10) * 3.75);
  max-width: 100%;
}

.ov-wbar {
  display: block;
  height: var(--token-space-2);
  border-radius: var(--token-inset-chip);
  background: var(--token-color-accent-fill);
}

.ov-deliv {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) calc(var(--token-space-4) + var(--token-gap-hair));
}

.ov-deliv > .ov-card-head {
  padding-bottom: calc(var(--token-space-1) * 1.5);
}

.ov-dl {
  gap: var(--token-space-2);
}

.ov-deliv .ov-foot,
.ov-sub-head {
  padding-top: calc(var(--token-space-1) * 1.5);
}

.ov-sub-head {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  font-weight: var(--token-weight-medium);
}

.ov-forms {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  padding: var(--token-space-4) calc(var(--token-space-4) + var(--token-gap-hair));
}

.ov-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.ov-chip {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  padding: calc(var(--token-space-1) * 1.5) var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
}

.ov-chip b {
  font-weight: var(--token-weight-regular);
}

.ov-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-5);
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

/* The long lists under the forms, two to a row. */
/* Two cards a row where each has a panel's width, one otherwise. A fixed pair
   — declared after the narrow-window rule, so it won — left a phone two 145px
   cards and a requirement 33 lines tall. */
.ov-more {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--token-layout-panel-min), 100%), 1fr));
  gap: var(--token-space-5);
  align-items: start;
}

.ov-more:empty {
  display: none;
}

.ov-more-card {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: var(--token-space-4) calc(var(--token-space-4) + var(--token-gap-hair));
  scroll-margin-top: var(--token-space-6);
}

.ov-list {
  margin: 0;
  padding-left: var(--token-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
}

.ov-prose {
  white-space: pre-line;
}

.ov-term + .ov-term {
  margin-top: var(--token-space-2);
}

.ov .panel > .cap + * {
  margin-top: 0;
}

/* The «+» before «Новий тендер» is a glyph in a button, not an icon button:
   the calendar's square-button floor does not apply to it. */
.tdash .btn .btn-icon {
  min-width: 0;
  padding: 0;
}

.tdash .lede {
  line-height: inherit;
}

/* The board's card button is a link, and reads in the accent like one. */
.dash-card > a.btn {
  color: var(--token-color-accent-text);
}

.fact.is-editing .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

/* ======================================================= the compact head
   Every tab but the Overview: the board's band — the trail, one row of the
   title, the status pill and the deadline, then the tab strip on the band's
   rule. Full width from the side column to the edge, like the Overview's. */
.ws-head.ws-band {
  display: block;
  margin: calc(var(--token-layout-page-pad-y) * -1) calc(var(--token-layout-page-pad-x) * -1) var(--token-layout-block-gap);
  padding: calc(var(--token-space-4) + var(--token-gap-hair)) var(--token-layout-page-pad-x) 0;
  background: var(--token-color-surface-raised);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

/* Under the work tabs the band sits on their body with no gap of its own. */
.wrap:has(> .tw) > .ws-head.ws-band {
  margin-bottom: 0;
}

.ws-band .crumbs {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.ws-band .ws-title-row {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
  margin-top: var(--token-space-1);
}

.ws-band .ws-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--token-fs-lg);
  line-height: 1.15;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-band .ws-deadline {
  flex: none;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.ws-band .tabs {
  margin-top: var(--token-space-2);
  border-bottom: 0;
  gap: var(--token-layout-tab-gap);
}

/* The status pill: a word on its tone, no glyph, opening the six statuses. */
.ws-band .ws-status {
  position: relative;
  flex: none;
}

.ws-band .ws-status > summary {
  list-style: none;
  cursor: pointer;
}

.ws-band .ws-status > summary::-webkit-details-marker {
  display: none;
}

.ws-band .ws-status .badge {
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  font-size: var(--token-fs-xs);
}

.ws-band .ws-status .badge-icon {
  display: none;
}

.ws-band .ws-status > .menu {
  position: absolute;
  top: calc(100% + var(--token-space-1));
  right: 0;
  z-index: 5;
  display: grid;
  gap: var(--token-gap-hair);
  min-width: calc(var(--token-layout-field-basis) * 0.8);
  padding: var(--token-space-1);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

/* A sub-criterion and a deliverable on one line, as the board's rows are; the
   whole text is in the hover. */
.ov-clip {
  display: block;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ov-dl li {
  min-width: 0;
}

/* A deliverable's name wraps inside its row instead of holding the row at
   its own one-line width past the card's edge. */
.ov-dl li > span {
  min-width: 0;
  overflow-wrap: break-word;
}

.ov-table td:has(> .ov-clip) {
  max-width: 0;
  width: 100%;
}

/* restore A: the status on each upcoming deadline, and the file a tender was
   created from in its head. The badge sits in its own span so it keeps its
   glyph (the score badges beside the leads drop theirs); the file name gives
   way to the title and ellipsises rather than pushing the status off. */
.dash-status {
  flex: none;
}

.ws-band .ws-filed {
  flex: 0 1 auto;
  min-width: 0;
  max-width: calc(var(--token-layout-search) + var(--token-space-5));
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-tertiary);
}

/* restore B: overview — provenance words, scales, the sheet's last cell. */
.ov-mark {
  white-space: nowrap;
}

/* The sub-criterion's scoring scale, opened under its name. */
.ov-scale {
  margin: var(--token-space-1) 0 0;
  padding-left: var(--token-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
}

/* Eleven cells: the last one takes the row's remaining two columns. */
.facts-grid > .fact:last-child:nth-child(4n + 3) {
  grid-column: span 2;
}

/* On a phone the weight column's fixed 170px and its track ran the overview
   table past the screen: there the column takes what the row leaves it. */
@media (max-width: 640px) {
  .ov-table th[data-col="weight"] {
    width: auto;
  }

  .ov-wtrack {
    width: 100%;
  }
}

/* Screen-shaped rules for the tenders-work screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   A tender's Requirements, Proposal and Audit tabs (boards RequirementsA,
   ProposalA, AuditA). Every rule is scoped under `.tw`, the root the module's
   views emit for these three tabs, so nothing here reaches another screen. */

/* ------------------------------------------------------------ the frame
   The tender's body keeps the frame's own sides — the same x as the
   Overview, the lists and every other page — and starts right under the tab
   strip. */
.wrap > .ws-head:has(+ .tw) {
  margin-bottom: 0;
}

.tw {
  font-size: var(--token-fs-sm);
}

.tw .badge {
  height: var(--token-size-badge);
  padding: 0 var(--token-space-2);
  gap: calc(var(--token-space-1) + var(--token-border-hair));
}

/* The work boards draw every state pill as a word on its tone, no glyph. */
.tw .badge-icon {
  display: none;
}

/* A table as the boards draw it: a card, a quiet header, rows sized by their
   text rather than a fixed height, and one line under each. */
.tw-card {
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  overflow: hidden;
}

.tw-t {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: var(--token-fs-xs-plus);
}

.tw-t th,
.tw-t th:first-child,
.tw-t th:last-child {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-layout-item-pad-x);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
  text-align: left;
  white-space: nowrap;
  background: none;
}

.tw-t td,
.tw-t td:first-child,
.tw-t td:last-child {
  height: auto;
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-layout-item-pad-x);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  vertical-align: top;
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
}

.tw-t tbody tr:last-child > td {
  border-bottom: 0;
}

.tw-empty {
  color: var(--token-color-text-tertiary);
}

.tw-dash {
  color: var(--token-color-text-tertiary);
}

/* A two-line cut of a long text; the whole of it is in the panel. */
.tw-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--token-color-text-primary);
}

.tw-clamp:hover {
  text-decoration: none;
  color: var(--token-color-accent-text);
}

/* ------------------------------------------------------- requirements
   The list on the surface, one requirement on a raised column to its right,
   the column running from the tab strip to the foot of the page. */
.wrap:has(> .tw-req) {
  min-height: 100vh;
  padding-bottom: 0;
}

.tw-req {
  flex: 1 1 auto;
  display: flex;
  align-items: stretch;
  margin: calc(-1 * var(--token-layout-block-gap)) calc(-1 * var(--token-layout-page-pad-x)) 0 calc(-1 * var(--token-layout-page-pad-x));
}

.tw-req-list {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  padding: var(--token-layout-block-gap) var(--token-space-5) var(--token-layout-block-gap) var(--token-layout-page-pad-x);
}

.tw-req-list > * {
  margin: 0;
}

.tw-bar {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--token-layout-item-pad-x);
}

/* One line on the board's width: the search gives up a little before the
   category menu drops under the segments. */
@media (max-width: 1300px) {
  .tw-bar {
    flex-wrap: wrap;
  }
}

.tw-bar .seg {
  flex: none;
}

.tw-bar .seg b {
  margin-left: 0;
}

.tw-bar form.inline {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
}

.tw-bar .field:has(> input[type='search']) {
  flex: 0 1 auto;
  width: calc(var(--token-layout-search) - var(--token-layout-item-pad-x));
  min-width: var(--token-layout-col-when);
  max-width: none;
}

.tw-bar .dropdown {
  flex: none;
}

.tw-bar .field input {
  font-size: var(--token-fs-sm);
}

.tw-bar .dropdown > summary {
  gap: var(--token-space-2);
  color: var(--token-color-text-primary);
  font-size: var(--token-fs-sm);
}

.tw-bar .dropdown .menu {
  right: 0;
  left: auto;
}

/* «За аудитом #N:» and the five chips, each a link that narrows the list. */
.tw-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-layout-pill-gap);
}

.tw-chips-lead {
  margin-right: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tw-fchip {
  display: inline-flex;
  align-items: center;
  gap: var(--token-layout-pill-gap);
  height: calc(var(--token-space-6) + var(--token-space-1));
  padding: 0 var(--token-layout-item-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs);
  line-height: 1;
  white-space: nowrap;
}

.tw-fchip b {
  font-weight: var(--token-weight-regular);
}

.tw-fchip:hover {
  text-decoration: none;
  border-color: var(--token-color-text-tertiary);
}

.tw-fchip[aria-current='true'] {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

/* The state's sign in a small pill of its own colour, before its word. */
.tw-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: calc(var(--token-space-4) + var(--token-layout-hair-gap));
  padding: 0 var(--token-layout-pill-gap);
  border-radius: var(--token-radius-pill);
  font-size: var(--token-fs-xs);
  line-height: 1;
}

.tw-critical {
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tw-warning {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.tw-ok {
  background: var(--token-color-state-ok-bg);
  color: var(--token-color-state-ok-text);
}

.tw-neutral {
  background: var(--token-color-state-neutral-bg);
  color: var(--token-color-state-neutral-text);
}

.tw-info {
  background: var(--token-color-state-info-bg);
  color: var(--token-color-state-info-text);
}

.tw-hidden-note {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* The list's columns, as wide as the board draws them. */
.tw-req-t .tw-c-ref {
  width: calc(var(--token-layout-col-duration) - var(--token-space-5) - var(--token-layout-hair-gap));
}

.tw-req-t .tw-c-cat,
.tw-req-t .tw-c-state {
  width: calc(var(--token-space-24) + var(--token-space-6) + var(--token-space-1));
}

/* «Ігнорувати» / «Відновити» on every row, as the original's «Actions». */
.tw-req-t .tw-c-act {
  width: calc(var(--token-space-24) + var(--token-space-3));
}

.tw-req-t .tw-act {
  text-align: right;
  white-space: nowrap;
}

.tw-req-t .tw-act form {
  margin: 0;
}

.tw-req-t .tw-act .btn {
  color: var(--token-color-text-secondary);
}

.tw-ref {
  font-family: var(--token-font-mono);
  font-size: calc(var(--token-fs-xs) + var(--token-border-hair) / 2);
  white-space: nowrap;
}

.tw-cat {
  color: var(--token-color-text-secondary);
}

.tw-req-t tr.is-open > td {
  background: var(--token-color-accent-wash);
}

.tw-req-t tr.is-open > td:first-child {
  box-shadow: inset var(--token-border-accent) 0 0 var(--token-color-accent-fill);
}

/* The open row's reference and text in medium: the one row being worked on. */
.tw-req-t tr.is-open .tw-ref,
.tw-req-t tr.is-open .tw-clamp {
  font-weight: var(--token-weight-medium);
}

.tw-req-t tr.is-ignored .tw-clamp {
  color: var(--token-color-text-tertiary);
}

/* Under the text: mandatory, the stage, the weight — the original's matrix
   states all three on every row. */
.tw-req-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1) var(--token-space-3);
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tw-mand {
  color: var(--token-color-state-warn-text);
  font-weight: var(--token-weight-medium);
}

/* The row's stage, as the original's per-row select: the word opens a menu
   of the two stages, each a button that posts it. */
.tw-stage > summary {
  display: inline;
  color: var(--token-color-text-tertiary);
}

.tw-stage > summary:hover {
  color: var(--token-color-text-secondary);
}

.tw-stage .menu {
  left: 0;
  right: auto;
}

.tw-stage .menu form {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.tw-stage .menu button {
  padding: var(--token-space-2) var(--token-space-3);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: none;
  color: var(--token-color-text-primary);
  font: inherit;
  font-size: var(--token-fs-sm);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.tw-stage .menu button:hover {
  background: var(--token-color-surface-inset);
}

.tw-stage .menu button[aria-pressed='true'] {
  background: var(--token-color-accent-wash);
  color: var(--token-nav-current-fg);
}

/* The panel: the requirement at the top, previous / next / ignore at the foot
   of the screen. Both halves stay in view while the list scrolls under them. */
.tw-panel {
  flex: 0 0 calc(var(--token-layout-aside) + var(--token-layout-item-pad-x));
  width: calc(var(--token-layout-aside) + var(--token-layout-item-pad-x));
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: var(--token-color-surface-raised);
  border-left: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tw-panel-body {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
  padding: calc(var(--token-space-5) + var(--token-layout-hair-gap)) calc(var(--token-space-6) + var(--token-layout-hair-gap)) var(--token-layout-block-gap);
}

.tw-panel-body > * {
  margin: 0;
}

.tw-panel-head {
  display: flex;
  align-items: center;
  gap: var(--token-layout-item-pad-x);
}

.tw-panel-ref {
  font-family: var(--token-font-mono);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  white-space: nowrap;
}

.tw-panel-pos {
  margin-left: auto;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
}

.tw-panel-text {
  font-size: calc(var(--token-fs-md) + var(--token-border-hair));
  line-height: 1.5;
}

.tw-panel-meta {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tw-weight {
  font-size: var(--token-fs-xs-plus);
}

/* What the audit said, on its state's own ground. */
.tw-finding {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-pill-gap);
  padding: calc(var(--token-space-3) + var(--token-layout-hair-gap)) var(--token-space-4);
  border-radius: var(--token-radius-seg);
  font-size: var(--token-fs-xs-plus);
}

.tw-finding > * {
  margin: 0;
}

.tw-finding p {
  color: var(--token-color-text-primary);
}

.tw-finding .tw-finding-head {
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  color: inherit;
}

.tw-finding.tw-neutral .tw-finding-head,
.tw-finding.tw-ok .tw-finding-head {
  color: var(--token-color-text-primary);
}

/* The stage as two segments across the panel, the current one raised. */
.tw-panel .ctrl {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-2);
  margin: 0;
}

.tw-panel .ctrl > .lbl,
.tw-label {
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
  text-transform: none;
  letter-spacing: 0;
}

.tw-panel .ctrl .seg {
  display: flex;
  width: 100%;
}

.tw-panel .ctrl .seg button {
  flex: 1 1 0;
  justify-content: center;
  height: calc(var(--token-layout-seg-item-h) + var(--token-layout-hair-gap));
  font-size: var(--token-fs-xs-plus);
}

/* The team's note: a quiet box, and a save button once there is a note. */
.tw-panel form.stack {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  margin: 0;
}

.tw-note {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.tw-note textarea {
  height: calc(var(--token-space-24) - var(--token-layout-pill-gap));
  padding: var(--token-layout-item-pad-x) var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  font: inherit;
  font-size: var(--token-fs-sm);
  resize: none;
}

.tw-note textarea::placeholder {
  color: var(--token-color-text-tertiary);
}

.tw-note textarea:focus {
  outline: none;
  border-color: var(--token-color-accent-text);
}

.tw-panel form.stack > .btn {
  align-self: flex-end;
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.tw-panel form:has(> .tw-note.is-empty textarea:placeholder-shown) > .btn {
  display: none;
}

.tw-panel-foot {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: var(--token-layout-item-pad-x);
  margin: 0 calc(var(--token-space-6) + var(--token-layout-hair-gap));
  padding: calc(var(--token-space-3) + var(--token-layout-hair-gap)) 0 calc(var(--token-space-5) + var(--token-layout-hair-gap));
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  background: var(--token-color-surface-raised);
}

.tw-panel-foot .btn {
  color: var(--token-color-text-primary);
}

.tw-panel-foot .btn[aria-disabled='true'] {
  color: var(--token-color-text-tertiary);
  cursor: default;
}

.tw-panel-foot > form:last-child {
  margin: 0 0 0 auto;
}

.tw-panel-foot > form:last-child .btn {
  color: var(--token-color-text-secondary);
}

@media (max-width: 1100px) {
  .tw-req {
    flex-direction: column;
  }

  .tw-panel {
    order: -1;
    width: auto;
    flex-basis: auto;
    border-left: 0;
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tw-panel-body,
  .tw-panel-foot {
    position: static;
  }
}

/* ----------------------------------------------------------- proposal
   The draft's files grouped by folder, what the audit said about each, and
   the switch that takes a file in or out of the next audit. */
.tw-prop {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  padding-top: var(--token-layout-hair-gap);
}

.tw-prop > * {
  margin: 0;
}

.tw-prop-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.tw-prop-head > form.inline {
  margin: 0;
}

.tw-prop-head .grow {
  min-width: 0;
}

.tw-prop-head .grow > * {
  margin: 0;
}

.tw-prop-title {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-md);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  letter-spacing: 0;
}

.tw-prop-sub {
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

.tw-prop-head .btn {
  font-size: var(--token-fs-sm);
}

.tw-btn-icon {
  width: var(--token-fs-md);
  height: var(--token-fs-md);
  flex: none;
}

/* The upload: a button that opens a drop area beneath it. */
.tw-upload {
  position: relative;
}

.tw-upload > summary {
  list-style: none;
  cursor: pointer;
  color: var(--token-color-text-primary);
}

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

.tw-upload[open] > summary {
  border-color: var(--token-color-accent-fill);
}

.tw-upload-pop {
  position: absolute;
  right: 0;
  top: calc(100% + var(--token-space-2));
  z-index: var(--token-z-sticky);
  width: var(--token-layout-aside);
  padding: var(--token-space-4);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.tw-upload-pop form {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  margin: 0;
}

.tw-drop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--token-layout-pill-gap);
  padding: var(--token-space-6) var(--token-space-4);
  border: var(--token-border-check) dashed var(--token-color-border-strong);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-inset);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--token-dur-fast), background-color var(--token-dur-fast);
}

/* The browser's own input, over the whole area and drawn invisible: a drop
   anywhere on the area lands in it, and a press opens the picker. */
.tw-drop input[type='file'] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}

.tw-drop:hover,
.tw-drop:has(input:focus-visible),
.tw-drop:has(input:valid) {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
}

.tw-drop:has(input:focus-visible) {
  outline: var(--token-border-thick) solid var(--token-color-accent-fill);
  outline-offset: var(--token-border-thick);
}

.tw-drop-icon {
  width: var(--token-space-6);
  height: var(--token-space-6);
  color: var(--token-color-text-tertiary);
}

.tw-drop-title {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

.tw-drop-hint {
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

.tw-drop-picked {
  display: none;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-accent-text);
}

.tw-drop:has(input:valid) .tw-drop-picked {
  display: block;
}

.tw-drop:has(input:valid) .tw-drop-hint {
  display: none;
}

.tw-upload-foot {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  font-size: var(--token-fs-xs-plus);
}

/* Nothing chosen, nothing to send: the button waits for a file. */
.tw-upload-pop form:has(input[type='file']:invalid) .btn-primary {
  opacity: 0.5;
  pointer-events: none;
}

/* The chips over the file list. */
.tw-pchips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.tw-pchip {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  height: var(--token-space-8);
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs-plus);
  line-height: 1;
  white-space: nowrap;
}

.tw-pchip b {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-primary);
}

.tw-pchip:hover {
  text-decoration: none;
  border-color: var(--token-color-text-tertiary);
}

.tw-pchip.is-crit {
  border-color: var(--token-color-state-crit-text);
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tw-pchip.is-crit b {
  color: var(--token-color-state-crit-text);
}

.tw-pchip[aria-current='true'] {
  box-shadow: inset 0 0 0 var(--token-border-hair) currentColor;
  border-color: currentColor;
}

.tw-pchip:not(.is-crit)[aria-current='true'] {
  color: var(--token-color-accent-text);
  background: var(--token-color-accent-wash);
}

.tw-chip-icon {
  width: var(--token-space-3);
  height: var(--token-space-3);
  flex: none;
}

/* The list: one grid for every row, so a folder's files line up with the
   next folder's and the header's. The last column is as wide as its own
   heading, «Включити в аудит» (a 96 cut it to «Включити в ау…»); the remarks
   give up the difference. */
.tw-docs {
  --tw-docs-cols: minmax(0, 1fr)
    calc(var(--token-layout-field-max) - var(--token-layout-item-pad-x) - var(--token-space-8))
    calc(var(--token-space-24) + var(--token-space-6)) var(--token-layout-col-duration)
    calc(var(--token-space-24) + var(--token-space-8));
}

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

.tw-row {
  display: grid;
  grid-template-columns: var(--tw-docs-cols);
  align-items: center;
  min-height: var(--token-space-10);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.tw-row > * {
  min-width: 0;
  padding: 0 var(--token-space-3);
}

.tw-docs > :last-child,
.tw-docs > :last-child > .tw-rows > .tw-row:last-child,
.tw-docs > details:last-child:not([open]) > summary {
  border-bottom: 0;
}

.tw-docs-head {
  min-height: 0;
  padding: calc(var(--token-space-2) + var(--token-border-hair)) 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  line-height: 1.5;
}

.tw-docs-head > * {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tw-docs-empty {
  margin: 0;
  padding: var(--token-space-4) var(--token-space-3);
  color: var(--token-color-text-tertiary);
}

.tw-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.tw-num.is-zero {
  color: var(--token-color-text-tertiary);
}

.tw-center {
  display: flex;
  justify-content: center;
}

.tw-row .tw-doc {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-primary);
}

.tw-row.is-nested .tw-doc {
  padding-left: calc(var(--token-space-6) + var(--token-layout-pill-gap));
}

.tw-cell {
  display: flex;
  align-items: center;
  gap: var(--token-layout-pill-gap);
}

.tw-remark {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-secondary);
}

.tw-remark-long {
  padding: var(--token-space-1) 0;
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

/* A folder's line: the inset ground, a caret, the name and its count. */
.tw-folder > summary {
  list-style: none;
  cursor: pointer;
  background: var(--token-color-surface-inset);
}

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

.tw-folder-name {
  display: flex;
  align-items: center;
  gap: var(--token-space-1);
  overflow: hidden;
  white-space: nowrap;
  color: var(--token-color-text-primary);
}

.tw-folder-name::before {
  content: '▸';
  width: var(--token-space-2);
  font-size: var(--token-fs-2xs);
  color: var(--token-color-text-secondary);
}

.tw-folder[open] .tw-folder-name::before {
  content: '▾';
}

.tw-folder-count {
  color: var(--token-color-text-tertiary);
}

.tw-folder[open] .tw-sum-shut {
  display: none;
}

.tw-folder > summary:hover .tw-folder-name {
  color: var(--token-color-accent-text);
}

.tw-foot-note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* In or out of the next audit, as a switch. */
.tw-row form.inline {
  margin: 0;
}

.tw-switch {
  position: relative;
  display: inline-block;
  width: var(--token-space-8);
  height: calc(var(--token-space-4) + var(--token-layout-hair-gap));
  padding: 0;
  border: 0;
  border-radius: var(--token-radius-pill);
  background: var(--token-color-border-strong);
  cursor: pointer;
  transition: background-color var(--token-dur-fast);
}

.tw-switch i {
  position: absolute;
  top: var(--token-layout-hair-gap);
  left: var(--token-layout-hair-gap);
  width: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  height: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-raised);
  transition: left var(--token-dur-fast);
}

.tw-switch[aria-checked='true'] {
  background: var(--token-color-accent-fill);
}

.tw-switch[aria-checked='true'] i {
  left: calc(100% - var(--token-space-3) - var(--token-layout-hair-gap) - var(--token-layout-hair-gap));
  background: var(--token-color-on-accent);
}

.tw-switch:focus-visible {
  outline: var(--token-border-thick) solid var(--token-color-accent-fill);
  outline-offset: var(--token-border-thick);
}

/* -------------------------------------------------------------- audit
   One report: the verdict and the figure as a band, its four parts, then the
   report's views as segments — blockers first. */
.tw-audit {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
  padding-top: var(--token-space-1);
}

.tw-audit > * {
  margin: 0;
}

.tw-audit .badge {
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
}

.tw-audit-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.tw-audit-head .grow > * {
  margin: 0;
}

.tw-audit-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-3);
}

.tw-audit-title h2 {
  margin: 0;
  font-family: var(--token-font-display);
  font-size: var(--token-fs-h2);
  font-weight: var(--token-weight-regular);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.tw-audit-settings {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.tw-audit-head .tw-audit-meta {
  margin-top: var(--token-layout-hair-gap);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.tw-audit-head .btn {
  font-size: var(--token-fs-sm);
}

/* The verdict on its state's ground, the figure on the raised surface. */
.tw-verdict {
  display: flex;
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: calc(var(--token-radius-md) + var(--token-layout-hair-gap));
  overflow: hidden;
}

.tw-verdict-main {
  flex: 1 1 auto;
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-4);
  padding: calc(var(--token-space-5) + var(--token-layout-hair-gap)) calc(var(--token-space-6) + var(--token-layout-hair-gap));
  background: var(--token-color-surface-inset);
}

.tw-v-crit .tw-verdict-main {
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tw-v-warn .tw-verdict-main {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.tw-v-ok .tw-verdict-main {
  background: var(--token-color-state-ok-bg);
  color: var(--token-color-state-ok-text);
}

.tw-verdict-main p {
  margin: 0;
}

.tw-verdict-icon {
  flex: none;
  width: calc(var(--token-space-6) + var(--token-space-1));
  height: calc(var(--token-space-6) + var(--token-space-1));
  margin-top: var(--token-layout-hair-gap);
}

.tw-verdict-title {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-xl);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.tw-verdict-main .tw-verdict-text {
  margin-top: var(--token-layout-pill-gap);
  font-size: calc(var(--token-fs-sm) + var(--token-border-hair));
  line-height: 1.5;
  color: var(--token-color-text-primary);
}

.tw-verdict-score {
  flex: 0 0 calc(var(--token-layout-panel-min) - var(--token-space-5));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--token-space-1);
  padding: var(--token-layout-block-gap) var(--token-space-6);
  border-left: var(--token-border-hair) solid var(--token-color-border-subtle);
  background: var(--token-color-surface-raised);
}

.tw-verdict-score p {
  margin: 0;
}

.tw-score-label {
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

.tw-score {
  display: flex;
  align-items: baseline;
  gap: var(--token-layout-pill-gap);
}

.tw-score-figure {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-2xl);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.tw-score-of {
  color: var(--token-color-text-tertiary);
}

/* The four parts of the figure, each a bar with its weight. */
.tw-parts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.tw-part {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: var(--token-space-4) var(--token-layout-block-gap);
}

.tw-part + .tw-part {
  border-left: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tw-part p {
  margin: 0;
}

.tw-part-head {
  display: flex;
  justify-content: space-between;
  gap: var(--token-space-2);
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

.tw-part-head > :first-child {
  font-size: var(--token-fs-xs-plus);
}

.tw-part-weight {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
}

.tw-part-figure {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-h2);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.tw-part .meter {
  display: block;
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

.tw-part .meter > span {
  display: block;
  height: 100%;
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-fill);
}

/* Under the four parts, across all of them: the weighted sum and the line
   about the formula, as the original's readiness card closes its breakdown. */
.tw-parts-sum {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-1) var(--token-space-4);
  padding: var(--token-space-3) var(--token-layout-block-gap);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tw-parts-sum p {
  margin: 0;
}

.tw-parts-total {
  display: inline-flex;
  align-items: baseline;
  gap: var(--token-space-2);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tw-parts-total b {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
  font-variant-numeric: tabular-nums;
}

.tw-parts-formula {
  flex: 1 1 0;
  min-width: 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* The views of the report, and the severity counts beside them. The bar
   stays in view while a long view scrolls under it. */
.tw-audit-bar {
  position: sticky;
  top: 0;
  z-index: var(--token-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  background: var(--token-color-surface);
}

.tw-audit-bar .seg a {
  height: calc(var(--token-space-8) + var(--token-layout-hair-gap));
  padding: 0 calc(var(--token-space-3) + var(--token-layout-hair-gap));
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  background: none;
  box-shadow: none;
}

.tw-audit-bar .seg b {
  color: inherit;
}

.tw-audit-bar .seg b.is-crit {
  color: var(--token-color-state-crit-text);
}

.tw-audit:has(#blockers:target) .tw-audit-bar a[data-view='blockers'],
.tw-audit:has(#actions:target) .tw-audit-bar a[data-view='actions'],
.tw-audit:has(#matrix:target) .tw-audit-bar a[data-view='matrix'],
.tw-audit:has(#findings:target) .tw-audit-bar a[data-view='findings'],
.tw-audit:not(:has(.tw-view:target)) .tw-audit-bar a[data-view='blockers'] {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  box-shadow: 0 var(--token-border-hair) var(--token-layout-hair-gap) color-mix(in srgb, var(--token-color-text-primary) 8%, transparent);
}

.tw-sev {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--token-space-2);
}

.tw-views {
  display: flex;
  flex-direction: column;
}

.tw-view {
  display: none;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
  scroll-margin-top: var(--token-space-16);
}

.tw-view:target,
.tw-views:not(:has(> .tw-view:target)) > #blockers {
  display: flex;
}

.tw-view > * {
  margin: 0;
}

.tw-view-empty {
  padding: var(--token-space-4) 0;
  color: var(--token-color-text-tertiary);
}

/* One finding: severity and place, the title, four labelled answers. */
.tw-issue {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  padding: calc(var(--token-space-5) + var(--token-layout-hair-gap)) var(--token-space-6);
}

.tw-issue > * {
  margin: 0;
}

.tw-issue-head {
  display: flex;
  align-items: center;
  gap: var(--token-layout-item-pad-x);
}

.tw-issue-ref {
  /* Usually «REQ-021», but the reference is the model's words and can be a
     sentence of the RFP (400 characters on WHO's audit): it wraps, or the
     issue head — and the page with it — grows to fit it on one line. */
  flex: 0 1 auto;
  min-width: 0;
  font-family: var(--token-font-mono);
  font-size: calc(var(--token-fs-xs) + var(--token-border-hair) / 2);
  color: var(--token-color-text-tertiary);
  overflow-wrap: break-word;
}

.tw-issue-meta {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tw-issue-head .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-primary);
}

.tw-issue-title {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-h3);
  font-weight: var(--token-weight-regular);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.tw-kv {
  display: grid;
  grid-template-columns: calc(var(--token-layout-col-when)) minmax(0, 1fr);
  gap: var(--token-layout-item-pad-x) var(--token-layout-block-gap);
  margin: 0;
}

.tw-kv dt {
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

.tw-kv dd {
  margin: 0;
  font-size: var(--token-fs-sm);
  line-height: 1.5;
}

.tw-kv dd.tw-do {
  font-weight: var(--token-weight-medium);
}

.tw-evs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-layout-pill-gap);
}

.tw-ev {
  display: inline-flex;
  align-items: center;
  gap: var(--token-layout-pill-gap);
  padding: calc(var(--token-space-1) + var(--token-border-hair)) var(--token-layout-item-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-inset);
  color: var(--token-color-text-primary);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
}

a.tw-ev:hover {
  text-decoration: none;
  border-color: var(--token-color-accent-fill);
}

.tw-ev-at {
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.tw-ev .tw-mark {
  height: calc(var(--token-space-4) + var(--token-layout-hair-gap));
}

.tw-children {
  display: grid;
  gap: var(--token-space-2);
  margin: var(--token-space-2) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--token-fs-xs-plus);
}

/* The plan: numbered, each action with its reason. */
.tw-plan {
  margin: 0;
  padding: 0;
  list-style: none;
}

.tw-plan li {
  display: grid;
  grid-template-columns: var(--token-space-6) minmax(0, 1fr);
  gap: var(--token-space-3);
  padding: calc(var(--token-space-3) + var(--token-layout-hair-gap)) var(--token-layout-block-gap);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tw-plan li:last-child {
  border-bottom: 0;
}

.tw-plan p {
  margin: 0;
  line-height: 1.5;
}

.tw-plan-n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--token-space-6);
  height: var(--token-space-6);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
  font-size: var(--token-fs-xs);
  font-variant-numeric: tabular-nums;
}

.tw-plan-why {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.tw-plan-warn {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-state-warn-text);
}

.tw-matrix-t .tw-c-ref {
  width: calc(var(--token-layout-col-duration) - var(--token-space-5) - var(--token-layout-hair-gap));
}

.tw-matrix-t .tw-c-must {
  width: var(--token-layout-col-duration);
}

.tw-matrix-t .tw-c-state {
  width: var(--token-layout-col-state);
}

.tw-matrix-t .tw-c-gap {
  width: 30%;
}

.tw-method {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
}

.tw-method > * {
  margin: 0;
}

@media (max-width: 900px) {
  .tw-verdict {
    flex-direction: column;
  }

  .tw-verdict-score {
    flex-basis: auto;
    border-left: 0;
    border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tw-parts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

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

/* -------------------------------------------------------- audits list
   Every audit as a row of the same card table, and the launch as a card of
   choices — no native menus. */
.tw-audits-t td {
  vertical-align: middle;
}

.tw-audits-t .tw-c-tick {
  width: var(--token-layout-col-tick);
}

.tw-audits-t .tw-c-verdict {
  width: var(--token-layout-col-state);
}

.tw-audits-t .tw-c-score {
  width: var(--token-layout-col-when);
}

.tw-audits-t .tw-c-found {
  width: calc(var(--token-layout-col-action) + var(--token-space-6));
}

.tw-audits-t .tw-c-when {
  width: calc(var(--token-layout-col-action) + var(--token-space-2));
}

.tw-audits-t a.row-act {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.tw-sub {
  display: block;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tw-model {
  font-family: var(--token-font-mono);
}

.tw-row-figure {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  font-variant-numeric: tabular-nums;
}

.tw-row-figure.is-ok,
.tw-score-figure.is-ok {
  color: var(--token-color-state-ok-text);
}

.tw-row-figure.is-warn,
.tw-score-figure.is-warn {
  color: var(--token-color-state-warn-text);
}

.tw-row-figure.is-crit,
.tw-score-figure.is-crit {
  color: var(--token-color-state-crit-text);
}

.tw-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
}

.tw-tick {
  vertical-align: middle;
}

.tw-compare {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-space-2) var(--token-space-2) var(--token-space-2) var(--token-space-4);
  border-radius: var(--token-radius-seg);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
  font-size: var(--token-fs-sm);
}

.tw-compare form.inline {
  margin: 0;
}

.tw-compare .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.tw-launch,
.tw-running {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-4);
  padding: calc(var(--token-space-5) + var(--token-layout-hair-gap)) var(--token-space-6);
}

.tw-launch > *,
.tw-running > * {
  margin: 0;
}

.tw-launch-title {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  font-weight: var(--token-weight-regular);
  line-height: 1.15;
}

.tw-launch form {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-4);
  margin: 0;
}

.tw-launch-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-4) var(--token-space-8);
}

/* A choice as a row of options, each a pill that fills when it is the one. */
.tw-launch .radios {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
  margin: 0;
  padding: 0;
  border: 0;
}

.tw-launch .radios > legend {
  float: left;
  width: 100%;
  margin-bottom: 0;
  padding: 0;
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
  text-transform: none;
  letter-spacing: 0;
}

.tw-launch .pick {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-space-3) 0 var(--token-layout-item-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  cursor: pointer;
}

.tw-launch .pick:has(input:checked) {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.tw-launch .pick input {
  width: var(--token-space-4);
  height: var(--token-space-4);
}

.tw-launch-facts {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tw-launch-facts > * {
  margin: 0;
}

.tw-launch-facts ul {
  margin: 0;
  padding-left: var(--token-space-4);
}

.tw-launch-warn {
  padding: var(--token-space-3) var(--token-space-4);
  border-radius: var(--token-radius-seg);
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
  font-size: var(--token-fs-xs-plus);
}

.tw-launch-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--token-space-3);
  padding-top: var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tw-running ul {
  display: grid;
  gap: var(--token-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--token-fs-xs-plus);
}

/* «Як рахується»: the report's own panels, drawn as the rest of the page —
   cards with a quiet caption, and each figure beside its name. */
.tw-method .panel {
  margin: 0;
  padding: var(--token-layout-block-gap) calc(var(--token-space-5) + var(--token-layout-hair-gap));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
}

.tw-method .panel > * + * {
  margin-top: var(--token-space-3);
}

.tw-method .panel > .cap {
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
  text-transform: none;
  letter-spacing: 0;
}

.tw-method .panel ul {
  display: grid;
  gap: var(--token-layout-pill-gap);
  margin-left: 0;
  margin-right: 0;
  padding: 0;
  list-style: none;
}

.tw-method .panel li {
  display: flex;
  justify-content: space-between;
  gap: var(--token-space-3);
  line-height: 1.5;
}

.tw-method .panel li > .mono {
  font-family: var(--token-font-body);
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-primary);
}

.tw-method .panel .figure,
.tw-method .panel > p.mono {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-h2);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.tw-method .panel .note {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tw-formula-sum {
  padding-top: var(--token-space-2);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-weight: var(--token-weight-medium);
}

/* A narrow screen: the file list's columns share what there is, and the
   heads wrap rather than squeeze their titles. */
@media (max-width: 1100px) {
  .tw-docs {
    --tw-docs-cols: minmax(0, 1.2fr) minmax(0, 1fr) auto calc(var(--token-space-16) + var(--token-space-5))
      calc(var(--token-space-16) + var(--token-space-2));
  }

  /* The switch column is narrower than its heading here: the heading takes
     two lines rather than losing its end. */
  .tw-docs-head > .tw-center {
    white-space: normal;
    text-align: center;
  }

  .tw-prop-head,
  .tw-audit-head {
    flex-wrap: wrap;
  }

  .tw-prop-head .grow,
  .tw-audit-head .grow {
    flex-basis: 100%;
  }
}

/* A tender with no requirements yet: the heading, the banner and the offer,
   in the same column as the list would be. */
.tw-req-empty {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
  padding-top: var(--token-layout-hair-gap);
}

.tw-req-empty > * {
  margin: 0;
}

/* restore D: the audit report's method view as a segment of its own, the
   evidence quotes as visible blocks under their chips, and merged findings
   expanded into whole cards. */
.tw-audit:has(#method:target) .tw-audit-bar a[data-view='method'] {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  box-shadow: 0 var(--token-border-hair) var(--token-layout-hair-gap) color-mix(in srgb, var(--token-color-text-primary) 8%, transparent);
}

.tw-audit-head .crumbs {
  margin-bottom: var(--token-space-1);
}

.tw-ev-list {
  display: grid;
  gap: var(--token-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tw-ev-list > li {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-1);
}

.tw-quote {
  margin: 0;
  padding: var(--token-space-1) 0 var(--token-space-1) var(--token-space-3);
  border-left: var(--token-border-thick) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

.tw-children > .tw-issue {
  padding: var(--token-space-4) var(--token-layout-block-gap);
  background: var(--token-color-surface);
}

/* restore C: a proposal row's remark says every fact that applies — a blocker,
   an extraction error, «Замінити», «повтор назви» — so the cell wraps rather
   than clipping the second one. */
.tw-prop .tw-row > .tw-cell {
  flex-wrap: wrap;
}

/* ------------------------------------------------ parity with the original */

/* «High» in the original's scale is orange; the platform has red and amber,
   so the warning chip is drawn in their mix — tokens only. */
.tw-sev-high .badge {
  background: color-mix(in srgb, var(--token-badge-crit-bg) 50%, var(--token-badge-warn-bg));
  color: color-mix(in srgb, var(--token-badge-crit-fg) 45%, var(--token-badge-warn-fg));
}

.tw-sev-high {
  display: inline-flex;
}

/* A finding's card, tinted by its severity (AuditResult.tsx:204-211). */
.tw-issue-critical {
  border-color: color-mix(in srgb, var(--token-color-state-crit-text) 30%, var(--token-color-border-subtle));
  background: color-mix(in srgb, var(--token-color-state-crit-bg) 35%, var(--token-color-surface-raised));
}

.tw-issue-high {
  border-color: color-mix(in srgb, color-mix(in srgb, var(--token-color-state-crit-text) 50%, var(--token-color-state-warn-text)) 30%, var(--token-color-border-subtle));
  background: color-mix(in srgb, color-mix(in srgb, var(--token-color-state-crit-bg) 50%, var(--token-color-state-warn-bg)) 35%, var(--token-color-surface-raised));
}

.tw-issue-medium {
  border-color: color-mix(in srgb, var(--token-color-state-warn-text) 30%, var(--token-color-border-subtle));
  background: color-mix(in srgb, var(--token-color-state-warn-bg) 35%, var(--token-color-surface-raised));
}

.tw-issue-low {
  border-color: color-mix(in srgb, var(--token-color-state-ok-text) 30%, var(--token-color-border-subtle));
  background: color-mix(in srgb, var(--token-color-state-ok-bg) 35%, var(--token-color-surface-raised));
}

/* A reviewed finding steps back and its title is struck (AuditResult.tsx:940, :953). */
.tw-issue.is-reviewed {
  opacity: 0.5;
}

.tw-issue.is-reviewed .tw-issue-title {
  text-decoration: line-through;
}

.tw-review {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: calc(var(--token-space-6) + var(--token-space-1));
  height: calc(var(--token-space-6) + var(--token-space-1));
  padding: 0;
  border: var(--token-border-thick) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-pill);
  background: transparent;
  color: var(--token-color-text-tertiary);
  cursor: pointer;
}

.tw-review svg {
  width: var(--token-space-4);
  height: var(--token-space-4);
}

.tw-review[aria-pressed='true'] {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-fill);
  color: var(--token-color-on-accent);
}

.tw-review[hidden],
.tw-review-show[hidden],
[data-review-empty][hidden],
[data-review-reviewed][hidden] {
  display: none;
}

/* Detailed Findings: the search, the severity chips and the reviewed switch. */
.tw-find {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
}

.tw-find-q {
  flex: 1 1 var(--token-layout-field-basis);
  max-width: var(--token-layout-search);
}

.tw-find-q input {
  width: 100%;
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  font: inherit;
}

.tw-find-sev {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
}

.tw-sev-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-chip);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs);
  cursor: pointer;
}

.tw-sev-chip-critical:has(input:checked) {
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tw-sev-chip-high:has(input:checked) {
  background: color-mix(in srgb, var(--token-color-state-crit-bg) 50%, var(--token-color-state-warn-bg));
  color: color-mix(in srgb, var(--token-color-state-crit-text) 45%, var(--token-color-state-warn-text));
}

.tw-sev-chip-medium:has(input:checked) {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.tw-sev-chip-low:has(input:checked) {
  background: var(--token-color-state-ok-bg);
  color: var(--token-color-state-ok-text);
}

.tw-review-show {
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-chip);
  background: transparent;
  color: var(--token-color-text-secondary);
  font: inherit;
  font-size: var(--token-fs-xs);
  cursor: pointer;
}

.tw-review-show[aria-pressed='true'] {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.tw-find-clear {
  font-size: var(--token-fs-xs);
}

.tw-find-count {
  margin: 0;
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-sm);
}

.tw-reviewed {
  padding: 0 var(--token-layout-pill-gap);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-xs);
}

.tw-no-match {
  padding: var(--token-space-10) var(--token-space-4);
  border: var(--token-border-hair) dashed var(--token-color-border-strong);
  border-radius: var(--token-radius-lg);
  color: var(--token-color-text-tertiary);
  text-align: center;
}

/* A section with nothing in it is not drawn; the first one there is shows
   when the address names none. */
.tw-views:not(:has(> .tw-view:target)) > .tw-view.is-default {
  display: flex;
}

.tw-audit:not(:has(.tw-view:target)) .tw-audit-bar a.is-default {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  box-shadow: 0 var(--token-border-hair) var(--token-layout-hair-gap) color-mix(in srgb, var(--token-color-text-primary) 8%, transparent);
}

/* The scoring note, in view and edged amber (AuditResult.tsx:1417-1424). */
.tw-scoring-note {
  margin: 0;
  padding: var(--token-space-2) var(--token-space-3);
  border: var(--token-border-hair) solid color-mix(in srgb, var(--token-color-state-warn-text) 40%, transparent);
  border-radius: var(--token-radius-md);
  background: color-mix(in srgb, var(--token-color-state-warn-bg) 40%, transparent);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs);
}

.tw-tone-crit {
  color: var(--token-color-state-crit-text);
}

.tw-tone-warn {
  color: var(--token-color-state-warn-text);
}

.tw-link-why {
  color: var(--token-color-text-secondary);
  font-style: italic;
}

/* The launch panel: the evidence size in its colour (Audits.tsx:25-31)… */
.tw-size {
  font-weight: var(--token-weight-medium);
}

.tw-size-crit {
  color: var(--token-color-state-crit-text);
}

.tw-size-high {
  color: color-mix(in srgb, var(--token-color-state-crit-text) 50%, var(--token-color-state-warn-text));
}

.tw-size-warn {
  color: var(--token-color-state-warn-text);
}

.tw-size-ok {
  color: var(--token-color-state-ok-text);
}

/* …and the route of the strictness whose radio is checked. */
.tw-route {
  display: none;
}

.tw-launch:has(input[name='strictness'][value='maximum_red_team']:checked) .tw-route[data-for='maximum_red_team'],
.tw-launch:has(input[name='strictness'][value='strict']:checked) .tw-route[data-for='strict'],
.tw-launch:has(input[name='strictness'][value='standard']:checked) .tw-route[data-for='standard'] {
  display: block;
}

.tw-launch-danger {
  color: var(--token-color-state-crit-text);
  font-weight: var(--token-weight-medium);
}

/* A running stage's clock, which the script moves every second. */
.tw-tick {
  font-variant-numeric: tabular-nums;
  color: var(--token-color-accent-text);
}

/* Screen-shaped rules for the tenders-registry screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   The group: Opportunities (queue, overview, one lead, sources & scoring —
   board «Можливості») and Experience (registry, overview, evidence library,
   review queue — board «Досвід»). Every page of the group wraps its body in
   `.tr-page`, so nothing here reaches a screen that is not one of them. */

/* ------------------------------------------------------------------ frame
   28 above, the frame's own sides (the column starts at the same x on every
   page), 16 and 18 between blocks. */
.wrap:has(> .tr-page) {
  padding-top: calc(var(--token-space-6) + var(--token-space-1));
}

.tr-page {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-4);
  min-width: 0;
}

.tr-page.tr-exp {
  gap: var(--token-layout-block-gap);
}

.tr-page > * {
  margin: 0;
}

.tr-page > section {
  padding-top: 0;
}

/* The head: title and lede on the left, the section switcher and the one
   action on the right, bottoms aligned. The lede is one line on the board. */
.tr-page > .hero {
  align-items: flex-end;
  gap: var(--token-space-4);
  flex-wrap: wrap;
  padding: 0;
}

/* The title and its line keep an aside's width before the actions give way
   and go under them: on one unwrapping row the «Досвід» head at 1280px left
   its line 93px — seven lines of two words each. */
.tr-page > .hero .hero-text {
  flex: 1 1 var(--token-layout-aside);
  min-width: min(var(--token-layout-aside), 100%);
}

.tr-page > .hero .lede {
  max-width: none;
  margin-top: calc(var(--token-space-1) * 1.5);
  color: var(--token-color-text-tertiary);
}

.tr-page > .hero .hero-action {
  display: flex;
  align-items: center;
  gap: var(--token-space-4);
  padding: 0;
}

.tr-page > .hero .hero-action > form.inline {
  display: inline-flex;
}

/* The Opportunities switcher: its own row under the title, on the left — the
   head's right holds only «Синхронізувати зараз». */
.tr-opp > .opp-sections {
  display: flex;
  justify-content: flex-start;
  min-width: 0;
}

.tr-page .seg a {
  color: var(--token-color-text-secondary);
}

.tr-page .seg a[aria-current='true'] {
  color: var(--token-color-text-primary);
  background: var(--token-color-surface-raised);
}

/* ------------------------------------------------------------ filter chips
   «Статус: Нові ▾» — a 32px chip, the choice in force in the text colour. */
.fchip-menu > summary.fchip {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  height: calc(var(--token-space-8));
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  line-height: 1;
  color: var(--token-color-text-secondary);
  white-space: nowrap;
}

.fchip-menu > summary.fchip:hover,
.fchip-menu[open] > summary.fchip {
  border-color: var(--token-color-text-tertiary);
}

.fchip-menu > summary.fchip b {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-primary);
}

.fchip-menu .fcaret {
  /* The board's «▾» is the system face's: Plex draws it twice the size. */
  font-family: system-ui, sans-serif;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.fchip-menu .menu {
  left: 0;
  right: auto;
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.fchip-menu .menu a {
  font-size: var(--token-fs-xs-plus);
}

.fchip-menu .menu-tall {
  max-height: calc(var(--token-layout-aside) * 0.9);
  overflow-y: auto;
}

/* ---------------------------------------------------------------- the bar */
.opp-bar,
.opp-quick,
.exp-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  min-width: 0;
}

.opp-bar .grow,
.exp-bar .grow,
.card-foot .grow {
  flex: 1 1 auto;
}

.opp-bar form.inline,
.exp-bar form.inline {
  display: inline-flex;
}

.opp-bar .field:has(> .sr) {
  flex: 0 0 auto;
  width: calc(var(--token-space-24) * 3 - var(--token-space-2));
  max-width: 100%;
  background: var(--token-color-surface-raised);
}

.bar-count,
.opp-quick-note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
}

.bar-count a {
  color: inherit;
}

.bar-count a:hover {
  color: var(--token-color-accent-text);
}

.bar-clear {
  font-size: var(--token-fs-xs-plus);
  padding: 0 var(--token-space-1);
}

/* The queue's quick filters: their row of toggles, a hair between the
   thresholds and the connectors. */
.opp-quick-sep {
  width: var(--token-border-hair);
  height: var(--token-space-5);
  margin: 0 var(--token-space-1);
  background: var(--token-color-border-subtle);
}

/* ---------------------------------------------------------------- the card
   The table's frame: rows reach its edges, 12 in from the side, and its foot
   is a bar of its own under a rule. */
.tr-page .panel:has(> .scroller) {
  padding: 0;
  overflow: hidden;
}

.tr-page .panel > .scroller th {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-layout-cell-pad-x);
}

.tr-page .panel > .scroller td {
  padding: 0 var(--token-layout-cell-pad-x);
}

.tr-page .panel > .scroller th:first-child,
.tr-page .panel > .scroller td:first-child,
.tr-page .panel > .scroller th:last-child,
.tr-page .panel > .scroller td:last-child {
  padding-inline: var(--token-layout-cell-pad-x);
}

.tr-page .panel > .scroller td.detail {
  height: auto;
}

/* Wraps on a phone: the count, «1 / 2» and both page links on one row ran
   «Далі» past the card's edge. */
.card-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  padding: calc(var(--token-space-2) + var(--token-layout-hair-gap)) var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.card-foot .note {
  font-size: var(--token-fs-xs-plus);
}

.card-foot a {
  white-space: nowrap;
}

.card-foot .tn {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-primary);
}

/* The quiet parts of a row. */
.tr-page .sec {
  color: var(--token-color-text-secondary);
}

.tr-page .dim {
  color: var(--token-color-text-tertiary);
}

.tr-page td .sub {
  display: block;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tr-page td .sub .mono {
  font-size: var(--token-fs-xs);
  color: inherit;
}

.tr-page td .sub.soon {
  color: var(--token-color-state-warn-text);
}

.tr-page td span.cl1 {
  font-weight: var(--token-weight-regular);
}

.tr-page td span.cl1.sec {
  color: var(--token-color-text-secondary);
}

.tr-page td span.cl1.sub {
  color: var(--token-color-text-tertiary);
}

/* A sub line with something at its end that must stay in sight — a lead's
   «Прийом не визначено», a record's «Нотатки». As one ellipsis line the tail
   was the part cut: the text gives up its end, the tail keeps its width. */
.tr-page td .sub.sub-row {
  display: flex;
  align-items: baseline;
  gap: var(--token-space-1);
  min-width: 0;
}

.tr-page td .sub-row > .cl1 {
  flex: 0 1 auto;
  min-width: 0;
  color: inherit;
}

.tr-page td .sub-row > .sub-tail {
  flex: none;
  white-space: nowrap;
}

.tr-page td .when {
  display: block;
  font-variant-numeric: tabular-nums;
}

.tr-page tr.row-dim > td .sec {
  color: var(--token-color-text-tertiary);
}

/* --------------------------------------------------------- opportunities
   The nine columns of `@tenders/web`'s list on the board's card, by name:
   country 52 · opportunity, the rest · source 72 · buyer 15% · status 120 ·
   score 100 · value 112 · deadline 128 · dates (published over updated) 120.
   The opportunity's name takes the rest — the country is a flag alone, the
   value shortened, the two dates one column. Scoped to the list's card — the
   dashboard is a `.tr-opp` page too, and its lead tables name their columns
   differently. */
.tr-opp .opp-card table.fixed col[data-col="country"] {
  width: calc(var(--token-space-12) + var(--token-space-1));
}

.tr-opp .opp-card table.fixed col[data-col="source"] {
  width: calc(var(--token-space-16) + var(--token-space-2));
}

/* The buyer grows with the table — at a fixed 120px a 1590px-wide queue set
   «СПЕЦІАЛІЗОВАНЕ КОМУНАЛЬНЕ ПІДПРИЄМСТВО» a syllable a line — as 15% of it:
   164px on a 1440 screen, 240px at 1590. A plain share, because a `<col>`
   drops a `max()` with a percentage and the column then split the rest
   evenly with the opportunity's name. */
.tr-opp .opp-card table.fixed col[data-col="buyer"] {
  width: 15%;
}

.tr-opp .opp-card table.fixed col[data-col="status"] {
  width: calc(var(--token-space-24) - var(--token-space-2) + var(--token-border-hair) + var(--token-border-hair));
}

.tr-opp .opp-card table.fixed col[data-col="score"] {
  width: calc(var(--token-space-24) + var(--token-space-1));
}

/* Published over Updated: wide enough for «Оновлено» and the sort glyph
   after it on the header's second line. */
.tr-opp .opp-card table.fixed col[data-col="dates"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

/* The value, shortened — «4.235M UAH» — needs a step over 100. */
.tr-opp .opp-card table.fixed col[data-col="value"] {
  width: calc(var(--token-space-24) + var(--token-space-4));
}

/* The deadline a notch wider: its «Прийом не визначено» badge took three
   lines in 100px. */
.tr-opp .opp-card table.fixed col[data-col="deadline"] {
  width: calc(var(--token-space-24) + var(--token-space-8));
}

/* The value right-aligned beside a left-aligned deadline: a step apart. */
.tr-opp .opp-card td.num {
  white-space: nowrap;
  padding-right: var(--token-space-5);
}

.tr-opp .opp-card table.fixed th {
  white-space: nowrap;
}

/* «Опубліковано / Оновлено» on two lines, as the two dates under it. */
.tr-opp .opp-card table.fixed th[data-col="dates"] {
  white-space: normal;
}

.tr-opp .panel > .scroller td {
  height: calc(var(--token-space-12) + var(--token-space-2) + var(--token-border-hair) + var(--token-border-hair));
}

/* The score: a 38 × 28 tile — a number, not a state, so no glyph. */
.score {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--token-space-10) - var(--token-border-hair) - var(--token-border-hair));
  height: calc(var(--token-space-6) + var(--token-space-1));
  border-radius: var(--token-radius-sm);
  font-size: var(--token-fs-sm);
  font-variant-numeric: tabular-nums;
}

.score.s-ok {
  color: var(--token-color-state-ok-text);
  background: var(--token-color-state-ok-bg);
}

.score.s-neutral {
  color: var(--token-color-state-neutral-text);
  background: var(--token-color-state-neutral-bg);
}

.score.s-none {
  color: var(--token-color-text-tertiary);
}

/* ✓ and ✕: 30 × 30 squares, 6 apart; the ✓ in the ok colour. */
.tr-page form.inline:has(> .ib) {
  gap: calc(var(--token-space-1) * 1.5);
}

.ib {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--token-layout-control-h-sm);
  height: var(--token-layout-control-h-sm);
  padding: 0;
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-secondary);
  cursor: pointer;
}

.ib .ico {
  width: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  height: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  stroke-width: 2.6;
}

.ib.ib-ok {
  color: var(--token-color-state-ok-text);
}

.ib.ib-ok .ico {
  stroke-width: 3;
}

.ib:hover {
  border-color: var(--token-color-text-tertiary);
}

.ib.ib-ok:hover,
.ib.ib-ok.ib-on {
  border-color: var(--token-color-state-ok-text);
  background: var(--token-color-state-ok-bg);
}

.ib.ib-on:not(.ib-ok) {
  border-color: var(--token-color-text-secondary);
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-primary);
}

.ib:focus-visible {
  outline: var(--token-border-thick) solid var(--token-color-accent-fill);
  outline-offset: var(--token-border-hair);
}

/* Narrower than the head's one row — the side column still beside the page
   at 820 leaves it about 530 — the title and its line take the row, and the
   switcher and the action go under it, wrapping inside the page's width. With
   `flex: none` the action kept its one-row width and ran past the edge. */
@media (max-width: 1100px) {
  .tr-page > .hero {
    flex-wrap: wrap;
  }

  .tr-page > .hero .hero-text {
    flex: 1 1 100%;
  }

  .tr-page > .hero .hero-action {
    flex: 1 1 100%;
    min-width: 0;
    flex-wrap: wrap;
    gap: var(--token-space-2) var(--token-space-4);
  }
}

/* ------------------------------------------------------------- experience
   The registry as the «Досвід» board draws it: 13px rows 48 tall, a found
   list with ticks and one bar, a card for the first run. */
.tr-exp .panel > .scroller td {
  height: var(--token-space-12);
  font-size: var(--token-fs-xs-plus);
}

.tr-exp .panel > .scroller td .badge {
  vertical-align: middle;
}

/* The first run: «У реєстрі ще немає перевірених проєктів». */
.intro-card.panel {
  display: flex;
  align-items: center;
  gap: var(--token-space-5);
  padding: calc(var(--token-space-5) + var(--token-layout-hair-gap)) var(--token-space-6);
}

.intro-card > * + * {
  margin-top: 0;
}

.intro-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--token-space-12);
  height: var(--token-space-12);
  border-radius: var(--token-radius-md);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.intro-ico .ico {
  width: calc(var(--token-space-5) + var(--token-layout-hair-gap));
  height: calc(var(--token-space-5) + var(--token-layout-hair-gap));
  stroke-width: 1.8;
}

.intro-text {
  flex: 1 1 auto;
  min-width: 0;
}

.intro-text h2 {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-md);
  font-weight: var(--token-weight-medium);
  line-height: var(--token-lh-normal);
  letter-spacing: 0;
  margin: 0;
}

.intro-text p {
  margin-top: var(--token-layout-hair-gap);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

/* «Знайдено в документах 25 з аудиту #1 · не перевірено … [пошук]». */
.found {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-2) + var(--token-layout-hair-gap));
  padding-top: 0;
}

.found > * {
  margin: 0;
}

.found-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-3);
  min-width: 0;
}

/* The search goes under the heading on a phone instead of leaving it 172px
   and three lines tall. */
.found-head form {
  flex: 0 1 var(--token-layout-panel-min);
  min-width: 0;
}

.found-head h2 {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  font-weight: var(--token-weight-regular);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0;
}

.found-head .n {
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.found-head .note {
  font-size: var(--token-fs-xs-plus);
}

.found-head .note a,
.bar-count a {
  color: inherit;
}

.found-head .grow {
  flex: 1 1 auto;
}

.found-head .field:has(> .sr),
.exp-bar .field:has(> .sr) {
  flex: 0 0 auto;
  width: var(--token-layout-search);
  max-width: 100%;
  background: var(--token-color-surface-raised);
}

.found .select-bar {
  gap: calc(var(--token-space-3) + var(--token-layout-hair-gap));
}

.found .select-bar .select-count {
  font-size: var(--token-fs-sm);
}

.found .select-bar .btn-primary {
  font-weight: var(--token-weight-medium);
}

.found-card.panel {
  padding: 0;
  overflow: hidden;
}

.found-card > * + * {
  margin-top: 0;
}

/* 40 · the rest · 250 · 260 · 152 — the board's columns, except the last. The
   board's 90 held its own label; ours, «Додати до реєстру», is 114 wide plus
   the cell's 32 of padding, and the card clips (overflow: hidden) rather than
   scrolls, so at 90 the action was cut in half with no way to reach it. */
.found-card table.fixed col[data-col="tick"] {
  width: var(--token-space-10);
}

.found-card table.fixed col[data-col="customer"] {
  width: var(--token-layout-card-min);
}

.found-card table.fixed col[data-col="source"] {
  width: calc(var(--token-layout-card-min) + var(--token-space-2) + var(--token-layout-hair-gap));
}

.found-card table.fixed col[data-col="action"] {
  width: calc(var(--token-space-24) + var(--token-space-12) + var(--token-space-2));
}

.found-card td:last-child :is(a, button) {
  white-space: nowrap;
}

.found-card .scroller th {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-layout-cell-pad-x);
}

.found-card .scroller td {
  height: var(--token-space-12);
  padding: 0 var(--token-layout-cell-pad-x);
  font-size: var(--token-fs-xs-plus);
}

.found-card .scroller th:first-child,
.found-card .scroller td:first-child,
.found-card .scroller th:last-child,
.found-card .scroller td:last-child {
  padding-inline: var(--token-layout-cell-pad-x);
}

/* A table's caption is for assistive tech: the heading above already says it. */
.tr-page .panel caption {
  position: absolute;
  width: var(--token-size-hidden);
  height: var(--token-size-hidden);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The board's tick: 16 square, 4 round, a 1.5 rule. */
.found-card td.tick input[type='checkbox'] {
  width: var(--token-space-4);
  height: var(--token-space-4);
  border-radius: var(--token-space-1);
  border-color: var(--token-color-border-strong);
  vertical-align: middle;
}

.found-card td.tick input[type='checkbox']::before {
  width: calc(var(--token-space-2) + var(--token-layout-hair-gap));
  height: calc(var(--token-space-2) + var(--token-layout-hair-gap));
}

.found-card .row-title {
  color: var(--token-color-text-primary);
}

.found-card .row-title.row-act {
  font-weight: var(--token-weight-medium);
}

/* «Показати всі» without a script: the rows past ten are in the page and
   shown while the card is the URL's target. */
.found-card:not(:target) tr.more {
  display: none;
}

/* The last row shown closes the card without a rule of its own. */
.found-card:not(:target) tr:has(+ tr.more) > td {
  border-bottom: 0;
}

.found-card:target .when-folded,
.found-card:not(:target) .when-open {
  display: none;
}

.found-card {
  scroll-margin-top: var(--token-space-6);
}

/* A cited document, as a small sunken chip. */
.tr-page .file {
  display: inline-block;
  max-width: 100%;
  padding: var(--token-layout-hair-gap) var(--token-space-2);
  border-radius: var(--token-radius-chip);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-xs);
  line-height: var(--token-lh-normal);
  color: var(--token-color-text-secondary);
  vertical-align: middle;
}

.tr-page a.file:hover {
  color: var(--token-color-text-primary);
  text-decoration: none;
}

/* A form's button drawn as a link — «Додати» at a row's end. */
.linkish-btn {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--token-color-accent-text);
  cursor: pointer;
}

.linkish-btn:hover {
  text-decoration: underline;
}

.tr-page td.num form.inline {
  justify-content: flex-end;
}

.tr-exp .exp-card > .scroller td {
  height: calc(var(--token-space-12) + var(--token-space-3));
}

.exp-card td .badge + .sub {
  margin-top: var(--token-layout-hair-gap);
}

.card-foot .sizes {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

.card-foot .sizes b {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-primary);
}

.card-foot .quiet-link {
  color: var(--token-color-text-tertiary);
}

/* The row's «⋯» menu. */
.row-menu > summary.ib {
  list-style: none;
}

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

.row-menu .menu {
  right: 0;
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

/* «Усі фільтри»: the rest of the filters in a sheet under the chip. */
.more-filters .more-sheet {
  width: min(calc(var(--token-layout-aside) * 2.2), calc(100vw - var(--token-layout-sidebar) - var(--token-space-16)));
  padding: var(--token-space-4);
}

.more-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--token-layout-field-basis), 1fr));
  gap: var(--token-space-4) var(--token-space-5);
  margin-bottom: var(--token-space-4);
}

.more-col {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-2);
  min-width: 0;
}

.more-col .sec-head {
  margin: 0;
}

.more-col .sec-head h2 {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-2xs);
  font-weight: var(--token-weight-regular);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.more-col .control {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-1);
}

.more-col .control .lbl,
.more-col .field .lbl {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.more-col .field {
  max-width: none;
  flex: none;
}

.more-col select {
  width: 100%;
}

.tr-page .scroller td a.file {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-secondary);
}

.tr-page td .sub.crit {
  color: var(--token-color-state-crit-text);
}

/* ---------------------------------------------------- experience overview */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--token-layout-stat-min), 1fr));
  gap: var(--token-space-4);
}

a.panel.kpi {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  padding: var(--token-space-4) var(--token-space-5);
  color: var(--token-color-text-primary);
  text-decoration: none;
}

a.panel.kpi > * + * {
  margin-top: 0;
}

a.panel.kpi:hover {
  border-color: var(--token-color-border-strong);
  text-decoration: none;
}

.kpi-label {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.kpi-n {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-h1);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
}

.attn-card table.fixed col[data-col="state"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.attn-card table.fixed col[data-col="count"],
.recent-card table.fixed col[data-col="record"] {
  width: calc(var(--token-space-24) + var(--token-space-16) + var(--token-space-2));
}

.recent-card table.fixed col[data-col="updated"] {
  width: calc(var(--token-space-24) + var(--token-space-24));
}

.tr-page td a.count {
  font-variant-numeric: tabular-nums;
}

.mini-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--token-layout-panel-min), 1fr));
  gap: var(--token-space-4);
}

.mini-card.panel {
  padding: var(--token-space-4) var(--token-space-5);
}

.card-cap {
  font-size: var(--token-fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

/* Label · bar · figure, the three columns shared by every row of the card. */
ul.bars {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: max-content minmax(var(--token-space-10), 1fr) max-content;
  align-items: center;
  gap: var(--token-space-3);
  font-size: var(--token-fs-xs-plus);
}

ul.bars > li {
  display: contents;
}

ul.bars > li > .grow {
  grid-column: 2;
}

ul.bars a {
  color: var(--token-color-text-primary);
}

ul.bars a.cl1 {
  max-width: calc(var(--token-layout-field-basis) * 0.8);
}

ul.bars a.count {
  justify-self: end;
  font-variant-numeric: tabular-nums;
  color: var(--token-color-accent-text);
}

ul.bars .meter {
  display: block;
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

ul.bars .meter > span {
  display: block;
  height: 100%;
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-fill);
}

/* ----------------------------------------------------- evidence library
   Документ · 180 · 130 · 210 · 130 · 110 · 54. */
.evidence-card table.fixed col[data-col="project"] {
  width: calc(var(--token-layout-card-min) - var(--token-space-16) - var(--token-space-1) - var(--token-space-1));
}

.evidence-card table.fixed col[data-col="date"],
.evidence-card table.fixed col[data-col="extraction"] {
  width: calc(var(--token-space-24) + var(--token-space-8) + var(--token-layout-hair-gap));
}

.evidence-card table.fixed col[data-col="restriction"] {
  width: calc(var(--token-layout-card-min) - var(--token-space-10));
}

.evidence-card table.fixed col[data-col="versions"] {
  width: calc(var(--token-space-24) + var(--token-space-4) - var(--token-layout-hair-gap));
}

.evidence-card table.fixed col[data-col="added"] {
  width: calc(var(--token-space-12) + var(--token-space-2) - var(--token-layout-hair-gap));
}

.tr-page .scroller td a.ib {
  color: var(--token-color-text-secondary);
}

.tr-page .scroller td a.ib:hover {
  text-decoration: none;
  border-color: var(--token-color-text-tertiary);
}

.ev-detail.panel {
  padding: var(--token-space-5) var(--token-space-6);
}

.ev-detail > .cap {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  letter-spacing: 0;
  text-transform: none;
  color: var(--token-color-text-primary);
}

.ev-detail .badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
}

.ev-detail h4 {
  margin-top: var(--token-space-5);
  font-size: var(--token-fs-2xs);
  font-weight: var(--token-weight-regular);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.ev-detail .kv {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--token-layout-field-basis), 1fr));
  gap: var(--token-space-3) var(--token-space-5);
}

.tr-page ul.plain {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  font-size: var(--token-fs-xs-plus);
}

/* ------------------------------------------------------- review queue
   Запис · 210 · 190 · 430. */
.queue-card table.fixed col[data-col="reasons"] {
  width: calc(var(--token-layout-card-min) - var(--token-space-10));
}

.queue-card table.fixed col[data-col="state"] {
  width: calc(var(--token-space-24) + var(--token-space-24) - var(--token-space-2) + var(--token-layout-hair-gap));
}

.queue-card table.fixed col[data-col="actions"] {
  width: var(--token-layout-aside);
}

.queue-card .scroller td {
  padding-block: var(--token-space-2);
}

.reasons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
}

.reasons a:hover {
  text-decoration: none;
}

.row-actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.tr-page td .sub a.notes-link {
  color: var(--token-color-accent-text);
}

.tr-page td .sub a {
  font-weight: var(--token-weight-regular);
}

/* --------------------------------------------------------- one lead
   The crumb, the title with its chips and the two verdicts, then the score
   and the notice on the left and the facts in a column on the right. */
.tr-page > .crumbs {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.tr-page > .detail-hero {
  align-items: flex-start;
}

.tr-page > .detail-hero h1 {
  font-size: var(--token-fs-h3);
  line-height: var(--token-lh-snug);
}

.tr-page > .detail-hero .lede.chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
  margin-top: var(--token-space-3);
  font-size: var(--token-fs-xs-plus);
}

.tr-page > .detail-hero .hero-action {
  gap: var(--token-space-2);
  padding-top: var(--token-space-1);
}

.tr-page > .detail-hero .hero-action form.inline {
  gap: var(--token-space-2);
}

.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--token-layout-aside);
  gap: var(--token-space-4);
  align-items: start;
}

.detail-main,
.detail-aside {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-4);
  min-width: 0;
}

.detail-card.panel {
  padding: var(--token-space-4) var(--token-space-5);
}

.detail-card.panel > * + * {
  margin-top: var(--token-space-2);
}

.detail-card .card-cap + .card-cap,
.detail-card .codes + .card-cap,
.detail-card .prose-sm + .card-cap {
  margin-top: var(--token-space-4);
}

.card-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.card-head .grow {
  flex: 1 1 auto;
}

.prose-sm {
  font-size: var(--token-fs-sm);
  line-height: var(--token-lh-relaxed);
  color: var(--token-color-text-secondary);
}

dl.facts {
  margin: 0;
}

dl.facts dt:not(:first-child) {
  margin-top: var(--token-space-3);
}

dl.facts dt {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

dl.facts dd {
  margin: var(--token-layout-hair-gap) 0 0;
  font-size: var(--token-fs-sm);
  overflow-wrap: break-word;
}

ul.codes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  font-size: var(--token-fs-xs-plus);
}

ul.codes .mono {
  margin-right: var(--token-space-2);
  font-size: var(--token-fs-xs);
}

.big-score {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-2xl);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
}

.big-score.s-ok {
  color: var(--token-color-state-ok-text);
}

.big-score span {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-md);
  color: var(--token-color-text-tertiary);
}

.breakdown {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.breakdown ul {
  margin: 0;
  padding-left: var(--token-space-4);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.breakdown li > span {
  margin-right: var(--token-space-2);
}

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

ul.file-list > li {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  min-height: var(--token-space-12);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

ul.file-list .file-name {
  flex: 1 1 auto;
  min-width: 0;
}

.tr-page ul.plain > li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
}

.stamp {
  font-size: var(--token-fs-xs);
  line-height: var(--token-lh-relaxed);
}

@media (max-width: 1100px) {
  .detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ------------------------------------------------ sources & scoring */
.set-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--token-layout-aside) + var(--token-space-10)), 1fr));
  gap: var(--token-space-4);
  align-items: stretch;
}

.set-stack {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-4);
}

.set-stack > .kit {
  justify-content: flex-end;
}

.set-card.panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: var(--token-space-5) var(--token-space-6);
}

.set-card.panel > * {
  margin: 0;
  max-width: 100%;
}

.set-card > .sec-head {
  margin: 0;
}

.set-card > .sec-head h2,
.set-card .sec-head h2 {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-lg);
  font-weight: var(--token-weight-regular);
}

.set-card .field {
  width: min(100%, var(--token-layout-field-max));
  flex: none;
}

.set-card .note {
  font-size: var(--token-fs-xs-plus);
  max-width: var(--token-measure-lede);
}

.set-card > .kit {
  margin-top: auto;
  padding-top: var(--token-space-2);
}

.set-card.set-wide > .scroller,
.set-card .scroller {
  width: 100%;
}

.set-activity {
  margin-top: var(--token-space-2);
}

.set-activity .seg {
  margin-left: var(--token-space-2);
}

/* The per-connector sync forms hold only a hidden field and are reached by
   `form=`; they take no room in the column. */
.tr-settings > form.inline:not(:has(:not(input[type='hidden']))) {
  display: none;
}

/* A keyword list: each term a chip that opens its rename form. */
.set-card ul:has(> li > details) {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.set-card ul > li > details > summary {
  display: inline-flex;
  align-items: center;
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-layout-pill-pad-x);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
  list-style: none;
  cursor: pointer;
}

.set-card ul > li > details > summary::-webkit-details-marker {
  display: none;
}

.set-card ul > li > details[open] {
  padding: var(--token-space-2);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

/* --------------------------------------------------- one project record */
.tr-project > .detail-hero h1 {
  font-size: var(--token-fs-h1);
}

.tr-project > .detail-hero .hero-action .dropdown .menu {
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.tr-project > .seg {
  align-self: flex-start;
  flex-wrap: wrap;
}

.tr-project .panel {
  padding: var(--token-space-4) var(--token-space-5);
}

.tr-project .panel > .cap {
  font-size: var(--token-fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.tr-project .panel dl:not(.kv) {
  display: grid;
  grid-template-columns: minmax(0, calc(var(--token-layout-field-basis) * 0.9)) minmax(0, 1fr);
  gap: var(--token-space-2) var(--token-space-4);
  margin: 0;
  font-size: var(--token-fs-sm);
}

.tr-project .panel dl:not(.kv) dt {
  color: var(--token-color-text-tertiary);
}

.tr-project .panel dl:not(.kv) dd {
  margin: 0;
}

/* ------------------------------------------------------------ the wizard
   The eleven steps as a rail on the left, the step's form in a card beside it. */
.wiz-grid {
  display: grid;
  grid-template-columns: calc(var(--token-layout-card-min) + var(--token-space-6)) minmax(0, 1fr);
  gap: var(--token-space-5);
  align-items: start;
}

ol.wiz-rail {
  list-style: none;
  margin: 0;
  padding: var(--token-space-2);
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-hair-gap);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  position: sticky;
  top: var(--token-space-6);
}

ol.wiz-rail > li > a,
ol.wiz-rail > li > span {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: var(--token-space-2);
  border-radius: var(--token-radius-sm);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs-plus);
  text-decoration: none;
}

ol.wiz-rail > li > a:hover {
  background: var(--token-color-surface-inset);
  text-decoration: none;
}

ol.wiz-rail > li > span:not([aria-current]) {
  color: var(--token-color-text-tertiary);
}

ol.wiz-rail > li > [aria-current='step'] {
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

ol.wiz-rail .n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--token-space-6);
  height: var(--token-space-6);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-xs);
  font-variant-numeric: tabular-nums;
}

ol.wiz-rail [aria-current='step'] .n {
  background: var(--token-color-accent-fill);
  color: var(--token-color-on-accent);
}

ol.wiz-rail .t {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-hair-gap);
  min-width: 0;
}

ol.wiz-rail .h {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tr-wizard .wiz-grid > form > .panel {
  padding: var(--token-space-5) var(--token-space-6);
}

.tr-wizard .wiz-grid > form > .kit {
  margin-top: var(--token-space-4);
}

@media (max-width: 900px) {
  .wiz-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  ol.wiz-rail {
    position: static;
  }
}

/* A deadline's distance stays on one line under its date, as the board's. */
.tr-page td .when + .sub {
  white-space: nowrap;
}


/* =====================================================================
   experience: record, wizard, card — and the four surfaces' tables
   (agent t-exp). Every rule below is scoped to `.tr-exp`, the class the
   Experience screens wrap their body in, and drawn from the «Досвід»
   board (ExperienceA) with the tender board's fact sheet (TenderOverviewA).
   ===================================================================== */

/* ---- the head: title and one line under it, the actions on the right ---- */
.tr-exp > .xp-head {
  align-items: flex-end;
}

.tr-exp > .xp-head .hero-text {
  flex: 1 1 auto;
  min-width: 0;
}

.tr-exp > .xp-head h1 {
  font-size: var(--token-fs-h1);
  line-height: 1.15;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tr-exp > .xp-head .xp-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5) var(--token-space-3);
  margin-top: calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.tr-exp > .xp-head .hero-action {
  flex: none;
  gap: var(--token-space-2);
  flex-wrap: wrap;
  justify-content: flex-end;
}

.tr-exp .xp-dot {
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-line > .xp-fact {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-3);
}

.tr-exp .xp-line > .xp-fact + .xp-fact::before {
  content: '·';
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-tone.t-ok { color: var(--token-color-state-ok-text); }
.tr-exp .xp-tone.t-info { color: var(--token-color-state-info-text); }
.tr-exp .xp-tone.t-warning { color: var(--token-color-state-warn-text); }
.tr-exp .xp-tone.t-critical { color: var(--token-color-state-crit-text); }
.tr-exp .xp-tone.t-neutral { color: var(--token-color-text-secondary); }

/* ---- the record's tab strip and the wizard's steps: the board's segmented
   control, one row that scrolls on its own rather than wrapping ---- */
.tr-exp > .xp-tabs,
.tr-exp > .xp-steps-nav {
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}

.tr-exp > .xp-tabs .seg,
.tr-exp > .xp-steps-nav .seg {
  flex-wrap: nowrap;
  max-width: none;
  padding: var(--token-layout-seg-inset);
  gap: var(--token-gap-hair);
  border-radius: var(--token-radius-seg);
}

.tr-exp > .xp-tabs .seg a,
.tr-exp .xp-steps > a,
.tr-exp .xp-steps > span {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  height: var(--token-layout-seg-item-h);
  padding: 0 var(--token-layout-seg-item-pad-x);
  flex: none;
  border-radius: var(--token-radius-seg-item);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  white-space: nowrap;
  text-decoration: none;
}

.tr-exp .xp-steps > span.is-off {
  color: var(--token-color-text-tertiary);
  cursor: not-allowed;
}

.tr-exp > .xp-tabs .seg a[aria-current='true'],
.tr-exp .xp-steps > a[aria-current='step'] {
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
  box-shadow: 0 var(--token-border-hair) var(--token-gap-hair) color-mix(in srgb, var(--token-color-text-primary) 8%, transparent);
}

.tr-exp .xp-steps .n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--token-space-4) + var(--token-gap-hair));
  height: calc(var(--token-space-4) + var(--token-gap-hair));
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-raised);
  font-style: normal;
  font-size: var(--token-fs-2xs);
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.tr-exp .xp-steps > a[aria-current='step'] .n {
  background: var(--token-color-accent-fill);
  color: var(--token-color-on-accent);
}

/* ---- the body under the head: blocks 18 apart ---- */
.tr-exp .xp-body {
  display: flex;
  flex-direction: column;
  gap: var(--token-layout-block-gap);
  min-width: 0;
}

.tr-exp .xp-body > * {
  margin: 0;
}

/* Two cards side by side, read together; one under the other when narrow or
   when one of the two has nothing to show. */
.tr-exp .xp-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: var(--token-space-5);
  align-items: start;
}

.tr-exp .xp-pair:has(> :only-child) {
  grid-template-columns: minmax(0, 1fr);
}

.tr-exp .xp-pair:empty {
  display: none;
}

/* ---- the card ---- */
.tr-exp .xp-card.panel {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) calc(var(--token-space-4) + var(--token-gap-hair));
  min-width: 0;
}

.tr-exp .xp-card.panel > * {
  margin: 0;
}

.tr-exp .xp-card-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  min-width: 0;
  padding-bottom: calc(var(--token-space-1) * 1.5);
}

.tr-exp .xp-card-head h2 {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: var(--token-lh-normal);
  letter-spacing: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tr-exp .xp-aside {
  flex: none;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
}

/* A card whose body is a table or a sheet: the head over a rule, the body to
   the card's edges — «Критерії оцінки» on the tender board. */
.tr-exp .xp-card.panel.xp-flush {
  gap: 0;
  padding: 0;
  overflow: hidden;
}

.tr-exp .xp-flush > .xp-card-head {
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tr-exp .xp-flush > .scroller {
  border: 0;
  border-radius: 0;
}

.tr-exp .xp-pad {
  padding: var(--token-space-3) var(--token-space-4);
}

.tr-exp .xp-pad-top {
  padding-bottom: 0;
}

.tr-exp .xp-muted {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-text {
  font-size: var(--token-fs-sm);
  line-height: var(--token-lh-relaxed);
  color: var(--token-color-text-secondary);
  overflow-wrap: break-word;
}

.tr-exp .xp-lead {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

.tr-exp .xp-lead + .xp-text {
  margin-top: var(--token-space-1);
}

.tr-exp .xp-sub {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-chips + .xp-sub {
  margin-top: var(--token-space-2);
}

.tr-exp .xp-foot-note {
  padding-top: calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* A numbered list — «D1 Legal and Regulatory Analysis…». */
.tr-exp .xp-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
}

.tr-exp .xp-list > li {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  min-width: 0;
}

.tr-exp .xp-list .grow {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: break-word;
}

.tr-exp .xp-list .dim {
  flex: none;
  font-variant-numeric: tabular-nums;
}

/* The chips of «Обов’язкові форми»: a hair box, 8 round, 13px. */
.tr-exp .xp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.tr-exp .chip {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  padding: calc(var(--token-space-1) * 1.5) calc(var(--token-space-2) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  line-height: var(--token-lh-snug);
}

/* ---- the fact sheet ---- */
.tr-exp .xp-sheet.panel {
  padding: 0;
  overflow: hidden;
}

/* The sheet's own edge swallows the last column's and row's rules. */
.tr-exp .xp-card.panel > .facts-grid {
  margin: 0 calc(var(--token-border-hair) * -1) calc(var(--token-border-hair) * -1) 0;
}

.tr-exp .facts-grid.xp-facts-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.tr-exp .fact {
  min-height: calc(var(--token-space-16) + var(--token-space-1));
}

.tr-exp .fact-v a {
  color: var(--token-color-accent-text);
}

.tr-exp .fact-s {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ---- the warning band: «2 розбіжності в документації — перевірте вручну» ---- */
.tr-exp .xp-warn.panel {
  padding: var(--token-space-4) var(--token-space-5);
  border-color: transparent;
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.tr-exp .xp-warn.panel > * {
  margin: 0;
}

.tr-exp .xp-warn.xp-neutral {
  background: var(--token-color-state-neutral-bg);
  color: var(--token-color-text-primary);
}

.tr-exp .xp-warn-title {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  font-weight: var(--token-weight-medium);
}

.tr-exp .xp-warn-title .ico {
  width: var(--token-space-4);
  height: var(--token-space-4);
  flex: none;
}

.tr-exp .xp-warn-list {
  list-style: none;
  margin: calc(var(--token-space-2) + var(--token-gap-hair)) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

.tr-exp .xp-warn-list > li {
  display: flex;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .xp-warn-text {
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

/* ---- the review row: where the record stands and the verbs on it ---- */
.tr-exp .xp-review-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  min-width: 0;
}

.tr-exp .xp-review-text {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-review-row .grow {
  flex: 1 1 auto;
}

.tr-exp .xp-actions,
.tr-exp .row-actions {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--token-space-2);
}

/* ---- buttons: the board's 36px, and its 30px «sm» for rows and menus ---- */
.tr-exp .btn,
.tr-exp a.btn,
.tr-exp summary.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--token-space-2);
  height: var(--token-layout-control-h);
  padding: 0 var(--token-layout-control-pad-x);
  font-size: var(--token-fs-sm);
  line-height: 1;
}

.tr-exp .btn.btn-sm,
.tr-exp summary.btn.btn-sm {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.tr-exp form.inline {
  display: inline-flex;
}

/* ---- a button that opens a small form under it ---- */
.tr-exp .xp-pop > .menu {
  width: min(calc(var(--token-layout-field-max) - var(--token-space-5)), calc(100vw - var(--token-space-8)));
  padding: var(--token-space-3);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  text-align: left;
}

.tr-exp .xp-pop > .menu form {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.tr-exp .xp-pop > .menu form > * {
  margin: 0;
}

.tr-exp .xp-pop .xp-pop-hint {
  font-size: var(--token-fs-xs-plus);
  line-height: var(--token-lh-normal);
  color: var(--token-color-text-secondary);
  white-space: normal;
}

.tr-exp .xp-pop .field > textarea {
  min-height: calc(var(--token-layout-control-h) * 2);
}

.tr-exp .xp-pop .kit {
  display: flex;
  justify-content: flex-end;
  margin: 0;
}

/* ---- review notes ---- */
.tr-exp .xp-notes {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tr-exp .xp-notes > li {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: calc(var(--token-space-2) + var(--token-gap-hair)) 0;
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tr-exp .xp-notes > li:first-child {
  padding-top: 0;
}

.tr-exp .xp-notes .grow {
  flex: 1 1 auto;
  min-width: 0;
}

.tr-exp .xp-notes > li.is-done .xp-note-text {
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-note-text {
  font-size: var(--token-fs-sm);
  overflow-wrap: break-word;
}

.tr-exp .xp-note-by {
  margin-top: var(--token-gap-hair);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-add {
  display: flex;
  gap: var(--token-space-2);
  margin-top: var(--token-space-1);
}

.tr-exp .xp-add > .field {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
}

/* ---- a bar over a body: the language switch and the review mark ---- */
.tr-exp .xp-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-3);
}

.tr-exp .xp-bar .grow {
  flex: 1 1 auto;
}

/* ---- forms: a card with its head, labelled fields two across, verbs at
   the foot under a rule ---- */
.tr-exp .xp-form.panel {
  gap: 0;
  padding: 0;
}

.tr-exp .xp-form > .xp-card-head {
  padding: var(--token-space-4) var(--token-space-5) 0;
}

.tr-exp .xp-form > .xp-card-head h2 {
  font-size: var(--token-fs-md);
}

.tr-exp .xp-card-lede {
  padding: 0 var(--token-space-5);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-card-lede + .xp-foot {
  margin-top: var(--token-space-4);
}

.tr-exp .xp-grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--token-space-4) var(--token-space-5);
  padding: var(--token-space-5);
}

.tr-exp .xp-grid-4 {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(calc(var(--token-layout-card-min) - var(--token-space-16) - var(--token-space-6)), 1fr));
  gap: var(--token-space-3);
}

.tr-exp .xp-field {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  min-width: 0;
}

.tr-exp .xp-field.is-wide {
  grid-column: 1 / -1;
}

.tr-exp .xp-field > .field,
.tr-exp .xp-grid-4 > .field {
  width: 100%;
  max-width: none;
  flex: none;
}

.tr-exp .xp-hint {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
  padding: var(--token-space-3) var(--token-space-5);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.tr-exp .xp-foot .grow {
  flex: 1 1 auto;
}

.tr-exp .xp-foot .note {
  color: var(--token-color-text-tertiary);
}

/* A short closed list as choice chips — radios drawn as the board's filter
   chips, the chosen one in the accent wash. No native list opens. */
.tr-exp fieldset.xp-choice {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.tr-exp fieldset.xp-choice > legend.lbl {
  margin-bottom: calc(var(--token-space-1) * 1.5);
  padding: 0;
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-opts {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--token-space-1) * 1.5);
}

.tr-exp .xp-opt {
  position: relative;
  display: inline-flex;
}

.tr-exp .xp-opt > input[type='radio'] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.tr-exp .xp-opt > span {
  display: inline-flex;
  align-items: center;
  height: var(--token-space-8);
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  white-space: nowrap;
}

.tr-exp .xp-opt:hover > span {
  border-color: var(--token-color-text-tertiary);
}

.tr-exp .xp-opt > input:checked + span {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.tr-exp .xp-opt > input:focus-visible + span {
  outline: var(--token-border-thick) solid var(--token-color-accent-fill);
  outline-offset: var(--token-border-hair);
}

/* ---- «Усі фільтри»: chip menus in a sheet, the typed ranges under them.
   The sheet hangs from the bar, not from its chip, so it never runs past the
   page's edge whatever the chip's position in a wrapped bar. ---- */
.tr-exp > .exp-bar {
  position: relative;
}

.tr-exp > .exp-bar > .more-filters {
  position: static;
}

.tr-exp .more-filters > .xp-sheet-menu {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  left: 0;
  right: auto;
  width: min(calc(var(--token-layout-aside) + var(--token-space-24) * 2 + var(--token-space-6)), 100%);
  padding: var(--token-space-4);
  z-index: 6;
}

.tr-exp .xp-more-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  margin-bottom: var(--token-space-1);
}

.tr-exp .xp-more-form {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  margin-top: var(--token-space-2);
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tr-exp .xp-more-form > * {
  margin: 0;
}

.tr-exp .xp-more-form .xp-foot {
  padding: 0;
  border-top: 0;
}

.tr-exp a.fchip.xp-toggle,
.tr-opp a.fchip.xp-toggle {
  display: inline-flex;
  align-items: center;
  height: var(--token-space-8);
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  text-decoration: none;
  white-space: nowrap;
}

.tr-exp a.fchip.xp-toggle[aria-pressed='true'],
.tr-opp a.fchip.xp-toggle[aria-pressed='true'] {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

/* ---- tables: the board's metrics — 12px heads, 13px rows, two lines in
   58, one line in 48, each line clipped rather than wrapped ---- */
.tr-exp .xp-card .scroller th,
.tr-exp .exp-card > .scroller th {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-layout-cell-pad-x);
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
  white-space: nowrap;
}

.tr-exp .xp-card .scroller td,
.tr-exp .exp-card > .scroller td {
  height: var(--token-space-12);
  padding: 0 var(--token-layout-cell-pad-x);
  font-size: var(--token-fs-xs-plus);
  vertical-align: middle;
}

.tr-exp .xp-card .scroller th:first-child,
.tr-exp .xp-card .scroller td:first-child,
.tr-exp .xp-card .scroller th:last-child,
.tr-exp .xp-card .scroller td:last-child {
  padding-inline: var(--token-layout-cell-pad-x);
}

.tr-exp .exp-card > .scroller td,
.tr-exp .evidence-card .scroller td,
.tr-exp .queue-card .scroller td,
.tr-exp .xp-history .scroller td {
  height: calc(var(--token-space-12) + var(--token-space-2) + var(--token-gap-hair));
  padding-block: 0;
}

.tr-exp .scroller td > .cl1:not(.file),
.tr-exp .scroller td .cv > .cl1:not(.file) {
  display: block;
  max-width: 100%;
}

.tr-exp .scroller td .sub {
  margin-top: var(--token-gap-hair);
  line-height: var(--token-lh-snug);
}

.tr-exp .scroller td .badge + .sub,
.tr-exp .scroller td span:has(> .badge) + .sub {
  margin-top: var(--token-space-1);
}

.tr-exp .scroller td .badge {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tr-exp .scroller td .row-title {
  display: block;
  color: var(--token-color-text-primary);
}

.tr-exp .scroller tr.sel > td {
  background: var(--token-color-accent-wash);
}

.tr-exp .scroller th a.sort {
  color: inherit;
  text-decoration: none;
}

.tr-exp .scroller th a.sort:hover {
  color: var(--token-color-text-primary);
}

.tr-exp .exp-card td:last-child {
  text-align: right;
}

.tr-exp .row-menu > .menu {
  min-width: calc(var(--token-layout-card-min) + var(--token-space-2));
  text-align: left;
}

.tr-exp .row-menu .xp-menu-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-2);
  padding: var(--token-space-2) var(--token-space-3) var(--token-space-2);
}

.tr-exp .row-menu .xp-menu-form > .field,
.tr-exp .xp-pop > .menu form > .field {
  width: 100%;
  max-width: none;
  flex: none;
}

/* The library: document · 200 · 120 · 170 · 130 · 90. */
.tr-exp .evidence-card table.fixed col[data-col="project"] {
  width: calc(var(--token-space-24) * 2 + var(--token-space-2));
}

.tr-exp .evidence-card table.fixed col[data-col="date"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.tr-exp .evidence-card table.fixed col[data-col="restriction"] {
  width: calc(var(--token-space-24) + var(--token-space-16) + var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .evidence-card table.fixed col[data-col="extraction"] {
  width: calc(var(--token-space-24) + var(--token-space-8) + var(--token-gap-hair));
}

.tr-exp .evidence-card table.fixed col[data-col="versions"] {
  width: calc(var(--token-space-24) - var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .evidence-card table.fixed col[data-col="added"] {
  width: auto;
}

/* One project's documents: no project column — 120 · 170 · 130 · 90. */
.tr-exp .xp-evidence table.fixed col[data-col="date"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.tr-exp .xp-evidence table.fixed col[data-col="restriction"] {
  width: calc(var(--token-space-24) + var(--token-space-16) + var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .xp-evidence table.fixed col[data-col="extraction"] {
  width: calc(var(--token-space-24) + var(--token-space-8) + var(--token-gap-hair));
}

.tr-exp .xp-evidence table.fixed col[data-col="versions"] {
  width: calc(var(--token-space-24) - var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .evidence-card td.num .sub {
  text-align: right;
}

/* The queue: record · 230 · 170 · 376. */
.tr-exp .queue-card table.fixed col[data-col="reasons"] {
  width: calc(var(--token-layout-card-min) - var(--token-space-5));
}

.tr-exp .queue-card table.fixed col[data-col="state"] {
  width: calc(var(--token-space-24) + var(--token-space-16) + var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .queue-card table.fixed col[data-col="actions"] {
  width: calc(var(--token-space-24) * 3 + var(--token-space-24) - var(--token-space-2));
}

.tr-exp .queue-card .reasons {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-1);
  min-width: 0;
}

.tr-exp .queue-card .reason-line {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  max-width: 100%;
  min-width: 0;
}

.tr-exp .queue-card .reason-line > a {
  min-width: 0;
  max-width: 100%;
}

.tr-exp .queue-card .reason-line > a:hover {
  text-decoration: none;
}

.tr-exp .queue-card .row-actions {
  flex-wrap: wrap;
}

/* The record's eleven tabs fit one row at the board's width with a notch
   less padding per item. */
.tr-exp > .xp-tabs .seg a {
  padding: 0 calc(var(--token-space-2) + var(--token-gap-hair));
}

/* A document's versions: file · 170 · 120 · 110. */
.tr-exp .xp-versions table.fixed col[data-col="uploaded"] {
  width: calc(var(--token-space-24) + var(--token-space-16) + var(--token-space-2) + var(--token-gap-hair));
}

.tr-exp .xp-versions table.fixed col[data-col="extraction"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.tr-exp .xp-versions table.fixed col[data-col="actions"] {
  width: calc(var(--token-space-24) + var(--token-space-3) + var(--token-gap-hair));
}

.tr-exp .xp-versions td.num {
  white-space: nowrap;
}

.tr-exp .xp-versions td.num .ib {
  margin-left: var(--token-space-2);
  vertical-align: middle;
}

/* History: when · what · who. */
.tr-exp .xp-history table.fixed col[data-col="when"] {
  width: calc(var(--token-space-24) + var(--token-space-16) + var(--token-space-2));
}

.tr-exp .xp-history table.fixed col[data-col="who"] {
  width: calc(var(--token-layout-card-min) - var(--token-space-8));
}

/* The overview's cards: the board's card head instead of an uppercase cap. */
.tr-exp .mini-card.xp-card {
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) calc(var(--token-space-4) + var(--token-gap-hair));
}

.tr-exp .ev-detail .xp-badges {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--token-space-1) * 1.5);
}

.tr-exp .ev-detail .facts-grid {
  margin-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tr-exp .ev-detail {
  scroll-margin-top: var(--token-space-6);
}

/* A row's menu and a row's small forms open over the rows below and past the
   card's foot: the card lets them out rather than clipping them. At table
   width only — a stacked table is a list and has nothing to scroll. */
@media (min-width: 901px) {
  .tr-exp .exp-card.panel,
  .tr-exp .exp-card > .scroller,
  .tr-exp .queue-card.panel,
  .tr-exp .queue-card > .scroller {
    overflow: visible;
  }
}

/* ---- narrow: the pair and the form's two columns fold, the head wraps,
   tables stack (the kit's `stack`) ---- */
@media (max-width: 1100px) {
  .tr-exp .xp-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  .tr-exp > .xp-head {
    flex-wrap: wrap;
    align-items: flex-start;
  }

  .tr-exp > .xp-head .hero-action {
    flex: 1 1 100%;
    min-width: 0;
    justify-content: flex-start;
  }

  .tr-exp > .xp-head h1 {
    white-space: normal;
  }

  .tr-exp .xp-grid-2 {
    grid-template-columns: minmax(0, 1fr);
  }

  .tr-exp .facts-grid.xp-facts-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* A stacked row is a card of label · value lines, not 58px cells. */
  .tr-exp .scroller.stack td,
  .tr-exp .xp-card .scroller.stack td,
  .tr-exp .exp-card > .scroller.stack td,
  .tr-exp .found-card .scroller.stack td {
    height: auto;
    min-height: 0;
    padding: var(--token-space-1) var(--token-space-4);
  }

  .tr-exp .scroller.stack td > .cv > .cl1,
  .tr-exp .scroller.stack td > .cv > .sub {
    display: block;
  }

  .tr-exp .scroller.stack td:empty,
  .tr-exp .scroller.stack td:has(> .cv:empty) {
    display: none;
  }

  .tr-exp .queue-card .reasons {
    align-items: flex-end;
  }

  .tr-exp .queue-card .row-actions,
  .tr-exp .xp-review-row .xp-actions {
    flex-wrap: wrap;
  }
}

/* restore F: the queue's filters in force, each with its own «×», after
   «Фільтри N»; the status menu's line about records the rules set aside; a
   decided row's «Повернути в чергу» under its two squares. */
.opp-active {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.opp-achip {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-space-1) 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  white-space: nowrap;
}

.opp-achip b {
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-primary);
}

.opp-achip a {
  padding: 0 var(--token-space-1);
  color: var(--token-color-text-tertiary);
  text-decoration: none;
}

.opp-achip a:hover {
  color: var(--token-color-text-primary);
}

.fchip-menu .menu .menu-note {
  margin: 0;
  padding: var(--token-space-2) var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
  white-space: normal;
}

.tr-opp td form.inline:has(> .opp-requeue) {
  flex-wrap: wrap;
}

.tr-opp .opp-requeue {
  flex-basis: 100%;
  text-align: left;
  font-size: var(--token-fs-xs);
}

/* restore G: «Досвід» — the filters in force as chips with «×», the way back
   from a project, the rest of a queue row's reasons, and the library's
   «Додано» column. */
.tr-exp .xp-active {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.tr-exp .xp-active > ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tr-exp .xp-active li {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  padding: var(--token-space-1) var(--token-space-2);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-active li > a {
  color: var(--token-color-text-tertiary);
  text-decoration: none;
}

.tr-exp .xp-active li > a:hover {
  color: var(--token-color-text-primary);
}

.tr-exp > .xp-back {
  font-size: var(--token-fs-xs-plus);
}

.tr-exp .queue-card .reason-rest > summary {
  list-style: none;
  cursor: pointer;
}

.tr-exp .queue-card .reason-rest > summary::-webkit-details-marker {
  display: none;
}

.tr-exp .queue-card .reason-rest[open] > summary {
  margin-bottom: var(--token-space-1);
}

.tr-exp .evidence-card table.fixed col[data-col="added"] {
  width: calc(var(--token-space-24) + var(--token-space-2));
}

.tr-exp .evidence-card table.fixed col[data-col="download"] {
  width: auto;
}

.tr-exp .xp-evidence table.fixed col[data-col="added"] {
  width: calc(var(--token-space-24) + var(--token-space-2));
}

/* One project's documents: the download as wide as the date added beside it.
   By position it got this width from the library's seventh-column rule; by name
   it says so. */
.tr-exp .xp-evidence table.fixed col[data-col="download"] {
  width: calc(var(--token-space-24) + var(--token-space-2));
}

/*
 * One project's agreements: contract · dates · signed · value. An addendum
 * sits under its contract, stepped in, as theirs nests it; the type, status
 * and disclosure badges run under the name.
 */
.tr-exp .xp-agreements .xp-badges {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--token-space-1) * 1.5);
  margin-top: var(--token-space-1);
}

.tr-exp .xp-agreements tr.xp-addendum > td:first-child {
  padding-left: calc(var(--token-space-4) + var(--token-space-6));
}

.tr-exp .xp-agreements table.fixed col[data-col="dates"],
.tr-exp .xp-agreements table.fixed col[data-col="value"] {
  width: calc(var(--token-space-24) + var(--token-space-16));
}

/*
 * The section editors (`experience-editors.ts` in @tenders/web): every list of
 * a record's tab and of the wizard's steps 2–9 as rows — name and badges, a
 * line of facts, the body, and «Змінити / Видалити» at the row's end. A row
 * never pushes the page sideways: text wraps anywhere, the actions wrap under
 * each other before they squeeze the name.
 */
.tr-exp .xp-edit-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.tr-exp .xp-edit-row {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  min-width: 0;
  padding: var(--token-space-3) 0;
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tr-exp .xp-edit-row:first-child {
  border-top: 0;
  padding-top: 0;
}

.tr-exp .xp-edit-row > .grow {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
}

.tr-exp .xp-edit-row.row-dim > .grow {
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-edit-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
  min-width: 0;
  font-size: var(--token-fs-sm);
  overflow-wrap: break-word;
}

.tr-exp .xp-edit-title .xp-badges {
  display: inline-flex;
  flex-wrap: wrap;
  gap: calc(var(--token-space-1) * 1.5);
}

.tr-exp .xp-edit-facts {
  margin: 0;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  overflow-wrap: anywhere;
}

.tr-exp .xp-edit-row .xp-text,
.tr-exp .xp-edit-row .xp-muted {
  margin: 0;
  overflow-wrap: anywhere;
}

.tr-exp .xp-edit-actions {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--token-space-1);
  max-width: 50%;
}

.tr-exp .xp-quote {
  margin: 0;
  padding-left: var(--token-space-3);
  border-left: var(--token-border-thick) solid var(--token-color-border-strong);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  overflow-wrap: break-word;
}

/* The editor's form: a sheet under its button, as wide as two field columns,
   scrolling inside itself rather than running off the page. */
.tr-exp .xp-editor > .menu.xp-editor-sheet {
  width: min(calc(var(--token-layout-field-max) * 2 + var(--token-space-16)), calc(100vw - var(--token-space-8)));
  max-height: calc(var(--token-layout-aside) * 1.6);
  overflow-y: auto;
  padding: 0;
  z-index: 7;
  /* The card head's aside it hangs from keeps its words on one line; a
     form's hints and labels wrap to the sheet. */
  white-space: normal;
}

.tr-exp .xp-editor-sheet > form.xp-form {
  gap: 0;
}

.tr-exp .xp-editor-sheet .xp-card-head {
  padding: var(--token-space-4) var(--token-space-5) 0;
}

.tr-exp .xp-editor-sheet .xp-card-head h2 {
  margin: 0;
  font-size: var(--token-fs-md);
  white-space: normal;
}

.tr-exp fieldset.xp-subform,
.tr-exp fieldset.xp-day,
.tr-exp fieldset.xp-checks {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.tr-exp fieldset.xp-subform > legend.lbl,
.tr-exp fieldset.xp-day > legend.lbl {
  margin-bottom: calc(var(--token-space-1) * 1.5);
  padding: 0;
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
}

.tr-exp fieldset.xp-subform > .xp-grid-2 {
  padding: 0;
}

/* Many-of-a-list as the same chips as a choice, ticked rather than chosen. */
.tr-exp .xp-opt > input[type='checkbox'] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.tr-exp .xp-checks .xp-opt {
  max-width: 100%;
  min-width: 0;
}

/* A ticked name may be a long document title: it wraps inside its chip
   rather than pushing the page sideways. */
.tr-exp .xp-checks .xp-opt > span {
  height: auto;
  min-height: var(--token-space-8);
  padding-top: var(--token-space-1);
  padding-bottom: var(--token-space-1);
  white-space: normal;
  overflow-wrap: break-word;
}

/* «Експорт»: JSON, the card, the evidence package. */
.tr-exp .xp-export > .menu {
  min-width: calc(var(--token-layout-field-max) * 0.75);
}

.tr-exp .xp-export > .menu .menu-group {
  display: flex;
  flex-direction: column;
}

.tr-exp .xp-export > .menu a {
  padding: var(--token-space-2) var(--token-space-3);
  border-radius: var(--token-radius-sm);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  text-decoration: none;
}

.tr-exp .xp-export > .menu a:hover {
  background: var(--token-color-surface-sunken);
}

/* A dictionary picker inside an editor's field: the label over it and the
   select as wide as its column, like every text field beside it. */
.tr-exp .xp-field > .control {
  display: flex;
  align-items: stretch;
  width: 100%;
}

.tr-exp .xp-field > .control > select {
  width: 100%;
  min-width: 0;
}

/* A day as day · month · year on one line: the month takes what is left. */
.tr-exp fieldset.xp-day .tt-date-row {
  flex-wrap: nowrap;
  align-items: stretch;
}

.tr-exp fieldset.xp-day .tt-date-row > .field {
  flex: 0 0 calc(var(--token-space-16) + var(--token-space-6));
  min-width: 0;
  max-width: none;
}

.tr-exp fieldset.xp-day .tt-date-row > .field:last-child {
  flex-basis: calc(var(--token-space-16) + var(--token-space-10));
}

.tr-exp fieldset.xp-day .tt-date-row > .control {
  flex: 1 1 auto;
  min-width: 0;
  align-items: stretch;
}

.tr-exp fieldset.xp-day .tt-date-row > .control > select {
  width: 100%;
  height: 100%;
}

@media (max-width: 1100px) {
  /*
   * Where a sheet hung from its button could run off the page's left edge,
   * the editor opens IN PLACE instead: the form under its button, as wide as
   * the row or the card head it belongs to. The button stays where it was, so
   * the same press closes it again.
   */
  .tr-exp details.xp-editor > .menu.xp-editor-sheet {
    position: static;
    width: auto;
    max-height: none;
    margin-top: var(--token-space-2);
    box-shadow: none;
  }

  .tr-exp details.xp-editor[open] {
    flex: 1 1 100%;
    width: 100%;
  }

  .tr-exp .xp-edit-row:has(details.xp-editor[open]) {
    flex-wrap: wrap;
  }

  .tr-exp .xp-edit-actions:has(> details.xp-editor[open]) {
    flex: 1 1 100%;
    max-width: none;
  }

  .tr-exp .xp-card-head:has(details.xp-editor[open]) {
    flex-wrap: wrap;
  }

  .tr-exp .xp-card-head .xp-aside:has(details.xp-editor[open]) {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--token-space-2);
  }
}

@media (max-width: 900px) {
  /* A row whose actions no longer fit beside it puts them under it — still
     at the row's end. */
  .tr-exp .xp-edit-row {
    flex-wrap: wrap;
  }

  .tr-exp .xp-edit-actions {
    flex: 1 1 100%;
    max-width: none;
  }
}

/* An opened document's head carries its name AND its verbs (download, change,
   new version, archive, the project link): the verbs wrap under the name
   rather than squeezing it to nothing or running past the card. */
.tr-exp .ev-detail > .xp-card-head {
  flex-wrap: wrap;
}

.tr-exp .ev-detail > .xp-card-head > h2 {
  flex: 1 1 calc(var(--token-layout-field-max) * 0.75);
}

.tr-exp .ev-detail > .xp-card-head > .xp-aside {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--token-space-2);
  min-width: 0;
  max-width: 100%;
}

/* ------------------------------------------------ the registry's columns
   The original's twelve columns, «Оновлено» and the row's menu
   (`ProjectRegistry.tsx:727-742`). Every value wraps in its own column —
   badges too — rather than being cut: a column is there to be read.

   From 1601px it is a table: the project takes the rest, the others the
   widths below. Under that the fourteen columns do not fit beside the side
   navigation, and each row becomes a record — the name across the top, the
   other values as labelled cells in a grid under it — so nothing is cut and
   nothing scrolls sideways. The sort order, which lived in the hidden head,
   is then the bar above the rows. */
.tr-exp .exp-card > .scroller th,
.tr-exp .exp-card > .scroller td {
  padding-inline: var(--token-space-2);
}

.tr-exp .exp-card > .scroller th {
  white-space: normal;
  vertical-align: bottom;
}

.tr-exp .exp-card > .scroller td {
  height: auto;
  padding-block: var(--token-space-3);
  font-size: var(--token-fs-xs);
  vertical-align: top;
  overflow-wrap: break-word;
}

.tr-exp .exp-card > .scroller td .badge {
  max-width: 100%;
  overflow: visible;
  white-space: normal;
  text-overflow: clip;
  padding-block: var(--token-gap-hair);
}

.tr-exp .exp-card > .scroller td .xp-name {
  display: block;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-primary);
}

.tr-exp .exp-card > .scroller td .sub,
.tr-exp .exp-card > .scroller td .when + .sub {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* A badge's two lines, read as two lines. */
.tr-exp .exp-card > .scroller td .badge {
  height: auto;
  line-height: var(--token-lh-snug);
}

/* A figure is not broken inside itself; its currency may go under it. */
.tr-exp .exp-card > .scroller td .xp-money {
  white-space: nowrap;
}

/* the rest · 124 · 84 · 112 · 112 · 116 · 76 · 80 · 112 · 108 · 120 · 120 · 112 · 48 */
.tr-exp .exp-card table.fixed col[data-col="customer"] {
  width: calc(var(--token-space-24) + var(--token-space-6) + var(--token-space-1));
}

.tr-exp .exp-card table.fixed col[data-col="country"] {
  width: calc(var(--token-space-16) + var(--token-space-5));
}

.tr-exp .exp-card table.fixed col[data-col="domains"],
.tr-exp .exp-card table.fixed col[data-col="services"],
.tr-exp .exp-card table.fixed col[data-col="value"],
.tr-exp .exp-card table.fixed col[data-col="updated"] {
  width: calc(var(--token-space-24) + var(--token-space-4));
}

.tr-exp .exp-card table.fixed col[data-col="delivery"] {
  width: calc(var(--token-space-24) + var(--token-space-5));
}

.tr-exp .exp-card table.fixed col[data-col="start"] {
  width: calc(var(--token-space-16) + var(--token-space-3));
}

.tr-exp .exp-card table.fixed col[data-col="completed"] {
  width: calc(var(--token-space-16) + var(--token-space-4));
}

.tr-exp .exp-card table.fixed col[data-col="role"] {
  width: calc(var(--token-space-24) + var(--token-space-3));
}

.tr-exp .exp-card table.fixed col[data-col="record"],
.tr-exp .exp-card table.fixed col[data-col="evidence"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.tr-exp .exp-card table.fixed col[data-col="actions"] {
  width: var(--token-space-12);
}

.tr-exp .exp-card .xp-sortbar {
  display: none;
}

/* Rows as cards up to 2000px: fourteen columns at 1920 left the customer
   124px and the services 112px, «EDGE | Фонд експертної підтримки» six lines
   tall. The table is for the screens that have room for it. */
@media (max-width: 2000px) {
  .tr-exp .exp-card .xp-sortbar {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--token-space-1) var(--token-space-4);
    padding: var(--token-space-3) var(--token-space-4);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }

  .tr-exp .exp-card .xp-sortbar a {
    color: var(--token-color-text-secondary);
  }

  .tr-exp .exp-card .xp-sortbar a[aria-current='true'] {
    color: var(--token-color-accent-text);
  }

  .tr-exp .exp-card > .scroller.stack table,
  .tr-exp .exp-card > .scroller.stack tbody {
    display: block;
    width: 100%;
  }

  .tr-exp .exp-card > .scroller.stack colgroup {
    display: none;
  }

  .tr-exp .exp-card > .scroller.stack thead {
    position: absolute;
    width: var(--token-size-hidden);
    height: var(--token-size-hidden);
    overflow: hidden;
    clip-path: inset(50%);
  }

  .tr-exp .exp-card > .scroller.stack tr {
    position: relative;
    display: grid;
    /* As many fields a row as fit at 150px each, by the card's own width:
       a count per window width left three 90px fields at 820px with the side
       panel open, a customer's name six lines tall. */
    grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--token-layout-panel-min) * 0.6), 100%), 1fr));
    gap: var(--token-space-2) var(--token-space-4);
    padding: var(--token-space-3) var(--token-space-4);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tr-exp .exp-card > .scroller.stack td {
    display: block;
    width: auto;
    height: auto;
    min-height: 0;
    padding: 0;
    border: 0;
  }

  .tr-exp .exp-card > .scroller.stack td[data-label]::before {
    content: attr(data-label);
    display: block;
    max-width: none;
    margin-bottom: var(--token-gap-hair);
    font-family: var(--token-font-body);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }

  .tr-exp .exp-card > .scroller.stack td > .cv {
    text-align: left;
  }

  /* The project across the top, its menu at the row's corner. */
  .tr-exp .exp-card > .scroller.stack td:first-child {
    grid-column: 1 / -1;
    padding-right: var(--token-space-10);
  }

  .tr-exp .exp-card > .scroller.stack td:first-child::before {
    display: none;
  }

  .tr-exp .exp-card > .scroller.stack td:last-child {
    position: absolute;
    top: var(--token-space-2);
    right: var(--token-space-2);
  }

  .tr-exp .exp-card > .scroller.stack td:last-child::before {
    display: none;
  }
}

/* ======================================================================
   Experience — the original's glyphs, states and guards (wave 2, slice D)
   ====================================================================== */

/* The search box with its Search glyph inside, as the original's. */
.tr-exp .xp-search {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
}

.tr-exp .xp-search > .ic {
  position: absolute;
  left: var(--token-layout-control-pad-x);
  color: var(--token-color-text-tertiary);
  pointer-events: none;
}

.tr-exp .xp-search input {
  width: 100%;
  padding-left: calc(var(--token-layout-control-pad-x) * 2 + var(--token-size-icon-sm));
}

.tr-exp .xp-search-form {
  flex: 1 1 var(--token-layout-search);
  min-width: 0;
  max-width: var(--token-layout-search);
}

/* «Фільтри» and «Очистити» carry their glyphs. */
.tr-exp .fchip .ic,
.tr-exp .bar-clear .ic {
  vertical-align: middle;
  margin-right: var(--token-space-1);
}

.tr-exp .bar-clear {
  display: inline-flex;
  align-items: center;
}

/* The filter sheet's own title and line. */
.tr-exp .xp-sheet-head {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  padding-bottom: var(--token-space-2);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tr-exp .xp-sheet-title {
  margin: 0;
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

/* A mark with its word in the hover: the critical gap, the change after verification. */
.tr-exp .xp-flag {
  display: inline-flex;
  vertical-align: middle;
  margin-left: var(--token-space-1);
  line-height: 0;
}

.tr-exp .xp-flag.crit {
  color: var(--token-color-state-crit-text);
}

.tr-exp .xp-flag.warn {
  color: var(--token-color-state-warn-text);
}

/* The confidentiality chip under the record's state. */
.tr-exp .xp-sub-badge {
  display: block;
  margin-top: var(--token-space-1);
}

/* A row of chips that wraps inside its cell rather than widening it. */
.tr-exp td .xp-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
}

/* The row menu's items: glyph, then word. */
.tr-exp .row-menu .menu a,
.tr-exp .row-menu .menu .btn {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.tr-exp .row-menu .menu .btn.xp-danger {
  color: var(--token-color-state-crit-text);
}

/* Pager links: the chevron beside the word. */
.tr-exp .card-foot a[rel] {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

/* The dashboard: the KPI's glyph at its label's end, the attention row's chevron. */
.tr-exp .kpi-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--token-space-2);
}

.tr-exp .kpi-icon {
  color: var(--token-color-text-tertiary);
  line-height: 0;
}

.tr-exp td a.count {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

.tr-exp .found-head h2 {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

.tr-exp .found-head h2 .ic {
  color: var(--token-color-state-warn-text);
}

/* The empty registry: its New project at the card's end. */
.intro-act {
  flex: none;
}

/* The empty states' glyphs in the tone they state. */
.tr-exp .empty-icon.ok {
  color: var(--token-color-state-ok-text);
}

.tr-exp .empty-icon.crit {
  color: var(--token-color-state-crit-text);
}

.tr-exp .xp-load-failed .empty .btn {
  margin-top: var(--token-space-2);
}

/* The evidence detail's «Відкрити докази проєкту» with its ExternalLink. */
.tr-exp .xp-ext {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

.tr-exp .xp-versions .row-title .ic {
  vertical-align: middle;
  margin-right: var(--token-space-1);
  color: var(--token-color-text-tertiary);
}

/* The queue's notes link and transition buttons with their glyphs. */
.tr-exp .notes-link {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

/* ---- the wizard ---- */

/* «Крок 3 з 11: …» and its bar. */
.tr-exp .xp-progress {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.tr-exp .xp-progress-text {
  margin: 0;
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
}

.tr-exp .xp-progress .meter {
  width: 100%;
}

/* The rail: each step's title with its hint under it. */
.tr-exp .xp-steps > a,
.tr-exp .xp-steps > span {
  height: auto;
  min-height: var(--token-layout-seg-item-h);
  padding-top: var(--token-space-1);
  padding-bottom: var(--token-space-1);
}

.tr-exp .xp-step-text {
  display: flex;
  flex-direction: column;
  line-height: var(--token-lh-tight);
}

.tr-exp .xp-step-hint {
  font-size: var(--token-fs-2xs);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-steps .n.is-done {
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

/* A field's own refusal, under it. */
.tr-exp .xp-error {
  display: flex;
  align-items: center;
  gap: var(--token-space-1);
  margin: var(--token-space-1) 0 0;
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-state-crit-text);
}

.tr-exp .xp-field.is-invalid input,
.tr-exp .xp-field.is-invalid textarea,
.tr-exp .xp-field.is-invalid select,
.tr-exp .xp-field.is-invalid .xp-picker-trigger {
  border-color: var(--token-color-state-crit-text);
}

/* The searchable pickers: a trigger like a field, a list that scrolls. */
.tr-exp .xp-picker {
  position: relative;
  width: 100%;
}

.tr-exp .xp-picker-trigger {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  min-height: var(--token-layout-control-h);
  padding: 0 var(--token-layout-control-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface);
  cursor: pointer;
  list-style: none;
}

.tr-exp .xp-picker-trigger::-webkit-details-marker {
  display: none;
}

.tr-exp .xp-picker-value {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tr-exp .xp-picker-value.is-empty {
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-picker-menu {
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.tr-exp .xp-picker-list {
  display: flex;
  flex-direction: column;
  max-height: calc(var(--token-layout-row-h) * 8);
  overflow-y: auto;
}

.tr-exp .xp-picker-list .xp-opt[hidden] {
  display: none;
}

/* The unsaved-changes guard. */
.xp-dialog {
  width: min(100% - var(--token-space-8), var(--token-layout-field-max));
  padding: var(--token-space-6);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  color: var(--token-color-text-primary);
}

.xp-dialog::backdrop {
  background: color-mix(in srgb, var(--token-color-text-primary) 40%, transparent);
}

.xp-dialog h2 {
  margin: 0 0 var(--token-space-2);
  font-size: var(--token-fs-md);
}

.xp-dialog p {
  margin: 0 0 var(--token-space-4);
  color: var(--token-color-text-secondary);
}

.xp-dialog .kit {
  justify-content: flex-end;
}

.tr-exp .xp-back {
  margin: 0;
}

/* The queue's three states stacked, each wrapping inside its column rather
   than being cut; the verbs wrap under each other when their glyphs make
   them wider than the column. */
.tr-exp .queue-card .xp-badges {
  flex-direction: column;
  align-items: flex-start;
  padding-block: var(--token-space-2);
}

.tr-exp .queue-card .xp-badges .badge {
  max-width: 100%;
  white-space: normal;
}

.tr-exp .queue-card .row-actions {
  flex-wrap: wrap;
  padding-block: var(--token-space-2);
}

/* A chip in a registry cell wraps its words inside the column instead of
   running into the next one — «Суворо конфіденційний», «Придатно з обмеженнями». */
.tr-exp .exp-card td .badge {
  max-width: 100%;
  white-space: normal;
}

.tr-exp fieldset.xp-picker-field {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.tr-exp fieldset.xp-picker-field > legend.lbl {
  margin-bottom: calc(var(--token-space-1) * 1.5);
  padding: 0;
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-picker-trigger {
  background: var(--token-color-surface-raised);
}

.tr-exp .xp-picker-list .xp-opt {
  width: 100%;
}

.tr-exp .xp-picker-menu > .xp-search {
  flex: none;
}

.tr-exp .xp-picker-menu > .xp-search input {
  height: var(--token-layout-control-h);
  min-height: 0;
}

.tr-exp .xp-picker-list {
  gap: var(--token-space-1);
  align-items: flex-start;
}

/* The evidence library's sort bar: only where its rows stack and the column
   heads are hidden, as the registry's. */
.tr-exp .evidence-card > .xp-sortbar {
  display: none;
}

@media (max-width: 900px) {
  .tr-exp .evidence-card > .xp-sortbar {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--token-space-1) var(--token-space-4);
    padding: var(--token-space-3) var(--token-space-4);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }

  .tr-exp .evidence-card > .xp-sortbar a {
    display: inline-flex;
    align-items: center;
    gap: var(--token-space-1);
    color: var(--token-color-text-secondary);
  }

  .tr-exp .evidence-card > .xp-sortbar a[aria-current='true'] {
    color: var(--token-color-accent-text);
  }
}

/* The stacked rows above, by the table's own width too (see `.scroller.stack`
   in app.css): a narrow card in a wide window is cards as well. */
@container (max-width: 860px) {
  /* A stacked row is a card of label · value lines, not 58px cells. */
  .tr-exp .scroller.stack td,
  .tr-exp .xp-card .scroller.stack td,
  .tr-exp .exp-card > .scroller.stack td,
  .tr-exp .found-card .scroller.stack td {
    height: auto;
    min-height: 0;
    padding: var(--token-space-1) var(--token-space-4);
  }

  .tr-exp .scroller.stack td > .cv > .cl1,
  .tr-exp .scroller.stack td > .cv > .sub {
    display: block;
  }

  .tr-exp .scroller.stack td:empty,
  .tr-exp .scroller.stack td:has(> .cv:empty) {
    display: none;
  }
}

/* Screen-shaped rules for the tenders-opps screens, matched to the approved canvas.
   Tokens only; one file per group so parallel work does not collide.

   The group has no boards of its own; each screen is drawn from its named
   reference board, element for element:

   - `.od`  Opportunities → Огляд: the OpportunitiesA head, CoverageA's KPI
            tiles, TendersDashA's cards, and the OpportunitiesA table;
   - `.ol`  one lead: the OpportunitiesA frame, TenderOverviewA's head row,
            fact sheet and cards;
   - `.os`  Opportunities → Джерела й оцінка: the OpportunitiesA head,
            FormatsA's fields, radios and drawer, cards with 14px heads;
   - `.st`  Налаштування (ШІ, Словники): the AdminA page — head, bar, table
            in a card, the «···» row menu, and FormatsA's drawer for a form.

   Values the token set has no name for are composed from the nearest tokens
   with calc(), and each is marked where it happens. */

/* ============================================================ shared parts */

/* A card, as every board draws one: raised, a hairline, 12 round. */
.oc {
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  padding: 0;
  min-width: 0;
}

.oc > * {
  margin: 0;
}

/* A card's head row (CoverageA, TenderOverviewA): 14 × 16, the name in the
   body face at medium, a quiet note beside it, the card's link at the end. */
.oc-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  min-width: 0;
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.oc-head h2,
.oc h2 {
  margin: 0;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  letter-spacing: 0;
}

.oc-head .note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.oc-head .grow {
  flex: 1 1 auto;
}

.oc-head a {
  font-size: var(--token-fs-xs-plus);
  white-space: nowrap;
}

.oc-head form.inline {
  display: inline-flex;
}

/* The board's small button: 30 tall, 10 in, 13px. */
.op-sm.btn,
a.op-sm.btn,
.oc-head .btn,
.oc-foot .btn:not(.btn-primary) {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

/* A card's foot: its note on the left, its action on the right, under a rule. */
.oc-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  padding: var(--token-space-3) var(--token-space-5);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.oc-foot .grow {
  flex: 1 1 auto;
}

.oc-foot .note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.oc-foot form.inline {
  display: inline-flex;
}

/* ================================================== Opportunities · Огляд */

/* Four tiles, 14 apart (CoverageA) — two to a row on a narrow screen. */
.od-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
}

.od-kpi {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: calc(var(--token-space-4) + var(--token-gap-hair)) var(--token-space-5);
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  color: var(--token-color-text-primary);
  text-decoration: none;
  line-height: 1.5;
}

.od-kpi:hover {
  border-color: var(--token-color-border-strong);
  text-decoration: none;
}

.od-kpi-l {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.od-kpi-n {
  margin-top: calc(var(--token-space-1) * 1.5);
  font-family: var(--token-font-display);
  font-size: var(--token-fs-hero-min);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
}

/* Three breakdown cards (TendersDashA's card: 18 × 20, 12 between rows). */
.od-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--token-space-4);
}

.od-card {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  min-width: 0;
  padding: calc(var(--token-space-4) + var(--token-gap-hair)) var(--token-space-5);
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  line-height: 1.5;
}

.od-card > * {
  margin: 0;
}

.od-card h2 {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  letter-spacing: 0;
}

.od-card .note {
  font-size: var(--token-fs-xs-plus);
}

/* Label · bar · figure, one grid so the bars of a card start together. */
ul.od-bars {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: max-content minmax(var(--token-space-10), 1fr) max-content;
  align-items: center;
  gap: calc(var(--token-space-2) + var(--token-gap-hair)) var(--token-space-3);
  font-size: var(--token-fs-sm);
}

ul.od-bars > li {
  display: contents;
}

a.od-bar-l {
  display: inline-flex;
  min-width: 0;
  max-width: calc(var(--token-layout-field-basis) * 0.8);
  color: var(--token-color-text-secondary);
  text-decoration: none;
}

a.od-bar-l:hover {
  text-decoration: none;
  color: var(--token-color-text-primary);
}

/* The board's bar: 6 tall, a pill on the sunken ground, the fill in the accent. */
ul.od-bars .meter {
  display: block;
  height: calc(var(--token-space-1) * 1.5);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

ul.od-bars .meter > span {
  display: block;
  height: 100%;
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-fill);
}

ul.od-bars a.count {
  justify-self: end;
  font-size: var(--token-fs-xs-plus);
  font-variant-numeric: tabular-nums;
  color: var(--token-color-accent-text);
}

/* The lead tables: a card with its head, then the queue's own table. */
.od-leads {
  overflow: hidden;
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  line-height: 1.5;
}

.od-leads > * {
  margin: 0;
}

.od-leads-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.od-leads-head h2 {
  margin: 0;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  letter-spacing: 0;
}

.od-leads-head .grow {
  flex: 1 1 auto;
}

.od-leads-head a {
  font-size: var(--token-fs-xs-plus);
}

.od-none {
  padding: var(--token-space-4);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
}

/* OpportunitiesA's table: headers 12 on 9 × 12, rows 58 tall, 12 in. */
.op-table .scroller th,
.od-leads .scroller th {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-layout-cell-pad-x);
}

.op-table .scroller td,
.od-leads .scroller td {
  height: calc(var(--token-space-12) + var(--token-space-2) + var(--token-gap-hair));
  padding: 0 var(--token-layout-cell-pad-x);
}

.op-table .scroller th:first-child,
.op-table .scroller td:first-child,
.op-table .scroller th:last-child,
.op-table .scroller td:last-child,
.od-leads .scroller th:first-child,
.od-leads .scroller td:first-child,
.od-leads .scroller th:last-child,
.od-leads .scroller td:last-child {
  padding-inline: var(--token-layout-cell-pad-x);
}

/* 96 · the rest · 120 · 150 — the first wide enough for the score's bar and
   figure side by side. */
.od-leads table.fixed col[data-col="score"] {
  width: var(--token-space-24);
}

.od-leads table.fixed col[data-col="deadline"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.od-leads table.fixed col[data-col="eligibility"] {
  width: calc(var(--token-layout-col-when));
}

@media (max-width: 1100px) {
  .od-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  .od-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ============================================================== one lead */

/* The head of TenderOverviewA without its band: the trail, the title with
   the lead's verdicts beside it, one line of what the lead is under it. */
.ol-top {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.5;
}

.ol-crumbs {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.ol-title-row {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--token-space-3) + var(--token-gap-hair));
  margin-top: calc(var(--token-space-1) * 1.5);
  min-width: 0;
}

/* 22px: the display face one step over the section heads, as the board's. */
.ol-title {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: calc(var(--token-fs-lg) * 1.1);
  line-height: 1.15;
  letter-spacing: -0.01em;
  overflow-wrap: break-word;
}

.ol-acts {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--token-space-2);
}

.ol-acts form.inline {
  display: inline-flex;
  gap: var(--token-space-2);
}

.ol-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-4);
  margin-top: var(--token-space-2);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.ol-sep {
  color: var(--token-color-text-tertiary);
}

/* The fact sheet: four cells across, each ruled right and below; the card's
   own edge swallows the last column's and row's rules. */
.ol-facts {
  overflow: hidden;
}

dl.ol-facts-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0 calc(var(--token-border-hair) * -1) calc(var(--token-border-hair) * -1) 0;
}

.ol-fact {
  min-width: 0;
  padding: calc(var(--token-space-3) - var(--token-border-hair)) var(--token-space-4);
  border-right: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  line-height: 1.5;
}

.ol-fact dt {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.ol-fact dd {
  margin: var(--token-space-1) 0 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-primary);
  font-variant-numeric: tabular-nums;
}

.ol-fact dd .is-none {
  color: var(--token-color-text-tertiary);
}

.ol-fact dd .badge {
  vertical-align: middle;
}

/* The score beside the notice, the same height (the board's criteria and
   deliverables pair). */
.ol-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: var(--token-space-5);
  align-items: stretch;
}

.ol-pair > :only-child {
  grid-column: 1 / -1;
}

.oc > .oc-body {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: calc(var(--token-space-3) + var(--token-gap-hair)) var(--token-space-4);
  line-height: 1.5;
}

.oc-body > * {
  margin: 0;
}

.ol-line {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

.ol-line b {
  font-weight: var(--token-weight-medium);
}

.ol-line.dim {
  color: var(--token-color-text-tertiary);
  font-size: var(--token-fs-xs-plus);
}

.ol-prose {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

/* The figure in the display face, CoverageA's 32, the «/ 100» quiet after it. */
.ol-big {
  font-family: var(--token-font-display);
  font-size: var(--token-fs-hero-min);
  line-height: var(--token-lh-tight);
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-primary);
}

.ol-big.s-ok {
  color: var(--token-color-state-ok-text);
}

.ol-big > span {
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
}

/* The parts of the score as the board's criteria table: 9 × 16 heads, rows
   10 × 16, the sub-rows on the inset ground at 13px. */
table.ol-parts {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

table.ol-parts th {
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-space-4);
}

table.ol-parts td {
  height: auto;
  padding: calc(var(--token-space-2) + var(--token-gap-hair)) var(--token-space-4);
  line-height: 1.5;
}

table.ol-parts th[data-col="points"] {
  width: calc(var(--token-space-10) * 1.75);
}

table.ol-parts th[data-col="share"] {
  width: calc(var(--token-space-10) * 3);
}

table.ol-parts td.num {
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
}

.ol-part {
  display: block;
  font-weight: var(--token-weight-medium);
}

.ol-why {
  display: block;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

table.ol-parts tr.sub td {
  background: var(--token-color-surface-inset);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  padding-top: calc(var(--token-space-1) + var(--token-inset-chip));
  padding-bottom: calc(var(--token-space-1) + var(--token-inset-chip));
}

table.ol-parts tr.sub td:first-child {
  padding-left: var(--token-space-8);
}

table.ol-parts tr.sub td.num {
  white-space: normal;
  text-align: right;
}

/* The weight's bar: 8 tall, the accent, 3 round — the board's criteria bar. */
table.ol-parts .meter {
  display: block;
  width: 100%;
  height: var(--token-space-2);
  background: none;
}

table.ol-parts .meter > span {
  display: block;
  height: 100%;
  border-radius: var(--token-inset-chip);
  background: var(--token-color-accent-fill);
}

ul.ol-rules {
  margin: 0;
  padding-left: var(--token-space-4);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

/* The codes: TenderOverviewA's «D1 …» rows — the code quiet, the words after. */
.ol-codes > ul {
  list-style: none;
  margin: var(--token-space-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.ol-codes li {
  display: flex;
  flex-wrap: wrap;
  gap: 0 calc(var(--token-space-2) + var(--token-gap-hair));
}

.ol-sub-h {
  font-weight: var(--token-weight-medium);
  padding-top: calc(var(--token-space-1) * 1.5);
}

.ol-code {
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.ol-codes .dim {
  color: var(--token-color-text-tertiary);
}

/* Files and history: rows of the board's table, 46 tall under a rule. */
ul.ol-file-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

ul.ol-file-list > li {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  min-height: calc(var(--token-space-12) - var(--token-gap-hair));
  padding: 0 var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-sm);
}

ul.ol-file-list > li:first-child {
  border-top: 0;
}

.ol-file {
  flex: 1 1 auto;
  min-width: 0;
}

ul.ol-file-list .dim {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

ul.ol-file-list .grow {
  flex: 1 1 auto;
}

ul.ol-file-list form.inline {
  display: inline-flex;
}

@media (max-width: 1100px) {
  .ol-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  dl.ol-facts-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ol-title-row {
    flex-wrap: wrap;
  }
}

.ol-score,
.ol-about,
.ol-files,
.ol-history {
  overflow: hidden;
}

/* ======================================= Opportunities · Джерела й оцінка */

/* The forms that only carry an id for `form=`, or a hidden source: nothing
   to show, and no room taken in the column. */
.os > form:empty,
.os > form.inline:not(:has(:not(input[type='hidden']))) {
  display: none;
}

.os > form {
  margin: 0;
}

.os-card {
  line-height: 1.5;
}

/* The head's name and its line under it (AdminA's legend card). */
.os-head-text {
  display: flex;
  flex-direction: column;
  gap: var(--token-gap-hair);
  min-width: 0;
}

.os-head-text .note {
  max-width: var(--token-measure-lede);
}

.os-body {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--token-space-5);
  padding: var(--token-space-5);
}

.os-body > * {
  margin: 0;
}

/* Two columns of fields, 20 apart, one on a narrow screen. */
.os-cols,
.os-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--token-space-5);
  align-items: start;
}

.os-grid {
  gap: var(--token-space-4) var(--token-space-5);
}

.os-col {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-4);
  min-width: 0;
}

.os-grid > .os-wide {
  grid-column: 1 / -1;
}

/* FormatsA's field: label 13 medium, box 40, the hint 12 and quiet under it. */
.os-field {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) * 1.5);
  min-width: 0;
}

.os-field > .field {
  flex: none;
  max-width: none;
  width: 100%;
}

.os-hint {
  margin: 0;
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

.os-lbl {
  margin: 0;
  padding: 0;
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

.os-line {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
}

.os-line b {
  font-weight: var(--token-weight-medium);
}

.os-group {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  min-width: 0;
}

.os-group > * {
  margin: 0;
}

.os-group > .os-hint + * {
  margin-top: var(--token-space-1);
}

/* A choice is a card: the chosen one takes the accent's frame and wash. */
fieldset.os-radios {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

fieldset.os-radios > legend.os-lbl {
  margin-bottom: var(--token-space-2);
}

fieldset.os-radios-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

fieldset.os-radios-2 > legend {
  grid-column: 1 / -1;
}

.os-radio {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: var(--token-space-3) calc(var(--token-space-3) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-seg);
  background: var(--token-color-surface-raised);
  cursor: pointer;
}

/* The chosen card's frame is 2px; its padding gives back the difference so
   the text does not move. */
.os-radio:has(input:checked) {
  border: var(--token-border-thick) solid var(--token-color-accent-fill);
  padding: calc(var(--token-space-3) - var(--token-border-hair)) calc(var(--token-space-3) + var(--token-gap-hair) - var(--token-border-hair));
  background: var(--token-color-accent-wash);
}

.os-radio input[type='radio'] {
  margin-top: var(--token-border-hair);
}

.os-radio input[type='radio']::before {
  width: var(--token-size-dot);
  height: var(--token-size-dot);
}

.os-radio-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.os-radio-t {
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.os-radio-d {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

/* The kit's ticks, in rows. */
.os-ticks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-3) var(--token-space-6);
}

.os-ticks-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.os-card .tickbox {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  cursor: pointer;
}

.os-card .tickbox:has(input:disabled) {
  color: var(--token-color-text-tertiary);
  cursor: not-allowed;
}

/* Keywords: the two lists side by side, each a row of chips and its box. */
.os-kw-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--token-space-5);
}

.os-kw {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  min-width: 0;
  padding: var(--token-space-4);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-seg);
  background: var(--token-color-surface-inset);
}

.os-kw > * {
  margin: 0;
}

.os-kw > form.inline {
  display: flex;
  gap: var(--token-space-2);
  align-items: center;
}

.os-kw > form.inline > .field {
  flex: 1 1 auto;
  max-width: none;
  background: var(--token-color-surface-raised);
}

ul.os-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

/* TenderOverviewA's chip: 6 × 10, a hairline, 8 round, 13px. */
.os-chip > summary,
.os-chip-t {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  padding: calc(var(--token-space-1) * 1.5) calc(var(--token-space-2) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-primary);
  list-style: none;
  cursor: pointer;
}

.os-chip-t {
  cursor: default;
}

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

.os-chip > summary:hover,
.os-chip[open] > summary {
  border-color: var(--token-color-border-strong);
}

.os-chip {
  position: relative;
}

/* The chip's rename and remove, as a menu card under it. */
.os-pop {
  position: absolute;
  top: calc(100% + var(--token-space-1));
  left: 0;
  z-index: var(--token-z-sticky);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  width: calc(var(--token-layout-field-basis) * 1.3);
  padding: var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.os-pop form.inline {
  display: flex;
  gap: var(--token-space-2);
  align-items: center;
}

.os-pop form.inline > .field {
  flex: 1 1 auto;
  max-width: none;
}

.os-remove {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-state-crit-text);
}

/* The rule table's bar: the search box and the chips. */
.os-bar .field:has(> .sr) {
  flex: 0 0 auto;
  width: calc(var(--token-space-24) * 3 - var(--token-space-2));
  max-width: 100%;
  background: var(--token-color-surface-raised);
}

.os-rules .os-body {
  gap: var(--token-space-3);
  padding-bottom: var(--token-space-4);
}

.os-rules > .op-table {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.os-rules .oc-foot {
  padding: calc(var(--token-space-2) + var(--token-gap-hair)) var(--token-space-4);
}

.os-rules .oc-foot a {
  white-space: nowrap;
}

.os-rules .oc-foot .tn {
  font-variant-numeric: tabular-nums;
  color: var(--token-color-text-primary);
}

/* Правило 90 · Код 110 · the rest · Дія 110 · Вага 70 · Стан 120 · 116. */
.os-rules table.fixed col[data-col="rule"] {
  width: calc(var(--token-space-24) - var(--token-space-2));
}

.os-rules table.fixed col[data-col="cpv"] {
  width: calc(var(--token-space-24) + var(--token-space-4) - var(--token-gap-hair));
}

.os-rules table.fixed col[data-col="action"] {
  width: calc(var(--token-space-24) + var(--token-space-4) - var(--token-gap-hair));
}

.os-rules table.fixed col[data-col="weight"] {
  width: calc(var(--token-space-16) + var(--token-space-1) + var(--token-gap-hair));
}

.os-rules table.fixed col[data-col="state"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.os-rules table.fixed col[data-col="edit"] {
  width: calc(var(--token-space-24) + var(--token-space-5));
}

.op-table td:last-child {
  text-align: right;
}

.os-query {
  margin: 0;
  padding: var(--token-space-2) var(--token-space-3);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-inset);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  overflow-wrap: anywhere;
}

/* Rows of a card: the board's table rows, 46 tall under a rule. */
ul.os-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A connector's runs: five in view, the rest of the page under a scroll —
   a page of twenty made each card as tall as three screens. The script
   measures five rows (`data-rows-visible`); this cap is five of the usual
   78px rows for a page without it. A run's details open inside the scroll
   and lengthen it. */
.os-activity > ul.os-rows {
  max-height: calc(var(--token-space-24) * 4);
  overflow-y: auto;
  overscroll-behavior: contain;
}

ul.os-rows > li {
  display: flex;
  align-items: center;
  gap: var(--token-space-4);
  min-height: calc(var(--token-space-12) - var(--token-gap-hair));
  padding: calc(var(--token-space-2) + var(--token-gap-hair)) var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-sm);
}

ul.os-rows > li:first-child {
  border-top: 0;
}

.os-when {
  flex: none;
  width: var(--token-layout-col-when);
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.os-src {
  flex: none;
  width: calc(var(--token-space-24) + var(--token-space-2));
}

.os-what {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
}

.os-sub {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.os-sub.crit {
  color: var(--token-color-state-crit-text);
}

.os-card .sec {
  color: var(--token-color-text-secondary);
}

/* A row that cannot be ticked keeps its text in line with the ones that can. */
.os-nobox {
  flex: none;
  width: var(--token-size-checkbox);
}

.os-empty,
.os-count {
  margin: 0;
  padding: var(--token-space-4);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
}

.os-count {
  padding-bottom: 0;
  color: var(--token-color-text-secondary);
}

.os-card > form > .oc-foot .note {
  max-width: var(--token-measure-lede);
}

.os-activity-head .seg {
  flex: none;
}

/* ====================================================== the drawer
   FormatsA's sheet: the page under a scrim, a 480px panel from the right,
   its head, its fields, its two buttons at the foot. Opened as the URL's
   target, so it needs no script. */
.os-sheet {
  --os-scrim: color-mix(in srgb, var(--token-color-text-primary) 28%, transparent);
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--token-z-skip);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .os-sheet {
    --os-scrim: color-mix(in srgb, var(--token-color-surface-sunken) 70%, transparent);
  }
}

:root[data-theme='dark'] .os-sheet {
  --os-scrim: color-mix(in srgb, var(--token-color-surface-sunken) 70%, transparent);
}

.os-sheet:target {
  display: block;
}

.os-scrim {
  position: absolute;
  inset: 0;
  background: var(--os-scrim);
  cursor: default;
}

.os-drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(100%, calc(var(--token-layout-aside) + var(--token-space-12) + var(--token-space-3)));
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-5);
  padding: var(--token-layout-aside-pad-x) var(--token-layout-page-pad-y);
  background: var(--token-color-surface-raised);
  border-left: var(--token-border-hair) solid var(--token-color-border-subtle);
  box-shadow: calc(var(--token-space-3) * -1) 0 var(--token-space-10) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  line-height: 1.5;
  text-align: left;
}

.os-drawer > * {
  margin: 0;
}

.os-drawer > form {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--token-space-5);
}

.os-drawer > form > * {
  margin: 0;
}

.os-drawer-head {
  display: flex;
  align-items: center;
}

.os-drawer-head h2 {
  flex-grow: 1;
  margin: 0;
  font-size: calc(var(--token-fs-lg) + var(--token-gap-hair));
  line-height: 1.15;
  letter-spacing: -0.01em;
}

a.btn.os-close {
  background: transparent;
  border-color: transparent;
  color: var(--token-color-text-secondary);
}

a.btn.os-close:hover {
  background: var(--token-color-surface-sunken);
  text-decoration: none;
}

.os-grow {
  flex-grow: 1;
}

.os-actions {
  display: flex;
  gap: var(--token-layout-item-pad-x);
  justify-content: flex-end;
}

.os-drawer .os-ticks {
  flex-direction: column;
  gap: var(--token-space-3);
}

.os-drawer .tickbox {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  cursor: pointer;
}

@media (max-width: 1100px) {
  .os-cols,
  .os-kw-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  .os-grid,
  .os-ticks-3 {
    grid-template-columns: minmax(0, 1fr);
  }

  .oc-head {
    flex-wrap: wrap;
  }
}

/* ============================================ Налаштування (ШІ, Словники)
   AdminA's page: 32 above, the frame's own sides, 20 between blocks. */
.wrap:has(> .st) {
  padding-top: var(--token-space-8);
}

.st {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-5);
  min-width: 0;
  line-height: 1.5;
}

.st > * {
  margin: 0;
}

.st > section {
  padding-top: 0;
}

/* The head: the title and its line; the switcher and the one action right,
   bottoms aligned. */
.st > .st-hero {
  align-items: flex-end;
  gap: var(--token-space-4);
  flex-wrap: wrap;
  padding: 0;
}

/* As every page head: the title keeps an aside's width, the actions go under. */
.st-hero .hero-text {
  flex: 1 1 var(--token-layout-aside);
  min-width: min(var(--token-layout-aside), 100%);
}

.st-hero h1 {
  font-size: var(--token-fs-h1);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.st-hero .lede {
  max-width: none;
  margin-top: calc(var(--token-space-1) * 1.5);
  color: var(--token-color-text-tertiary);
  line-height: 1.5;
}

.st-hero .hero-action {
  display: flex;
  align-items: center;
  gap: var(--token-space-4);
  padding: 0;
}

.st-hero .btn-icon {
  width: var(--token-space-4);
  height: var(--token-space-4);
  min-width: 0;
  padding: 0;
}

.st .seg a {
  color: var(--token-color-text-secondary);
}

.st .seg a[aria-current='true'] {
  color: var(--token-color-text-primary);
}

.st-head-text {
  display: flex;
  flex-direction: column;
  gap: var(--token-gap-hair);
  min-width: 0;
}

/* AdminA's bar: the 300px search, the segments, 12 apart. */
.st-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--token-space-3);
  min-width: 0;
}

.st-bar form.inline {
  display: inline-flex;
}

.st-bar .field:has(> .sr) {
  flex: 0 0 var(--token-layout-panel-min);
  width: var(--token-layout-panel-min);
  max-width: 100%;
  background: var(--token-color-surface-raised);
}

.st-bar .grow {
  flex: 1 1 auto;
}

/* «Показати неактивні»: the kit's checkbox, drawn on a link. */
a.st-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  text-decoration: none;
  white-space: nowrap;
}

a.st-toggle:hover {
  text-decoration: none;
}

.st-box {
  display: inline-grid;
  place-content: center;
  flex: none;
  width: var(--token-size-checkbox);
  height: var(--token-size-checkbox);
  border: var(--token-border-check) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-check);
  background: var(--token-color-surface-raised);
  color: var(--token-color-on-accent);
  transition: background-color var(--token-dur-fast), border-color var(--token-dur-fast);
}

a.st-toggle:hover .st-box {
  border-color: var(--token-color-accent-fill);
}

a.st-toggle[aria-checked='true'] .st-box {
  background-color: var(--token-color-accent-fill);
  border-color: var(--token-color-accent-fill);
}

.st-box::before {
  content: '';
  width: var(--token-space-3);
  height: var(--token-space-3);
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")
    center / contain no-repeat;
  transform: scale(0);
}

a.st-toggle[aria-checked='true'] .st-box::before {
  transform: scale(1);
}

/* AdminA's table: headers 12 on 10 × 16, rows 50 at 13px, 16 in. */
.st-card {
  overflow: visible;
}

.st-table .scroller th {
  padding: var(--token-layout-head-pad-y) var(--token-space-4);
}

.st-table .scroller td {
  height: var(--token-layout-row-h);
  padding: 0 var(--token-space-4);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
}

.st-table .scroller th:last-child,
.st-table .scroller td:last-child {
  padding-right: var(--token-space-4);
}

.st-table .scroller td .row-title {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
  text-decoration: none;
}

.st-table .scroller td a.row-title:hover {
  color: var(--token-color-accent-text);
}

.st-table td .badge {
  vertical-align: middle;
}

.st-card .oc-head + .st-table {
  border-top: 0;
}

.st-card .sec {
  color: var(--token-color-text-secondary);
}

/* The dictionary's columns: Назва 240 · Синоніми the rest · Опис 260 ·
   Використань 110 · Порядок 90 · 60 for the «···». */
.st-table table.fixed col[data-col="name"] {
  width: calc(var(--token-layout-card-min) - var(--token-space-2) - var(--token-gap-hair));
}

.st-table table.fixed col[data-col="description"] {
  width: calc(var(--token-layout-card-min) + var(--token-space-2) + var(--token-gap-hair));
}

.st-table table.fixed col[data-col="usage"] {
  width: calc(var(--token-space-24) + var(--token-space-3) + var(--token-gap-hair));
}

.st-table table.fixed col[data-col="order"] {
  width: calc(var(--token-space-24) - var(--token-space-1) - var(--token-gap-hair));
}

.st-table table.fixed col[data-col="menu"] {
  width: calc(var(--token-space-16) - var(--token-space-1));
}

/* A synonym is a word, not a state: AdminA's small pill, no glyph. */
.st-syns {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-1);
}

.st-syn {
  display: inline-flex;
  align-items: center;
  height: var(--token-layout-pill-h-sm);
  padding: 0 var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-state-neutral-bg);
  color: var(--token-color-state-neutral-text);
  font-size: var(--token-fs-2xs);
  white-space: nowrap;
}

.st-more-n {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* ↑ ↓: the board's 30px squares, 6 apart. */
.st-table form.inline:has(> .ib) {
  display: inline-flex;
  gap: calc(var(--token-space-1) * 1.5);
}

.st-table .ib:disabled {
  color: var(--token-color-text-tertiary);
  border-color: var(--token-color-border-subtle);
  background: var(--token-color-surface-inset);
  cursor: not-allowed;
}

/* The row's «···»: AdminA's quiet button, a menu card under it. */
.st-more > summary.st-dots {
  height: var(--token-layout-control-h);
  padding: 0 var(--token-layout-control-pad-x);
  background: transparent;
  border-color: transparent;
  color: var(--token-color-text-secondary);
  letter-spacing: 0;
}

.st-more > summary.st-dots:hover,
.st-more[open] > summary.st-dots {
  background: var(--token-color-surface-sunken);
}

.st-more .menu {
  min-width: calc(var(--token-layout-field-basis) * 0.8);
  text-align: left;
  z-index: var(--token-z-sticky);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.st-more .menu form.inline {
  display: block;
}

.st-menu-btn {
  display: block;
  width: 100%;
  padding: var(--token-space-2) var(--token-space-3);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: none;
  font: inherit;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.st-menu-btn:hover {
  background: var(--token-color-surface-inset);
}

.st-more .menu a.st-menu-danger {
  color: var(--token-color-state-crit-text);
}

.st-foot-note {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.st-empty {
  margin: 0;
  padding: var(--token-space-4);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
}

.st-table td.detail {
  padding: 0;
}

ul.st-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

ul.st-rows > li {
  display: flex;
  align-items: center;
  gap: var(--token-space-4);
  min-height: var(--token-layout-row-h);
  padding: var(--token-space-2) var(--token-space-4);
  font-size: var(--token-fs-xs-plus);
}

.st-what {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
}

.st-sub {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.st-sub.crit {
  color: var(--token-color-state-crit-text);
}

.st-when {
  flex: none;
  color: var(--token-color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* The one warning on the page, on the warning ground (TenderOverviewA). */
.st-warn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  padding: var(--token-space-4) var(--token-space-5);
  border-radius: var(--token-radius-md);
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.st-warn > * {
  margin: 0;
}

.st-warn-title {
  font-weight: var(--token-weight-medium);
}

.st-warn p {
  color: var(--token-color-text-primary);
}

/* A removal is the danger colour, not the accent. */
.btn-primary.st-danger {
  background: var(--token-color-state-crit-text);
}

/* «Загальні»: the section's line, then one reader's letter preferences and
   the stuck letters inside the outage card, on the card's own rhythm. */
.st > .st-lede {
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.st-pref {
  padding: var(--token-space-3) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.st-pref p,
.st-deliveries p {
  margin: 0;
}

.st-pref-title {
  font-weight: var(--token-weight-medium);
}

.st-pref .note {
  margin-top: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.st-prefs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2) var(--token-space-5);
  margin-top: var(--token-space-3);
}

.st-deliveries {
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
}

.st-deliveries > .st-pref-title {
  padding: 0 var(--token-space-4);
}

.st-card > .st-waiting {
  margin: 0;
  padding: var(--token-space-3) var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

@media (max-width: 900px) {
  .st > .st-hero {
    flex-wrap: wrap;
  }
}

/* Under the name, AdminA's small pills: what the entry is besides its name. */
.st-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
  margin-top: var(--token-inset-chip);
}

.st-tags .badge {
  min-height: var(--token-layout-pill-h-sm);
  font-size: var(--token-fs-2xs);
}

.st-table .scroller td:has(.st-tags) {
  padding-top: var(--token-space-2);
  padding-bottom: var(--token-space-2);
}

.st-bar + .st-bar {
  margin-top: calc(var(--token-space-2) - var(--token-space-5));
}

/* ============================================================ narrow
   Under 900 the kit stacks a table into one card per row; the rows keep the
   card's side padding and lose the fixed height of a table row. */
@media (max-width: 900px) {
  .od-leads .scroller.stack tr,
  .op-table .scroller.stack tr,
  .st-table .scroller.stack tr {
    padding: var(--token-space-3) var(--token-space-4);
  }

  .od-leads .scroller.stack td,
  .op-table .scroller.stack td,
  .st-table .scroller.stack td,
  .od-leads .scroller.stack td:first-child,
  .op-table .scroller.stack td:first-child,
  .st-table .scroller.stack td:first-child,
  .od-leads .scroller.stack td:last-child,
  .op-table .scroller.stack td:last-child,
  .st-table .scroller.stack td:last-child {
    height: auto;
    padding: var(--token-space-1) 0;
  }

  .od-leads .scroller.stack td[data-label='']::before,
  .op-table .scroller.stack td[data-label='']::before,
  .st-table .scroller.stack td[data-label='']::before {
    content: none;
  }

  .od-leads .scroller.stack td > .cv,
  .op-table .scroller.stack td > .cv,
  .st-table .scroller.stack td > .cv {
    min-width: 0;
    max-width: 70%;
  }

  .od-leads .scroller.stack td .cl1,
  .op-table .scroller.stack td .cl1 {
    white-space: normal;
  }

  .st-table .scroller.stack tbody tr:last-child,
  .od-leads .scroller.stack tbody tr:last-child,
  .op-table .scroller.stack tbody tr:last-child {
    border-bottom: 0;
  }

  .st-bar .field:has(> .sr),
  .os-bar .field:has(> .sr) {
    flex: 1 1 auto;
    width: auto;
  }

  .ol-acts {
    flex-wrap: wrap;
  }
}

/* restore E: the confirmation step before a bulk action (Сховати вибрані,
   Виправити / Спростити вибрані назви). The first press opens the warning and
   the button that posts, as the original's disclosure did. */
.oc-foot .os-confirm {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--token-space-2);
}

.oc-foot .os-confirm[open] {
  flex: 1 1 100%;
}

.oc-foot .os-confirm > summary {
  list-style: none;
  cursor: pointer;
}

.oc-foot .os-confirm > summary::-webkit-details-marker {
  display: none;
}

.oc-foot .os-confirm-body {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
}

/* ------------------------------------------------ opportunities parity
   The original's behaviours drawn in this product's language: score bands,
   the outcome line, the outage banner, the connector cards. Tokens only. */

/* Their relevanceColor: amber from 50, red below — ok stays green. */
.score.s-warn {
  color: var(--token-color-state-warn-text);
  background: var(--token-color-state-warn-bg);
}

.score.s-crit {
  color: var(--token-color-state-crit-text);
  background: var(--token-color-state-crit-bg);
}

.ol-big.s-warn {
  color: var(--token-color-state-warn-text);
}

.ol-big.s-crit {
  color: var(--token-color-state-crit-text);
}

.ol-big.s-none {
  color: var(--token-color-text-tertiary);
}

/* The whole title and the whole buyer, three lines at most (their line-clamp-3). */
.tr-opp span.opp-buyer {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  /* Whole words; only a word longer than the column breaks. */
  overflow-wrap: break-word;
  hyphens: auto;
}

.tr-opp a.opp-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  overflow-wrap: break-word;
  color: var(--token-color-text-primary);
}

/* What the last press did: the state chip and its sentence. */
.opp-flash {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  margin: 0 0 var(--token-space-4);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

/* The Shell's outage banner, above every Tenders page. */
.outage-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-3);
  margin: 0 0 var(--token-space-4);
  padding: var(--token-space-3) var(--token-space-4);
  border: var(--token-border-hair) solid var(--token-color-state-crit-text);
  border-radius: var(--token-radius-md);
  background: var(--token-color-state-crit-bg);
  font-size: var(--token-fs-sm);
}

.outage-banner .grow {
  flex: 1 1 auto;
}

.outage-banner form.inline {
  margin: 0;
}

/* The scheme a source classification belongs to, beside its code. */
.ol-scheme {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  margin-right: var(--token-space-2);
}

/* Three connector cards side by side, one column on a phone. */
.os-activity-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--token-layout-card-min)), 1fr));
  gap: var(--token-space-4);
  margin-bottom: var(--token-space-4);
}

.os-activity-grid .os-card {
  margin: 0;
}

.os-activity h2 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
}

.os-runs-h {
  padding: var(--token-space-2) var(--token-space-4) 0;
}

.os-sub.warn,
.os-hint.warn {
  color: var(--token-color-state-warn-text);
}

.os-hint.crit,
.os-line.crit {
  color: var(--token-color-state-crit-text);
}

.os-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  margin-bottom: var(--token-space-3);
}

/* The exchange-rate panel: the facts on the left, the resync on the right. */
.os-fx {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--token-space-4);
}

.os-fx-text {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
  min-width: 0;
}

/* ------------------------------------------------ opportunities columns
   Their list's Country, Source and Score cells (OpportunityList.tsx:879-990),
   and the score bar the dashboard's leads and a lead's page draw too. */

/* The country: the flag at their `text-xl`, its code beside it. */
.opp-country {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  white-space: nowrap;
}

.opp-flag {
  font-size: var(--token-fs-lg);
  line-height: 1;
}

.opp-cc {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
}

/* The source: the portal's mark on its own white tile — theirs is 32 × 32,
   `bg-white` in both themes — and the way out to the notice. */
.opp-src {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  white-space: nowrap;
}

.src-mark {
  display: inline-flex;
  flex: none;
  width: var(--token-space-8);
  height: var(--token-space-8);
}

.src-mark > svg {
  width: 100%;
  height: 100%;
}

.src-tag {
  display: inline-flex;
  align-items: center;
  min-height: var(--token-layout-pill-h-sm);
  padding: 0 var(--token-layout-chip-pad-x);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-chip);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
}

a.src-out {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
  text-decoration: none;
}

a.src-out:hover {
  color: var(--token-color-accent-text);
}

/* The score: their bar, then the figure's tile. The track is the sunken
   surface; the fill takes the band's colour and the kit's `pct-N` width. */
/* Published over Updated in one cell: the update smaller and lighter. */
.opp-dates {
  display: flex;
  flex-direction: column;
  gap: var(--token-gap-hair);
}

.opp-dates > .opp-upd {
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  color: var(--token-color-text-tertiary);
}

.score-cell {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--token-space-1) * 1.5);
  white-space: nowrap;
}

/* The figure is a button: hover and focus open its explanation. */
button.score {
  border: 0;
  padding: 0;
  font: inherit;
  font-size: var(--token-fs-sm);
  cursor: help;
}

button.score:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-thick);
}

/* A one-line tooltip on a value — the flag's country, the whole amount
   behind «4.235M UAH» — in the score tooltip's card, as wide as its text. */
.opp-tip {
  padding: var(--token-space-1) var(--token-space-2);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  color: var(--token-color-text-primary);
  font-size: var(--token-fs-xs-plus);
  font-weight: var(--token-weight-regular);
  white-space: nowrap;
}

.opp-value,
.opp-country[data-tip] {
  cursor: help;
}

.opp-value:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-thick);
  border-radius: var(--token-radius-sm);
}

/* The main CPV tag under an opportunity's title: the winning rule's code,
   then its description cut to the cell. A button when there is a description
   to show whole on hover and focus. */
.opp-cpv-row {
  display: flex;
  min-width: 0;
  margin-top: var(--token-space-1);
}

.opp-cpv {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  min-width: 0;
  max-width: 100%;
  height: var(--token-layout-pill-h);
  padding: 0 var(--token-space-2);
  border: 0;
  border-radius: var(--token-radius-pill);
  background: var(--token-badge-neutral-bg);
  color: var(--token-badge-neutral-fg);
  font: inherit;
  font-size: var(--token-fs-xs);
  line-height: var(--token-lh-tight);
  text-align: left;
}

.opp-cpv > .mono {
  flex: none;
}

.opp-cpv-d {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

button.opp-cpv {
  cursor: help;
}

button.opp-cpv:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-thick);
}

/* The score's explanation: a section per contribution, heading over its
   lines, then what the figure is. Wraps, as the cell it hangs from does not.
   The CPV tag's whole description wears the same card. */
.score-tip,
.opp-cpv-tip {
  display: grid;
  gap: var(--token-space-2);
  width: min(calc(var(--token-space-24) * 3 + var(--token-space-8)), calc(100vw - var(--token-space-4)));
  padding: var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  color: var(--token-color-text-secondary);
  font-size: var(--token-fs-xs-plus);
  line-height: var(--token-lh-normal);
  text-align: left;
  white-space: normal;
  overflow-wrap: anywhere;
}

.opp-cpv-tip {
  display: block;
  color: var(--token-color-text-primary);
}

.opp-cpv-tip > b {
  font-weight: var(--token-weight-medium);
}

.score-tip-s {
  display: grid;
  gap: var(--token-gap-hair);
}

.score-tip-s > b {
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.score-tip-s.crit > span {
  color: var(--token-color-state-crit-text);
}

.score-tip-s.warn > span {
  color: var(--token-color-state-warn-text);
}

.score-tip-foot {
  padding-top: var(--token-space-2);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  color: var(--token-color-text-tertiary);
  font-size: var(--token-fs-xs);
}

.score-bar {
  display: inline-block;
  flex: none;
  width: var(--token-space-8);
  height: calc(var(--token-space-1) + var(--token-border-thick));
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  overflow: hidden;
}

.score-bar > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--token-color-text-tertiary);
}

.score-bar.s-ok > span {
  background: var(--token-color-state-ok-text);
}

.score-bar.s-warn > span {
  background: var(--token-color-state-warn-text);
}

.score-bar.s-crit > span {
  background: var(--token-color-state-crit-text);
}

/* A lead's page: their 200-wide bar, a step taller, before the big figure. */
.ol-figure {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
}

.ol-figure > .score-bar {
  flex: 0 1 auto;
  width: calc(var(--token-space-24) * 2 + var(--token-space-2));
  height: var(--token-space-2);
}

.ol-figure > .ol-big {
  margin: 0;
}

.tr-opp .opp-card td .when {
  font-size: var(--token-fs-xs-plus);
}

/* Ten columns need about 1070 of width to leave the title a readable measure.
   Narrower than that — the side column beside a 1400 screen leaves about 1070
   — the list becomes one card per lead, as the kit makes every stacking table
   under 900: the title first and whole, then the other columns as small named
   facts flowing in a grid, several to a line. Never a sideways scroll, never a
   cut column. */
@media (max-width: 1400px) {
  .tr-opp .opp-card .scroller.stack table,
  .tr-opp .opp-card .scroller.stack tbody {
    display: block;
    width: 100%;
  }

  .tr-opp .opp-card .scroller.stack thead {
    position: absolute;
    width: var(--token-size-hidden);
    height: var(--token-size-hidden);
    overflow: hidden;
    clip-path: inset(50%);
  }

  .tr-opp .opp-card .scroller.stack colgroup {
    display: none;
  }

  .tr-opp .opp-card .scroller.stack tr {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--token-space-24) + var(--token-space-10))), 1fr));
    gap: var(--token-space-2) var(--token-space-4);
    width: 100%;
    padding: var(--token-space-3) var(--token-space-4);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tr-opp .opp-card .scroller.stack tbody tr:last-child {
    border-bottom: 0;
  }

  .tr-opp .opp-card .scroller.stack td,
  .tr-opp .opp-card .scroller.stack td:first-child,
  .tr-opp .opp-card .scroller.stack td:last-child {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--token-layout-hair-gap);
    width: auto;
    min-width: 0;
    height: auto;
    padding: 0;
    border-bottom: 0;
  }

  .tr-opp .opp-card .scroller.stack td[data-label]::before {
    content: attr(data-label);
    max-width: none;
    font-family: var(--token-font-body);
    font-size: var(--token-fs-xs);
    color: var(--token-color-text-tertiary);
  }

  .tr-opp .opp-card .scroller.stack td > .cv {
    min-width: 0;
    max-width: 100%;
    text-align: left;
  }

  /* The title leads the card, whole, unlabelled and across it. */
  .tr-opp .opp-card .scroller.stack td[data-label='Можливість'] {
    grid-column: 1 / -1;
    order: -1;
  }

  .tr-opp .opp-card .scroller.stack td[data-label='Можливість']::before {
    content: none;
  }

  .tr-opp .opp-card .scroller.stack td .cl1 {
    white-space: normal;
  }

  .tr-opp .opp-card .scroller.stack td.detail {
    display: block;
    grid-column: 1 / -1;
  }
}

/* ---- Stop and Force restart under the newest running sync (their two
   buttons, OpportunitySettings.tsx:289-297), each a small menu that asks
   before it posts, as their confirmation dialogs do. `os-ctl`, not the
   keyword chip's `os-pop`, whose absolute box pulled the controls out of
   their row. ---- */
.os .os-run-ctl {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  margin-top: var(--token-space-2);
}

.os .os-ctl > .menu {
  width: min(calc(var(--token-layout-field-max) - var(--token-space-5)), calc(100vw - var(--token-space-8)));
  padding: var(--token-space-3);
  text-align: left;
}

.os .os-ctl > .menu form {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.os .os-ctl .os-pop-hint {
  margin: 0;
  font-size: var(--token-fs-xs-plus);
  line-height: var(--token-lh-normal);
  color: var(--token-color-text-secondary);
  white-space: normal;
}

.os .os-ctl .kit {
  display: flex;
  justify-content: flex-end;
}

.os .os-danger {
  border-color: var(--token-color-state-crit-text);
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

/* ======================================================= wave 2 · parity C/F
   The Opportunities screens and Settings as the original draws them: its
   icons, its status pill menu, its filter sheet, its sliders, its connector
   tabs, its run glyphs — in this product's tokens. */

/* A glyph beside words: the kit's `.btn` already spaces one; links and
   headings here take the same small gap. */
.st-card-t,
.os-line.os-active,
.ol-back,
.ol-out,
.ol-docs,
.opp-hidden,
.od-kpi-l {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

.st-card-t > .ic,
.os-active > .ic,
.st .st-section-head .ic {
  color: var(--token-color-accent-text);
}

.ol-back > .ic,
.opp-hidden > .ic {
  color: var(--token-color-text-tertiary);
}

/* ---------------------------------------------------------------- status
   Their coloured pill, which opens the menu of the three a person may set.
   Open wears the accent's wash, converted the accent itself: this palette has
   no blue, and its accent is the purple. */
.badge.opp-st-converted {
  background: var(--token-color-accent-fill);
  color: var(--token-color-on-accent);
}

.opp-st-menu {
  position: relative;
  display: inline-block;
}

.opp-st-menu > summary.badge {
  list-style: none;
  cursor: pointer;
}

.opp-st-menu > summary.badge::-webkit-details-marker {
  display: none;
}

.opp-st-menu > summary.badge:hover {
  box-shadow: inset 0 0 0 var(--token-border-hair) currentColor;
}

.opp-st-menu > summary.badge:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-border-thick);
}

.opp-st-menu > .menu {
  left: 0;
  right: auto;
  min-width: calc(var(--token-space-24) + var(--token-space-16));
  padding: var(--token-space-1);
}

.opp-st-menu > .menu form {
  display: block;
}

.opp-st-item {
  display: block;
  width: 100%;
  padding: var(--token-space-2) var(--token-space-3);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: none;
  font: inherit;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-primary);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.opp-st-item:hover:not(:disabled) {
  background: var(--token-color-surface-inset);
}

.opp-st-item[aria-current='true'] {
  color: var(--token-color-text-tertiary);
  cursor: default;
}

/* ------------------------------------------------------------- the toolbar
   Their search with its `Search` glyph inside the box. */
.field.opp-search {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: 0 1 auto;
  width: calc(var(--token-space-24) * 3 - var(--token-space-2));
  max-width: 100%;
}

.field.opp-search > .ic {
  position: absolute;
  left: var(--token-space-3);
  color: var(--token-color-text-tertiary);
  pointer-events: none;
}

.field.opp-search > input {
  width: 100%;
  padding-left: calc(var(--token-space-3) + var(--token-size-icon) + var(--token-space-2));
  background: var(--token-color-surface-raised);
}

.opp-tools {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  min-width: 0;
}

.opp-tools .grow {
  flex: 1 1 auto;
}

.opp-filters-btn .opp-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--token-space-5);
  height: var(--token-space-5);
  padding: 0 var(--token-space-1);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-primary);
}

.opp-achip a {
  display: inline-flex;
  align-items: center;
}

.opp-quick-set {
  display: contents;
}

.opp-active:empty {
  display: none;
}

/* The deadline and their ActionabilityBadge beside it. */
.opp-dl {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-1);
}

.opp-act {
  display: inline-flex;
  cursor: help;
}

a.src-out {
  display: inline-flex;
  align-items: center;
}

/* Their pager: the two chevrons, the one leading nowhere dimmed. */
.tr-opp .card-foot .btn-glyph:disabled {
  opacity: 0.4;
}

/* Their error row and empty rows sit in the table's card. */
.opp-failed .empty-icon,
.od-failed .empty-icon,
.ol-missing .empty-icon {
  color: var(--token-color-state-crit-text);
}

.od-failed,
.ol-missing {
  padding: var(--token-space-8) var(--token-space-6);
}

/* ------------------------------------------------------------ the sheet
   Their «Filters» sheet: status, sources, eligibility as pill choices, the
   country as a narrowing list, «Очистити все» and «Застосувати». */
.opp-sheet .os-drawer-head {
  align-items: flex-start;
}

.opp-sheet .os-drawer-head > div {
  flex: 1 1 auto;
}

.opp-sheet .os-drawer-head .note {
  margin: var(--token-space-1) 0 0;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.opp-sheet-g {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.opp-sheet-g > legend {
  padding: 0;
  margin-bottom: var(--token-space-2);
}

.opp-picks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.opp-pick {
  position: relative;
  display: inline-flex;
}

.opp-pick > input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.opp-pick > span {
  display: inline-flex;
  align-items: center;
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
  cursor: pointer;
}

.opp-pick > input:checked + span {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.opp-pick > input:focus-visible + span {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-gap-hair);
}

/* Their country combobox: the choice with `ChevronsUpDown`, then the box and
   the list, a `Check` on the chosen one. */
.opp-combo > summary.opp-combo-t {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  height: var(--token-layout-control-h);
  padding: 0 var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-strong);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-raised);
  font-size: var(--token-fs-sm);
  list-style: none;
  cursor: pointer;
}

.opp-combo > summary.opp-combo-t::-webkit-details-marker {
  display: none;
}

.opp-combo > summary .cl1 {
  flex: 1 1 auto;
}

.opp-combo > summary > .ic {
  color: var(--token-color-text-tertiary);
}

.opp-combo-pop {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  margin-top: var(--token-space-2);
  padding: var(--token-space-2);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface);
}

.opp-combo-pop .field.opp-search {
  width: 100%;
}

.opp-combo-list {
  max-height: calc(var(--token-layout-aside) * 0.9);
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.opp-country-opt {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  padding: var(--token-space-2);
  border-radius: var(--token-radius-sm);
  font-size: var(--token-fs-sm);
  cursor: pointer;
}

.opp-country-opt:hover {
  background: var(--token-color-surface-inset);
}

.opp-country-opt > input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.opp-country-opt > .ic {
  visibility: hidden;
  color: var(--token-color-accent-text);
}

.opp-country-opt:has(> input:checked) > .ic {
  visibility: visible;
}

.opp-country-opt:has(> input:focus-visible) {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
}

.opp-country-opt .cl1 {
  flex: 1 1 auto;
}

.opp-combo-none {
  padding: var(--token-space-2);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-tertiary);
}

/* ------------------------------------------------------------ dashboard */
.od-kpi-l {
  justify-content: space-between;
  width: 100%;
}

.od-kpi-l > .ic {
  color: var(--token-color-text-tertiary);
}

.od-go {
  display: inline-flex;
  color: var(--token-color-text-tertiary);
}

.od-leads table.fixed col[data-col="open"] {
  width: calc(var(--token-space-8) + var(--token-space-2));
}

/* ------------------------------------------------------------ one lead */
.ol-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: var(--token-space-2) var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-sm);
  font-size: var(--token-fs-sm);
}

.ol-alert p {
  margin: 0;
}

.ol-alert-crit {
  border-color: var(--token-color-state-crit-text);
  background: var(--token-color-state-crit-bg);
}

.ol-alert-crit > .ic {
  color: var(--token-color-state-crit-text);
}

.ol-alert-t {
  font-weight: var(--token-weight-medium);
}

.ol-alert-d {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
}

/* Their rule rows: `CheckCircle2` green when it matched, grey when not. */
.ol-rules li {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-2);
}

.ol-rules li > .ic {
  margin-top: var(--token-gap-hair);
}

.ol-rule-on > .ic {
  color: var(--token-color-state-ok-text);
}

.ol-rule-off > .ic {
  color: var(--token-color-text-tertiary);
}

.ol-rule-text {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
}

/* «Показати ще N правил» / «Показати менше»: the list opens above its button. */
.ol-rules-rest,
.ol-more-hide {
  display: none;
}

.ol-more-t:checked ~ .ol-rules-rest {
  display: flex;
}

.ol-more-t:checked ~ .ol-more-b .ol-more-hide,
.ol-more-show {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}

.ol-more-t:checked ~ .ol-more-b .ol-more-show {
  display: none;
}

.ol-more-t:focus-visible ~ .ol-more-b {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
}

.ol-more-b {
  cursor: pointer;
}

/* Their CPV rows, coloured by outcome, the glyph in the outcome's colour. */
.ol-cpv-mark {
  display: inline-flex;
  vertical-align: middle;
  margin-right: var(--token-space-1);
}

table.ol-parts tr.sub.ol-cpv-won td {
  background: var(--token-color-state-ok-bg);
}

.ol-parts tr.ol-cpv-won .ol-cpv-mark {
  color: var(--token-color-state-ok-text);
}

table.ol-parts tr.sub.ol-cpv-gated td {
  background: var(--token-color-state-warn-bg);
}

.ol-parts tr.ol-cpv-gated .ol-cpv-mark {
  color: var(--token-color-state-warn-text);
}

table.ol-parts tr.sub.ol-cpv-excluded td {
  background: var(--token-color-state-crit-bg);
}

.ol-parts tr.ol-cpv-excluded .ol-cpv-mark {
  color: var(--token-color-state-crit-text);
}

.ol-parts tr.ol-cpv-noise .ol-cpv-mark,
.ol-parts tr.ol-cpv-outscored .ol-cpv-mark {
  color: var(--token-color-text-tertiary);
}

.ol-file-i {
  display: inline-flex;
  color: var(--token-color-text-tertiary);
}

.ol-docs > .ic {
  color: var(--token-color-text-tertiary);
}

/* ------------------------------------------------------------ settings */

/* Their activity card: the portal's mark, the name and state, the timing,
   and the full-width «Sync now» with `Zap` under them. */
.os-act-head {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  padding: var(--token-space-4);
}

.os-act-id {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  min-width: 0;
}

.os-act-mark {
  flex: none;
  margin-top: var(--token-gap-hair);
}

.os-activity-error {
  border-color: var(--token-color-state-crit-text);
}

.os-activity-running {
  border-color: var(--token-color-accent-fill);
}

.os-activity .os-runs-h {
  display: flex;
  justify-content: space-between;
  margin: 0;
  padding: var(--token-space-2) var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  background: var(--token-color-surface-inset);
  font-size: var(--token-fs-2xs);
  font-weight: var(--token-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

/* One run: what it did, and their result glyph that opens the details. */
.os-run {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-2);
}

.os-run > .os-what {
  flex: 1 1 auto;
  min-width: 0;
}

.os-run-d {
  position: relative;
  flex: none;
}

.os-run-i {
  display: inline-flex;
  padding: var(--token-space-1);
  border-radius: var(--token-radius-pill);
  list-style: none;
  cursor: help;
}

.os-run-i::-webkit-details-marker {
  display: none;
}

.os-run-i:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
}

.os-run-running .os-run-i {
  color: var(--token-color-accent-text);
}

.os-run-completed .os-run-i {
  color: var(--token-color-state-ok-text);
}

.os-run-completed_with_errors .os-run-i {
  color: var(--token-color-state-warn-text);
}

.os-run-stopped .os-run-i {
  color: var(--token-color-text-tertiary);
}

.os-run-failed .os-run-i {
  color: var(--token-color-state-crit-text);
}

.os-run-pop {
  position: absolute;
  right: 0;
  z-index: var(--token-z-sticky);
  width: min(calc(var(--token-layout-field-max) - var(--token-space-5)), calc(100vw - var(--token-space-8)));
  padding: var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.os-run-pop > p {
  margin: 0 0 var(--token-space-1);
}

.os-run-state {
  font-weight: var(--token-weight-medium);
  color: var(--token-color-text-primary);
}

.os-empty.crit {
  color: var(--token-color-state-crit-text);
}

/* Their sliders: the label and the value, the track, its two ends. */
.os-slider {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.os-slider-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--token-space-3);
}

.os-slider-v {
  min-width: var(--token-space-10);
  padding: var(--token-space-1) var(--token-space-2);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  text-align: center;
}

.os-range {
  width: 100%;
  height: var(--token-space-5);
  margin: 0;
  background: transparent;
  accent-color: var(--token-color-accent-fill);
  cursor: pointer;
  appearance: none;
}

.os-range::-webkit-slider-runnable-track {
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
}

.os-range::-moz-range-track {
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-surface-sunken);
}

.os-range::-moz-range-progress {
  height: var(--token-space-2);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-fill);
}

.os-range::-webkit-slider-thumb {
  width: var(--token-space-5);
  height: var(--token-space-5);
  margin-top: calc((var(--token-space-2) - var(--token-space-5)) / 2);
  border: var(--token-border-thick) solid var(--token-color-accent-fill);
  border-radius: 50%;
  background: var(--token-color-surface-raised);
  appearance: none;
}

.os-range::-moz-range-thumb {
  width: var(--token-space-4);
  height: var(--token-space-4);
  border: var(--token-border-thick) solid var(--token-color-accent-fill);
  border-radius: 50%;
  background: var(--token-color-surface-raised);
}

.os-range:focus-visible {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: var(--token-space-1);
}

.os-slider-ends {
  display: flex;
  justify-content: space-between;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.os-sep {
  margin-top: var(--token-space-5);
  padding-top: var(--token-space-5);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

/* «Детальні налаштування підключень»: a tab per connector, its mark and
   name, one panel at a time — radios the stylesheet reads. */
.os-tabs {
  display: grid;
  grid-template-columns: repeat(var(--os-tab-n, 3), minmax(0, 1fr));
  gap: var(--token-space-1);
}

.os-tabs-1 {
  --os-tab-n: 1;
}

.os-tabs-2 {
  --os-tab-n: 2;
}

.os-tabs-4 {
  --os-tab-n: 4;
}

.os-tabs-5 {
  --os-tab-n: 5;
}

.os-tabs-6 {
  --os-tab-n: 6;
}

.os-tabs-7 {
  --os-tab-n: 7;
}

.os-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--token-space-2);
  min-width: 0;
  padding: var(--token-space-2) var(--token-space-3);
  border-radius: var(--token-radius-sm);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
  cursor: pointer;
}

.os-tab .src-mark {
  width: var(--token-space-5);
  height: var(--token-space-5);
}

.os-tab > span:last-child {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.os-tab-r:checked + .os-tab {
  background: var(--token-color-surface-raised);
  box-shadow: inset 0 0 0 var(--token-border-hair) var(--token-color-border-strong);
  color: var(--token-color-text-primary);
}

.os-tab-r:focus-visible + .os-tab {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
}

.os-tab-panel {
  display: none;
  grid-column: 1 / -1;
  padding-top: var(--token-space-4);
}

.os-tabs:has(#os-tab-prozorro:checked) .os-tab-panel-prozorro,
.os-tabs:has(#os-tab-ted:checked) .os-tab-panel-ted,
.os-tabs:has(#os-tab-ungm:checked) .os-tab-panel-ungm,
.os-tabs:has(#os-tab-ec_ft:checked) .os-tab-panel-ec_ft,
.os-tabs:has(#os-tab-world_bank:checked) .os-tab-panel-world_bank,
.os-tabs:has(#os-tab-rss:checked) .os-tab-panel-rss,
.os-tabs:has(#os-tab-undp:checked) .os-tab-panel-undp {
  display: block;
}

.os-conn-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--token-space-3);
}

.os-conn-head h3 {
  margin: 0;
  font-size: var(--token-fs-md);
}

.os-conn-head .grow {
  flex: 1 1 auto;
}

.os-conn > .os-body {
  padding: var(--token-space-4) 0 0;
}

.os-conn-foot {
  padding-top: var(--token-space-3);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.os-conn-foot:empty {
  display: none;
}

.os-save {
  display: flex;
  justify-content: flex-end;
}

/* Their keyword chips: the term opens its box, the `X` takes it off. */
.os-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--token-gap-hair);
}

.os-tag-x {
  display: inline-flex;
  align-items: center;
  padding: var(--token-gap-hair);
  border: 0;
  border-radius: var(--token-radius-sm);
  background: none;
  color: var(--token-color-text-tertiary);
  cursor: pointer;
}

.os-tag-x:hover,
.os-tag-x:has(input:focus-visible) {
  color: var(--token-color-state-crit-text);
}

.os-tag:has(.os-tag-x input:checked) .os-chip > summary {
  text-decoration: line-through;
  opacity: 0.55;
}

.os-tag:has(.os-tag-x input:checked) .os-tag-x {
  color: var(--token-color-state-crit-text);
}

.os-tag-new .os-chip-t {
  border-style: dashed;
}

.os-kw-add {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.os-kw-add > .field {
  flex: 1 1 calc(var(--token-space-24) * 2);
}

/* --------------------------------------------------------- settings · st */
.st-section-head {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-1);
}

.st-section-head h2 {
  margin: 0;
  font-size: var(--token-fs-xl);
}

.st-section-head .st-lede {
  margin: 0;
}

/* Their «Configured by» chips: the variable in the accent, a legacy source
   in amber, the default quiet. */
.st-src {
  display: inline-block;
  padding: var(--token-gap-hair) var(--token-space-2);
  border-radius: var(--token-radius-sm);
  font-family: var(--token-font-mono);
  font-size: var(--token-fs-xs);
}

.st-src-env {
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

.st-src-legacy {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.st-src-default {
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-secondary);
}

/* Their check result: `CheckCircle2` or `XCircle`, in its state's frame. */
.st-check {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  margin: var(--token-space-4);
  padding: var(--token-space-3) var(--token-space-4);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

.st-check-ok {
  border-color: var(--token-color-accent-fill);
  background: var(--token-color-accent-wash);
}

.st-check-ok > .ic {
  color: var(--token-color-accent-text);
}

.st-check-fail {
  border-color: var(--token-color-state-crit-text);
  background: var(--token-color-state-crit-bg);
}

.st-check-fail > .ic {
  color: var(--token-color-state-crit-text);
}

.st-check-b > p {
  margin: 0;
}

.st-check-t {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-2);
  font-weight: var(--token-weight-medium);
}

.st-warn-title {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.st-warn-title > .ic {
  color: var(--token-color-state-warn-text);
}

/* Their row menu: the glyphs beside each word. */
.st-more .menu a {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.st-merge .field.opp-search {
  width: 100%;
  margin-bottom: var(--token-space-2);
}

.st-merge-list {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.st-merge-list > [hidden] {
  display: none;
}

/* What the script shows or hides by the `hidden` attribute, over the display
   these rules give them: the narrowing boxes, the «Шукати» and «Зберегти» a
   scripted page does not need, «Додати», the filtered-out options. */
[data-filter-show][hidden],
[data-live-search-hide][hidden],
[data-auto-submit-hide][hidden],
[data-tag-add][hidden],
[data-tag-none][hidden],
[data-filter-text][hidden],
[data-filter-empty][hidden] {
  display: none;
}

/* The queue's Status column holds their pill now, not two squares, a little
   wider — 120, the pill and a step before the score; a long status and the
   Deadline column's ActionabilityBadge wrap inside their pill rather than
   spilling into the next column. */
.tr-opp .opp-card table.fixed col[data-col="status"] {
  width: calc(var(--token-space-24) + var(--token-space-6));
}

.opp-st-menu > summary.badge,
.opp-act > .badge {
  max-width: 100%;
  padding-block: var(--token-gap-hair);
  white-space: normal;
  text-align: left;
}

/* The toolbar's last menus open to the left: at the far end of the row a
   menu opening rightwards runs off the page. */
.opp-tools > .grow ~ .fchip-menu .menu {
  left: auto;
  right: 0;
}

/* The stacked rows above, by the table's own width too (see `.scroller.stack`
   in app.css): a narrow card in a wide window is cards as well. */
@container (max-width: 860px) {
  .od-leads .scroller.stack tr,
  .op-table .scroller.stack tr,
  .st-table .scroller.stack tr {
    padding: var(--token-space-3) var(--token-space-4);
  }

  .od-leads .scroller.stack td,
  .op-table .scroller.stack td,
  .st-table .scroller.stack td,
  .od-leads .scroller.stack td:first-child,
  .op-table .scroller.stack td:first-child,
  .st-table .scroller.stack td:first-child,
  .od-leads .scroller.stack td:last-child,
  .op-table .scroller.stack td:last-child,
  .st-table .scroller.stack td:last-child {
    height: auto;
    padding: var(--token-space-1) 0;
  }

  .od-leads .scroller.stack td[data-label='']::before,
  .op-table .scroller.stack td[data-label='']::before,
  .st-table .scroller.stack td[data-label='']::before {
    content: none;
  }

  .od-leads .scroller.stack td > .cv,
  .op-table .scroller.stack td > .cv,
  .st-table .scroller.stack td > .cv {
    min-width: 0;
    max-width: 70%;
  }

  .od-leads .scroller.stack td .cl1,
  .op-table .scroller.stack td .cl1 {
    white-space: normal;
  }

  .st-table .scroller.stack tbody tr:last-child,
  .od-leads .scroller.stack tbody tr:last-child,
  .op-table .scroller.stack tbody tr:last-child {
    border-bottom: 0;
  }
}

/* On a phone the criteria table's two fixed columns left the criterion
   itself 86px, «Ключові слова конектора» a word a line: there they take
   what their figures need. */
@media (max-width: 640px) {
  table.ol-parts th[data-col="points"],
  table.ol-parts th[data-col="share"] {
    width: auto;
  }
}

/* Screen-shaped rules for a tender's remaining screens, matched to the
   approved canvas. Tokens only; one file per group so parallel work does not
   collide.

   Sources, Activity and Settings (tabs), Readiness, New tender and the audit
   Comparison. None has a board of its own; each is built from the elements of
   its reference board — ProposalA's head, drop area and card table,
   RequirementsA's table, FormatsA's drawer fields, TenderOverviewA's cards and
   warning band, AuditA-Plex's head, verdict band and parts, Main's page head.
   Every rule is scoped under `.tt`, the root these views emit, and the `.tw-*`
   pieces they share with the work tabs keep their own rules in
   tenders-work.css. */

/* ------------------------------------------------------------ the frame */
.tt {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-3) + var(--token-layout-hair-gap));
  padding-top: var(--token-layout-hair-gap);
  min-width: 0;
}

.tt > * {
  margin: 0;
}

.tt > .seg {
  align-self: flex-start;
}

.tt .tw-prop-head .btn {
  gap: var(--token-space-2);
}

.tt .tw-prop-head > form.inline {
  margin: 0;
}

.tt .btn[disabled] {
  opacity: 0.5;
  cursor: default;
}

/* A primary act that cannot be taken yet reads as a quiet button with its
   word still legible, not as a faded accent. */
.tt .btn-primary[disabled] {
  opacity: 1;
  border-color: var(--token-color-border-subtle);
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-tertiary);
}

.tt-quiet {
  color: var(--token-color-text-tertiary);
}

/* ------------------------------------------------------------ a notice
   TenderOverviewA's warning band: the state's ground, its sign and a medium
   title in the state's ink, the sentence in the page's ink under it. */
.tt-notice {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  padding: var(--token-space-4) var(--token-space-5);
  border: var(--token-border-hair) solid transparent;
  border-radius: var(--token-radius-md);
  font-size: var(--token-fs-sm);
  line-height: 1.5;
}

.tt-notice > p {
  margin: 0;
}

.tt-notice-warning {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
}

.tt-notice-critical {
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tt-notice-info {
  background: var(--token-color-state-info-bg);
  color: var(--token-color-state-info-text);
}

.tt-notice-ok {
  background: var(--token-color-state-ok-bg);
  color: var(--token-color-state-ok-text);
}

.tt-notice-title {
  display: flex;
  align-items: center;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  font-weight: var(--token-weight-medium);
}

.tt-notice-icon {
  width: var(--token-space-4);
  height: var(--token-space-4);
  flex: none;
}

.tt-notice-text,
.tt-notice-act {
  padding-left: calc(var(--token-space-4) + var(--token-space-2) + var(--token-gap-hair));
  color: var(--token-color-text-primary);
}

.tt-notice-act a {
  color: var(--token-color-accent-text);
  text-decoration: none;
}

.tt-notice-act a:hover {
  text-decoration: underline;
}

.tt-notice-act form.inline {
  margin: 0;
}

/* ------------------------------------------------------- a card and head
   TenderOverviewA's «Критерії оцінки»: 14 by 16, the name in medium, a
   quiet 13px line at the right, one rule beneath. */
.tt-card {
  background: var(--token-color-surface-raised);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
}

.tt-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--token-space-3);
  padding: calc(var(--token-space-3) + var(--token-layout-hair-gap)) var(--token-space-4);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tt-card-title {
  flex: 1 1 auto;
  min-width: min(var(--token-layout-panel-min) / 2, 100%);
  margin: 0;
  font-family: var(--token-font-body);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  line-height: 1.5;
  letter-spacing: 0;
}

.tt-card-meta {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
  text-align: right;
}

/* ------------------------------------------------------------ the table
   ProposalA's list: a quiet 12px header on one rule, rows of 13px text at
   least 40 tall, 12 in from each side, a rule under each. */
.tt-t {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: var(--token-fs-xs-plus);
}

.tt-t th,
.tt-t th:first-child,
.tt-t th:last-child {
  height: auto;
  padding: calc(var(--token-space-2) + var(--token-border-hair)) var(--token-space-3);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  background: none;
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-regular);
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--token-color-text-tertiary);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tt-t td,
.tt-t td:first-child,
.tt-t td:last-child {
  height: var(--token-space-10);
  padding: var(--token-space-1) var(--token-space-3);
  border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  vertical-align: middle;
}

.tt-t th.tw-num,
.tt-t td.tw-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.tt-t tbody tr:last-child > td {
  border-bottom: 0;
}

.tt-t tbody tr:hover > td {
  background: none;
}

.tt-c-center {
  text-align: center;
}

.tt-t th.tt-c-center {
  text-align: center;
}

.tt-c-end {
  text-align: right;
}

.tt-t form.inline {
  display: inline-flex;
  margin: 0;
}

.tt .badge {
  white-space: nowrap;
}

/* ------------------------------------------------------------- sources */
.tt-src .tw-card {
  overflow: visible;
}

.tt-src-t .tt-c-remark {
  width: var(--token-layout-card-min);
}

.tt-src-t .tt-c-state {
  width: calc(var(--token-space-24) + var(--token-space-8));
}

.tt-src-t .tt-c-file {
  width: calc(var(--token-layout-col-duration) + var(--token-layout-item-pad-x));
}

.tt-src-t .tt-c-docs {
  width: var(--token-space-24);
}

.tt-src-t .tt-c-when {
  width: calc(var(--token-layout-col-duration) + var(--token-space-5));
}

.tt-src-t .tt-c-switch {
  width: calc(var(--token-space-16) + var(--token-space-4));
}

.tt-src-t .tt-c-menu {
  /* The row's download and its «⋯», side by side. */
  width: calc(var(--token-layout-col-tick) + var(--token-space-6) + var(--token-space-1));
}

.tt-src-t .tt-a-menu {
  white-space: nowrap;
}

.tt-name {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--token-color-text-primary);
}

/* A page that gave attachments sits on the inset ground, as a folder does. */
.tt-src-t tr.is-parent > td {
  background: var(--token-color-surface-inset);
}

.tt-src-t tr.is-nested .tt-a-name {
  padding-left: calc(var(--token-space-6) + var(--token-layout-pill-gap));
}

.tt-remark {
  flex-wrap: wrap;
  min-width: 0;
}

.tt-src-t .tt-a-file,
.tt-src-t .tt-a-when {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tt-a-switch .tw-switch {
  vertical-align: middle;
}

/* The row's «⋯» and its menu of forms; the download beside it, the same square. */
.tt-a-menu > a.tt-dl,
.tt-more > summary.tt-dots {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--token-space-6) + var(--token-space-1));
  height: calc(var(--token-space-6) + var(--token-space-1));
  border-radius: var(--token-radius-sm);
  color: var(--token-color-text-secondary);
  list-style: none;
  cursor: pointer;
}

.tt-more > summary.tt-dots::-webkit-details-marker {
  display: none;
}

.tt-a-menu > a.tt-dl:hover,
.tt-more > summary.tt-dots:hover,
.tt-more[open] > summary.tt-dots {
  background: var(--token-color-surface-sunken);
  color: var(--token-color-text-primary);
}

.tt-dots-icon {
  width: var(--token-space-4);
  height: var(--token-space-4);
}

.tt-more .menu {
  z-index: var(--token-z-sticky);
  min-width: calc(var(--token-layout-field-basis) + var(--token-space-6));
  text-align: left;
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
}

.tt-more .menu form {
  display: block;
  margin: 0;
}

.tt-menu-form form {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
  padding: var(--token-space-2) var(--token-space-3);
}

.tt-menu-form .field {
  flex: none;
  max-width: none;
}

.tt-menu-form .field > .lbl {
  font-size: var(--token-fs-xs);
}

.tt-menu-form .btn {
  align-self: flex-end;
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
}

.tt-menu-danger .menu-item {
  color: var(--token-color-state-crit-text);
}

/* «Додати посилання»: the drop area's pop, holding a field instead. */
.tt-pop .tw-upload-pop .field {
  flex: none;
  max-width: none;
}

.tt-pop .tickbox {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

/* Unsupported and excluded rows, under a folder-style line of their own. */
.tt-skipped {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tt-skipped > summary {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  min-height: var(--token-space-10);
  padding: 0 var(--token-space-3);
  background: var(--token-color-surface-inset);
  font-size: var(--token-fs-xs-plus);
  list-style: none;
  cursor: pointer;
}

.tt-skipped:not([open]) > summary {
  border-bottom-left-radius: var(--token-radius-md);
  border-bottom-right-radius: var(--token-radius-md);
}

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

.tt-skipped-name {
  display: flex;
  align-items: center;
  gap: var(--token-space-1);
  color: var(--token-color-text-primary);
}

.tt-skipped-name::before {
  content: '▸';
  width: var(--token-space-2);
  font-size: var(--token-fs-2xs);
  color: var(--token-color-text-secondary);
}

.tt-skipped[open] .tt-skipped-name::before {
  content: '▾';
}

.tt-skipped > summary:hover .tt-skipped-name {
  color: var(--token-color-accent-text);
}

.tt-skipped .tt-t {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

/* A narrow screen: every source a block of its own — the name and its acts
   on the first line, what needs attention under it, the facts on the last. */
@media (max-width: 1100px) {
  .tt .tw-prop-head {
    flex-wrap: wrap;
  }

  .tt .tw-prop-head > .grow {
    flex-basis: 100%;
  }

  .tt .tw-prop-head > details:first-of-type .tw-upload-pop {
    left: 0;
    right: auto;
  }

  .tt .tw-upload-pop {
    width: min(var(--token-layout-aside), calc(100vw - var(--token-space-10)));
  }

  .tt-src-t,
  .tt-src-t tbody {
    display: block;
  }

  .tt-src-t colgroup,
  .tt-src-t thead {
    display: none;
  }

  .tt-src-t tr {
    display: grid;
    grid-template-columns: auto auto auto minmax(0, 1fr) auto auto;
    grid-template-areas:
      'name name name name switch menu'
      'remark remark remark remark remark remark'
      'state file docs when when when';
    align-items: center;
    gap: var(--token-space-1) var(--token-space-3);
    padding: var(--token-space-3);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tt-src-t tbody tr:last-child {
    border-bottom: 0;
  }

  .tt-src-t tr.is-parent {
    background: var(--token-color-surface-inset);
  }

  .tt-src-t tr.is-parent > td {
    background: none;
  }

  .tt-src-t tr.is-nested {
    padding-left: calc(var(--token-space-6) + var(--token-layout-pill-gap));
  }

  .tt-src-t td,
  .tt-src-t td:first-child,
  .tt-src-t td:last-child {
    display: block;
    height: auto;
    padding: 0;
    border: 0;
    min-width: 0;
  }

  .tt-src-t tr.is-nested .tt-a-name {
    padding-left: 0;
  }

  .tt-a-name {
    grid-area: name;
  }

  .tt-a-remark {
    grid-area: remark;
  }

  .tt-a-remark:has(> .tt-remark > .tw-dash:only-child) {
    display: none;
  }

  .tt-a-state {
    grid-area: state;
  }

  .tt-a-file {
    grid-area: file;
  }

  .tt-a-docs {
    grid-area: docs;
  }

  .tt-src-t td.tt-a-docs {
    text-align: left;
    color: var(--token-color-text-tertiary);
  }

  .tt-a-docs::before {
    content: attr(data-label) ' ';
  }

  .tt-a-when {
    grid-area: when;
  }

  .tt-a-switch {
    grid-area: switch;
  }

  .tt-a-menu {
    grid-area: menu;
  }
}

/* ------------------------------------------------------------ activity
   RequirementsA's table: when, who, what, and the detail, in 13px Plex. */
.tt-act-t .tt-c-when {
  width: var(--token-layout-col-when);
}

.tt-act-t .tt-c-who {
  width: var(--token-layout-field-basis);
}

.tt-act-t .tt-c-what {
  width: calc(var(--token-layout-card-min) + var(--token-space-4));
}

.tt-act-t td {
  padding-top: calc(var(--token-space-2) + var(--token-border-hair));
  padding-bottom: calc(var(--token-space-2) + var(--token-border-hair));
}

.tt-when {
  color: var(--token-color-text-secondary);
  font-variant-numeric: tabular-nums;
}

/* A two-line cut of a long detail; the whole of it is in the title. */
.tt-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--token-color-text-secondary);
  overflow-wrap: break-word;
}

/* The log's card never makes the page scroll sideways. */
.tt-scroll {
  max-width: 100%;
}

/* Narrower, each entry is two lines — when, who and what, and the detail
   under them — rather than a table whose detail column had to be scrolled
   to: a sideways scroll hid exactly the file names the log is read for. */
@media (max-width: 1100px) {
  .tt-act-t,
  .tt-act-t thead,
  .tt-act-t tbody {
    display: block;
    width: 100%;
  }

  .tt-act-t colgroup {
    display: none;
  }

  .tt-act-t tr {
    display: grid;
    grid-template-columns: var(--token-layout-col-when) minmax(0, 1fr) minmax(0, 1fr);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tt-act-t tbody tr:last-child {
    border-bottom: 0;
  }

  .tt-act-t th,
  .tt-act-t th:first-child,
  .tt-act-t th:last-child,
  .tt-act-t td,
  .tt-act-t td:first-child,
  .tt-act-t td:last-child {
    height: auto;
    border-bottom: 0;
  }

  .tt-act-t th:last-child {
    display: none;
  }

  .tt-act-t td:last-child {
    grid-column: 1 / -1;
    padding-top: 0;
  }
}

/* ------------------------------------------------------- forms in a card
   The Formats drawer's fields — label above, 13px medium in the secondary
   ink, 6 over a 40px control — laid in a card the Overview board's way. */
.tt-form {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.tt-fields {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--token-space-5);
  padding: var(--token-space-5) var(--token-space-4);
}

.tt-fields > * {
  min-width: 0;
}

.tt-f-full {
  grid-column: 1 / -1;
}

.tt-fields .field,
.tt-fields .field-tall {
  flex: none;
  width: 100%;
  max-width: none;
  margin: 0;
}

.tt-fields .control {
  display: flex;
  align-items: stretch;
  width: 100%;
  margin: 0;
}

.tt-fields .control > select {
  width: 100%;
}

.tt-fields .field-tall textarea {
  min-height: calc(var(--token-layout-control-h) * 3);
  line-height: 1.5;
}

.tt-field-note {
  margin: calc(var(--token-space-1) * 1.5) 0 0;
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

/* Why the save was refused, under the field it is about. */
.tt-error {
  margin: var(--token-space-1) 0 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-state-crit-text);
}

.tt-card-foot {
  display: flex;
  justify-content: flex-end;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  padding: var(--token-space-4);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

.tt-card-foot .btn {
  margin: 0;
}

/* The danger zone: one row — what it does, and the ghost button. */
.tt-danger-row {
  display: flex;
  align-items: center;
  gap: var(--token-space-4);
  padding: var(--token-space-4);
}

.tt-danger-row p {
  margin: 0;
}

.tt-danger-title {
  font-size: var(--token-fs-sm);
}

.tt-danger-text {
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.tt-confirm {
  position: relative;
}

.tt-confirm > summary {
  list-style: none;
  cursor: pointer;
  color: var(--token-color-text-primary);
}

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

.tt-confirm[open] > summary {
  border-color: var(--token-color-state-crit-text);
}

.tt-confirm-pop {
  position: absolute;
  right: 0;
  top: calc(100% + var(--token-space-2));
  z-index: var(--token-z-sticky);
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  width: min(var(--token-layout-aside), calc(100vw - var(--token-space-10)));
  padding: var(--token-space-4);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-6) color-mix(in srgb, var(--token-color-text-primary) 12%, transparent);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
}

.tt-confirm-pop p,
.tt-confirm-pop form {
  margin: 0;
}

.tt-confirm-pop form {
  display: flex;
  justify-content: flex-end;
}

.tt-btn-danger {
  border-color: var(--token-color-state-crit-text);
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

@media (max-width: 1100px) {
  .tt-fields {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ----------------------------------------------------------- readiness
   AuditA-Plex: the head with its acts on the right, 18 between blocks, the
   four parts across, notices and the sources that need a decision. */
.tt.tw-audit {
  gap: var(--token-layout-block-gap);
  padding-top: var(--token-space-1);
}

.tt .tw-audit-head > form.inline {
  margin: 0;
}

.tt .tw-audit-head .btn {
  font-size: var(--token-fs-sm);
}

.tt-ready .tw-part {
  justify-content: flex-start;
}

.tt-ready-t .tt-c-src {
  width: calc(var(--token-layout-panel-min) + var(--token-space-6));
}

.tt-ready-t .tt-c-state {
  width: calc(var(--token-space-24) + var(--token-space-8));
}

.tt-ready-t .tt-c-act {
  width: calc(var(--token-space-24) + var(--token-space-8));
}

.tt-ready-t td {
  padding-top: calc(var(--token-space-2) + var(--token-border-hair));
  padding-bottom: calc(var(--token-space-2) + var(--token-border-hair));
}

.tt-t .btn {
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-primary);
}

.tt-clamp.tt-ink {
  color: var(--token-color-text-primary);
}

.tt-sub {
  display: block;
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

.tt-card.tt-scroll > .tt-t {
  border-radius: 0 0 var(--token-radius-md) var(--token-radius-md);
}

@media (max-width: 1100px) {
  .tt .tw-audit-head {
    flex-wrap: wrap;
  }

  .tt .tw-audit-head > .grow {
    flex-basis: 100%;
  }

  .tt-card.tt-scroll {
    overflow-x: auto;
  }

  .tt-ready-t {
    min-width: calc(var(--token-layout-panel-min) * 2 + var(--token-space-24));
  }

  .tt-ready-t .tt-c-src {
    width: calc(var(--token-layout-col-action) + var(--token-space-2));
  }
}

@media (max-width: 900px) {
  .tt .tw-parts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tt .tw-part:nth-child(3) {
    border-left: 0;
  }

  .tt .tw-part:nth-child(n + 3) {
    border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  }
}

/* ---------------------------------------------------------- new tender
   The front page's head — the frame's sides and 36 above, a 13px line over a
   30px heading, 28 to what follows — over one card of the Overview kind. */
.wrap:has(> .tt-page) {
  padding-top: calc(var(--token-space-8) + var(--token-space-1));
}

.tt-page {
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-6) + var(--token-space-1));
  min-width: 0;
  line-height: 1.5;
}

.tt-page > * {
  margin: 0;
}

.tt-page-head h1 {
  margin: 0;
  font-size: calc(var(--token-fs-h1) + var(--token-gap-hair));
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.tt-eyebrow {
  margin: 0 0 calc(var(--token-space-1) * 1.5);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-tertiary);
}

.tt-eyebrow a {
  color: var(--token-color-accent-text);
  text-decoration: none;
}

.tt-new-card {
  width: 100%;
  max-width: calc(var(--token-layout-aside) + var(--token-layout-panel-min));
}

.tt-fields-one {
  grid-template-columns: minmax(0, 1fr);
}

.tt-card-text {
  margin: 0;
  padding: var(--token-space-5) var(--token-space-4);
  font-size: var(--token-fs-sm);
  line-height: 1.5;
}

/* ---------------------------------------------------------- comparison
   AuditA-Plex: the head, the verdict band with the figure's movement on its
   raised side, the four parts, then the report's card tables — two across
   where they pair, as the Overview board sets its two cards. */
.tt-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--token-space-5);
  align-items: start;
}

.tt-pair > * {
  min-width: 0;
}

.tt-cmp .tw-verdict-score .tw-score-label:last-child {
  color: var(--token-color-text-tertiary);
}

.tt-part-sub {
  font-size: var(--token-fs-xs);
  line-height: 1.5;
  color: var(--token-color-text-tertiary);
}

.tt-cmp-t .tt-c-param {
  width: var(--token-layout-field-basis);
}

.tt-cmp-t .tt-c-change {
  width: calc(var(--token-space-24) + var(--token-space-10));
}

.tt-cmp-t .tt-c-sev {
  width: calc(var(--token-space-24) + var(--token-space-2));
}

.tt-cmp-t .tt-c-status {
  width: calc(var(--token-space-24) + var(--token-space-10) + var(--token-space-2));
}

.tt-cmp-t td {
  padding-top: calc(var(--token-space-2) + var(--token-border-hair));
  padding-bottom: calc(var(--token-space-2) + var(--token-border-hair));
}

.tt-ref {
  font-family: var(--token-font-mono);
  font-size: calc(var(--token-fs-xs) + var(--token-border-hair) / 2);
  white-space: nowrap;
}

@media (max-width: 1100px) {
  .tt-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  .tt .tw-verdict {
    flex-direction: column;
  }

  .tt .tw-verdict-score {
    flex-basis: auto;
    border-left: 0;
    border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  }
}

/* ---- Sources, Overview and readiness: the original's states (parity) ---- */

/* The counters' inks: completed green, processing amber, failed red, documents blue. */
.tt-count b {
  font-weight: var(--token-weight-medium);
}
.tt-count.tone-ok b,
.tw-part-figure.tone-ok {
  color: var(--token-color-state-ok-text);
}
.tt-count.tone-warning b,
.tw-part-figure.tone-warning {
  color: var(--token-color-state-warn-text);
}
.tt-count.tone-critical b,
.tw-part-figure.tone-critical {
  color: var(--token-color-state-crit-text);
}
.tt-count.tone-info b,
.tw-part-figure.tone-info {
  color: var(--token-color-state-info-text);
}

/* An excluded source is drawn faded, as the original's row is. */
.tt-src-t tr.is-excluded > td {
  opacity: 0.5;
}

/* The tree: a chevron that opens a row's children, and the deeper levels' indent. */
.tt-chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--token-space-4);
  height: var(--token-space-4);
  margin-right: var(--token-space-1);
  color: var(--token-color-text-tertiary);
  vertical-align: middle;
}
.tt-chev:hover {
  color: var(--token-color-text-primary);
}
.tt-chev-icon {
  width: var(--token-space-3);
  height: var(--token-space-3);
}
.tt-chev.is-open .tt-chev-icon {
  transform: rotate(90deg);
}
.tt-src-t tr.depth-2 .tt-a-name {
  padding-left: calc(var(--token-space-10) + var(--token-layout-pill-gap));
}
.tt-src-t tr.depth-3 .tt-a-name,
.tt-src-t tr.depth-4 .tt-a-name {
  padding-left: calc(var(--token-space-16) + var(--token-layout-pill-gap));
}
.tt-src-t tr.tt-ignored-row > td {
  padding: var(--token-space-1) var(--token-space-4);
  text-align: center;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}
.tt-src-t tr.tt-ignored-row a {
  color: inherit;
}

/* A Drive link resolved before it is added. */
.tt-drive {
  margin: var(--token-space-2) 0 0;
  font-size: var(--token-fs-xs);
}
.tt-drive.is-ok {
  color: var(--token-color-state-ok-text);
}
.tt-drive.is-error {
  color: var(--token-color-state-crit-text);
}

/* The readiness screen's bulk acceptance and the note over its blocked table. */
.tt-bulk .tt-notice-act {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}
.tt-ready .tt-foot-note {
  margin: 0;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
}

/* The failed-extraction banner: its raw error and its «×». */
.tt-notice .tt-block {
  display: block;
  margin-top: var(--token-space-1);
}
.tt-notice-act {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}
.tt-dismiss {
  margin-left: auto;
  border: 0;
  background: transparent;
  color: inherit;
  font-size: var(--token-fs-sm);
  cursor: pointer;
}

/* A control that exists but cannot be pressed now. */
.btn.is-disabled {
  opacity: 0.5;
  pointer-events: none;
}

/* The deadline countdown's ink: three days or fewer red, a week or fewer amber. */
.fact.tone-critical .fact-v,
.fact.tone-critical .fact-s {
  color: var(--token-color-state-crit-text);
}
.fact.tone-warning .fact-v,
.fact.tone-warning .fact-s {
  color: var(--token-color-state-warn-text);
}
.fact-v.ov-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-1);
}

/* The status, the procurement id and the jurisdiction; the buyer under them. */
.ov-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
  margin: var(--token-space-2) 0;
}
.ov-meta-item,
.ov-entity {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
}
.ov-entity {
  margin: 0 0 var(--token-space-3);
  font-size: var(--token-fs-sm);
}
.ov-pill.is-unknown {
  padding: var(--token-space-1) var(--token-space-3);
  border: var(--token-border-hair) dashed var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}
.ov-source {
  margin-top: var(--token-space-2);
}

/* A long text: its first 280 characters, and the rest behind «Показати більше». */
.ov-long:has(> details[open]) > .ov-preview {
  display: none;
}
.ov-more-toggle > summary {
  list-style: none;
  cursor: pointer;
  font-size: var(--token-fs-xs);
  color: var(--token-color-accent-text);
}
.ov-more-toggle > summary::-webkit-details-marker {
  display: none;
}
.ov-more-toggle .when-open,
.ov-more-toggle[open] .when-closed {
  display: none;
}
.ov-more-toggle[open] .when-open {
  display: inline;
}
.ov-more-toggle[open] > summary {
  order: 2;
}

/* The date & time editor: day, month, year; hour and minute; the stated zone. */
.tt-date-editor {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}
.tt-date-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--token-space-2);
}
.tt-date-zone {
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-secondary);
}

/* =====================================================================
   Tenders — the original's glyphs and behaviours on the shell, the tender
   list and dashboard, the workspace head and its Overview, Sources,
   Requirements and readiness screens (parity A, @strim/web 2.41 icons).

   Only placement lives here: the glyphs are `components/icon.ts`, sized by
   `.ic-*` and coloured by the text they sit in.
   ===================================================================== */

/* A glyph set inline before its words: one small step of air after it. */
.cell-when > .ic,
.cell-spend > .ic,
.dash-due > .ic,
.ws-fact > .ic,
.ws-back > .ic,
.ov-mark > .ic,
.ov-edit .ic,
.fact-v > .ic,
.ov-chip > .ic,
.ov-entity > .ic,
.ov-cname > .ic,
.ov-card-head h2 > .ic,
.tt-card-title > .ic,
.tw-mand > .ic,
.tw-weight-line > .ic,
.tw-weight p > .ic,
.tw-empty > .ic,
.menu-item > .ic,
.menu a > .ic,
.tt-drive > .ic,
.tabs a > .ic,
.dropdown .menu-item .tt-quiet {
  margin-right: var(--token-space-1);
}

.fact-v a > .ic {
  margin-left: var(--token-space-1);
}

/* The workspace tabs: the glyph in the tab's own ink, quieter until current. */
.tabs a > .ic {
  color: var(--token-color-text-tertiary);
}

.tabs a[aria-current='page'] > .ic {
  color: currentColor;
}

/* The board notice's glyph box holds a Lucide icon at its own size. */
span.tt-notice-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

span.tt-notice-icon > .ic {
  width: 100%;
  height: 100%;
}

/* Google's «G» and Drive's mark are shapes, not strokes. */
.ic[data-icon='GoogleG'] {
  fill: currentColor;
  stroke: none;
}

.ic[data-icon='GoogleDrive'] {
  stroke-width: 1.8;
}

/* ---- the shell's banners over the page ----
   The model-access and outage banners sit above the page's own head; the
   Overview's head is drawn full-bleed from the top of the page and would
   slide under them, so after a banner it starts where the banner ends. */

.wrap > .banner,
.wrap > .outage-region:not(:empty) {
  margin-bottom: var(--token-space-4);
}

.wrap > .banner ~ .ws-head.ws-full,
.wrap > .outage-region:not(:empty) ~ .ws-head.ws-full {
  margin-top: 0;
}

/* ---- dashboard ---- */

.dash-recent-head {
  padding: var(--token-space-3) var(--token-layout-cell-pad-x) 0;
}

.dash-empty {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--token-space-2);
  color: var(--token-color-text-tertiary);
}

.cell-spend {
  white-space: nowrap;
}

/* ---- new tender, step two: Globe in its circle ---- */

.tt-new-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--token-size-icon-xl) + var(--token-space-4));
  height: calc(var(--token-size-icon-xl) + var(--token-space-4));
  margin: 0 0 var(--token-space-3);
  border-radius: var(--token-radius-pill);
  background: var(--token-color-accent-wash);
  color: var(--token-color-accent-text);
}

/* ---- Overview ---- */

.ov-group {
  margin: 0;
  padding: var(--token-space-3) var(--token-space-4) var(--token-space-1);
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.ov-section {
  margin: var(--token-space-6) 0 var(--token-space-3);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--token-color-text-tertiary);
}

.ov-running {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.ov-mark.is-human > .ic {
  color: var(--token-color-state-ok-text);
}

.ov-mark.is-unsure > .ic {
  color: var(--token-color-state-warn-text);
}

.ov-mark:not(.is-human):not(.is-unsure) > .ic {
  color: var(--token-color-text-tertiary);
}

/* The date editor's two rows under Calendar «Дата» and Clock «Час». */
.tt-date-cap {
  display: flex;
  align-items: center;
  gap: var(--token-space-1);
  margin: var(--token-space-2) 0 var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tt-date-cap:first-of-type {
  margin-top: 0;
}

.tt-date-row input:disabled {
  opacity: 0.55;
}

/* ---- Sources ---- */

.tt-type {
  display: inline-flex;
  margin-right: var(--token-space-2);
  color: var(--token-color-text-tertiary);
  vertical-align: middle;
}

.tt-url-row {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.tt-pop .tw-upload-pop .tt-url-row .field {
  flex: 1 1 auto;
  min-width: 0;
}

/* The chevron, the type glyph and the name on one line; the name still
   ends in an ellipsis rather than pushing the row wider. */
.tt-src-t .tt-a-name {
  white-space: nowrap;
}

.tt-src-t .tt-a-name > .tt-name {
  display: inline-block;
  max-width: calc(100% - var(--token-space-10));
  vertical-align: middle;
}

.tt-url-lead {
  display: inline-flex;
  color: var(--token-color-text-tertiary);
}

.tt-empty-icon {
  display: block;
  margin-bottom: var(--token-space-2);
  color: var(--token-color-text-tertiary);
}

.tt-drop-always {
  padding: var(--token-space-4);
}

.field-pending {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

/* ---- Requirements ---- */

.tw-req-head {
  margin-bottom: var(--token-space-4);
}

.tw-search {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-2);
  color: var(--token-color-text-tertiary);
}

.tw-mand {
  color: var(--token-color-state-crit-text);
}

.tw-optional {
  color: var(--token-color-text-tertiary);
}

/* A post-award obligation: amber, as the original's select draws it. */
.tw-stage.is-contract > summary {
  background: var(--token-color-state-warn-bg);
  color: var(--token-color-state-warn-text);
  font-weight: var(--token-weight-medium);
}

.tw-stage .menu button:disabled {
  color: var(--token-color-text-tertiary);
  cursor: default;
}

/* ---- the readiness dialog ---- */

.tt-modal {
  position: fixed;
  inset: 0;
  /* Over the side column too, under the toasts. */
  z-index: calc(var(--token-z-skip) - 1);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--token-space-8) var(--token-space-4);
  overflow-y: auto;
}

.tt-modal-scrim {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--token-color-text-primary) 38%, transparent);
}

.tt-modal-card {
  position: relative;
  width: 100%;
  max-width: calc(var(--token-layout-max) * 0.62);
  padding: var(--token-layout-card-pad-y) var(--token-layout-card-pad-x);
  border-radius: var(--token-radius-lg);
  background: var(--token-color-surface-raised);
  box-shadow: 0 var(--token-space-2) var(--token-space-8) color-mix(in srgb, var(--token-color-text-primary) 22%, transparent);
}

.tw-audit-title h2 > .ic {
  margin-right: var(--token-space-2);
  color: var(--token-color-accent-text);
}

.tt-ready-blocked .tt-card-title > .ic {
  color: var(--token-color-state-crit-text);
}

.tt-ready-accepted .tt-card-title > .ic {
  color: var(--token-color-state-warn-text);
}

/* «Заблоковано»: the original's destructive button. */
.btn.btn-danger,
.btn.btn-danger:disabled {
  background: var(--token-color-state-crit-bg);
  border-color: color-mix(in srgb, var(--token-color-state-crit-text) 30%, transparent);
  color: var(--token-color-state-crit-text);
}

/* A button that is working: Loader2 before its words. */
.btn[aria-busy='true'] > .ic {
  margin-right: var(--token-space-1);
}

@media (max-width: 760px) {
  .tt-modal {
    padding: var(--token-space-4) var(--token-space-2);
  }
}

/* =====================================================================
   Tender Proposal, Audits, the audit report, the comparison, Activity and
   Settings — what the original draws there and the boards did not: its
   lucide glyphs, the muted excluded row, the red and yellow warning boxes,
   the live findings search. Tokens only; each rule names the element it
   serves (PARITY_ELEMENTS.md, part B).
   ===================================================================== */

/* ---- shared: a warning box with its glyph (AlertCircle, AlertTriangle, Info) */

.tw-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-2);
  margin: 0;
  padding: var(--token-space-2) var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-seg);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
}

.tw-alert > .ic {
  flex: none;
  margin-top: var(--token-layout-hair-gap);
}

.tw-alert-crit {
  border-color: color-mix(in srgb, var(--token-color-state-crit-text) 30%, transparent);
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

/* The limitations box: muted ground, the page's quieter ink. */
.tw-alert-info {
  background: var(--token-color-surface-inset);
  color: var(--token-color-text-secondary);
}

/* The running-audit warning keeps its yellow ground; it gains the glyph's row. */
.tw-launch-warn.tw-alert {
  border-color: color-mix(in srgb, var(--token-color-state-warn-text) 30%, transparent);
}

/* ---- Proposal */

/* FileText before the name; the name alone gives up its end. */
.tw-row .tw-doc {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.tw-row .tw-doc > .ic {
  color: var(--token-color-text-tertiary);
}

.tw-doc-name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* A file out of the next audit is drawn muted (Proposal.tsx:155-157). */
.tw-row.is-excluded {
  background: var(--token-color-surface-inset);
}

.tw-row.is-excluded .tw-doc,
.tw-row.is-excluded .tw-num,
.tw-row.is-excluded .tw-remark,
.tw-row.is-excluded .tw-remark-long {
  color: var(--token-color-text-tertiary);
}

/* The switch and its word; on a narrow column the word goes under it. */
.tw-row form.inline {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--token-space-1) var(--token-space-2);
}

.tw-switch-word {
  font-size: var(--token-fs-xs);
  font-weight: var(--token-weight-medium);
  white-space: nowrap;
  color: var(--token-color-text-primary);
}

.tw-row.is-excluded .tw-switch-word,
form[aria-busy='true'] .tw-switch-word {
  color: var(--token-color-text-tertiary);
}

/* The empty list: FileText over the sentence, as the original's. */
.tw-docs-empty.tw-docs-none {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--token-space-3);
  padding: var(--token-space-8) var(--token-space-3);
  text-align: center;
}

.tw-docs-none > .ic {
  color: var(--token-color-text-tertiary);
}

.tw-docs-none > p {
  margin: 0;
}

.tw-prop-snap > .ic {
  margin-right: var(--token-space-1);
  color: var(--token-color-text-tertiary);
}

/* ---- Audits */

.tw-launch-title {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
}

.tw-est {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-1);
}

.tw-est > .ic {
  color: var(--token-color-text-tertiary);
}

/* The status tile before each audit: FileSearch, ShieldAlert, Loader2. */
.tw-audit-cell {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
  min-width: 0;
}

.tw-audit-cell > span:last-child {
  min-width: 0;
}

.tw-tile {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--token-space-8);
  height: var(--token-space-8);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-inset);
  color: var(--token-color-text-secondary);
}

.tw-tile-crit {
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tw-tile-run {
  background: var(--token-color-state-info-bg);
  color: var(--token-color-state-info-text);
}

/* ChevronRight at the row's end: the whole row leads into the report. */
.tw-audits-t .tw-c-go {
  width: var(--token-space-10);
}

.tw-go {
  text-align: right;
  color: var(--token-color-text-tertiary);
}

.tw-go a {
  display: inline-flex;
  color: inherit;
}

.tw-audits-t tr:hover .tw-go {
  color: var(--token-color-text-primary);
}

/* ---- stage progress: Clock before the waiting line */

.tw-wait {
  display: flex;
  align-items: center;
  gap: var(--token-space-1);
}

/* ---- the audit report */

.tw-back {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

/* The gate's glyph is a Lucide icon now; the box keeps the size it had. */
.tw-verdict-icon {
  display: inline-flex;
}

.tw-verdict-icon > .ic {
  width: 100%;
  height: 100%;
  stroke-width: 2.2;
}

/* Running and failed: the big glyph beside the line. */
.tw-state-head {
  display: flex;
  align-items: center;
  gap: var(--token-space-3);
  margin: 0;
  font-size: var(--token-fs-lg);
  font-weight: var(--token-weight-medium);
}

.tw-audit-state .tw-state-head > .ic {
  color: var(--token-color-accent-text);
}

.tw-audit-failed .tw-state-head,
.tw-audit-failed .tw-state-head > .ic {
  color: var(--token-color-state-crit-text);
}

/* A frozen snapshot that can no longer be found: its row in red. */
.tw-row-missing td,
.tw-row-missing td .ic {
  color: var(--token-color-state-crit-text);
}

.tw-row-missing td .ic {
  margin-right: var(--token-space-1);
}

.tw-missing {
  font-size: var(--token-fs-2xs);
  font-weight: var(--token-weight-medium);
  text-transform: uppercase;
}

/* A trace's completion: CheckCircle2 green, AlertTriangle amber. */
.tw-mark-ok {
  display: inline-flex;
  color: var(--token-color-state-ok-text);
}

.tw-mark-warn {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  color: var(--token-color-state-warn-text);
}

/* PenLine before the signature line. */
.tw-sig {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-1);
}

.tw-sig > .ic {
  flex: none;
  margin-top: var(--token-layout-hair-gap);
  color: var(--token-color-text-tertiary);
}

.tw-merged > summary > .ic {
  margin-right: var(--token-space-1);
  color: var(--token-color-text-tertiary);
}

/* The findings search: Search inside the field, X at its end. */
.tw-find-q {
  position: relative;
  display: flex;
  align-items: center;
}

.tw-find-q > .ic {
  position: absolute;
  left: var(--token-layout-control-pad-x-sm);
  color: var(--token-color-text-tertiary);
  pointer-events: none;
}

.tw-find-q input {
  padding-left: calc(var(--token-layout-control-pad-x-sm) + var(--token-size-icon-sm) + var(--token-space-2));
  padding-right: calc(var(--token-size-icon-sm) + var(--token-space-4));
}

.tw-find-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--token-color-text-tertiary);
}

.tw-find-x:hover {
  color: var(--token-color-text-primary);
}

.tw-find-q .tw-find-x {
  position: absolute;
  right: var(--token-space-2);
}

[data-live-filter-submit][hidden] {
  display: none;
}

/* Eye while reviewed findings show, EyeOff while they are hidden. */
.tw-review-show {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

.tw-review-show[aria-pressed='false'] [data-icon='Eye'],
.tw-review-show[aria-pressed='true'] [data-icon='EyeOff'] {
  display: none;
}

.tw-no-match {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--token-space-2);
  text-align: center;
}

.tw-no-match > .ic {
  color: var(--token-color-text-tertiary);
}

.tw-no-match p {
  margin: 0;
}

/* ---- the comparison */

.tw-cmp-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-2);
}

.tw-cmp-title > .ic {
  color: var(--token-color-text-secondary);
}

.tw-change {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

.tw-change > .ic {
  flex: none;
  color: var(--token-color-text-tertiary);
}

/* The movement of the figure, below the identity it depends on. */
.tw-cmp-move {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.tw-cmp-move .tw-verdict-score {
  flex: none;
  border-left: 0;
  background: transparent;
}

.tw-cmp-move-note {
  flex: 1 1 var(--token-layout-field-basis);
  margin: 0;
  padding: var(--token-space-4) var(--token-layout-block-gap);
  font-size: var(--token-fs-xs-plus);
  line-height: 1.5;
  color: var(--token-color-text-secondary);
}

/* ---- tender settings: the danger zone in the destructive ink */

.tt-danger .tt-card-title {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  color: var(--token-color-state-crit-text);
}

/* A narrow page: the audit table's fixed columns add up to more than there
   is, so each audit becomes a card — the tile and name on the first line, the
   gate, the figure, the findings and the time wrapping under it, the chevron
   in its corner. Nothing runs past the page's edge. */
@media (max-width: 1100px) {
  .tw-audits-t colgroup,
  .tw-audits-t thead {
    display: none;
  }

  .tw-audits-t,
  .tw-audits-t tbody {
    display: block;
    width: 100%;
  }

  .tw-audits-t tr {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--token-space-2) var(--token-space-4);
    padding: var(--token-space-3) calc(var(--token-space-10) + var(--token-space-2)) var(--token-space-3) var(--token-space-4);
    border-bottom: var(--token-border-hair) solid var(--token-color-border-subtle);
  }

  .tw-audits-t tr:last-child {
    border-bottom: 0;
  }

  .tw-audits-t td,
  .tw-card .tw-audits-t tbody td {
    display: block;
    width: auto;
    min-width: 0;
    padding: 0;
    border: 0;
  }

  .tw-audits-t td.tw-tick {
    flex: none;
  }

  .tw-audits-t td:has(.tw-audit-cell) {
    flex: 1 0 calc(100% - var(--token-space-16));
  }

  .tw-audits-t td.tw-go {
    position: absolute;
    top: var(--token-space-3);
    right: var(--token-space-4);
  }
}

/* =====================================================================
   experience: one project record, its sections and its dialogs — what the
   original draws beyond the board (wave 2, parity E1/E2): the section
   descriptions and counts, the row glyphs, the icon-only row verbs, the
   dialogs over the page (a document, the evidence package), the unsaved-
   changes mark, the pending spinner, the card's printed footer.
   Every rule is scoped to `.tr-exp`, like the block it extends in
   `tenders-registry.css`.
   ===================================================================== */

/* ---- the card head: «(3)» after the title, the section's sentence under it ---- */
.tr-exp .xp-card-head h2 > .ic {
  width: var(--token-size-icon-sm);
  height: var(--token-size-icon-sm);
  margin-right: var(--token-space-2);
  vertical-align: -0.15em;
}

.tr-exp .xp-count {
  color: var(--token-color-text-tertiary);
  font-weight: var(--token-weight-regular);
}

.tr-exp .xp-card-desc {
  margin: 0;
  font-size: var(--token-fs-xs-plus);
  line-height: var(--token-lh-normal);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-editor-sheet .xp-card-desc {
  padding: var(--token-space-1) var(--token-space-5) 0;
}

.tr-exp .xp-card-refused .xp-card-head h2 > .ic {
  color: var(--token-color-state-crit-text);
}

/* ---- the review row: the status card's badges, apart ---- */
.tr-exp .xp-review-row .xp-badges,
.tr-exp .xp-modal-body > .xp-badges,
.tr-exp .xp-pkg-row .xp-badges {
  display: inline-flex;
  flex-wrap: wrap;
  gap: calc(var(--token-space-1) * 1.5);
}

/* ---- glyphs beside words ---- */
.tr-exp .xp-back a,
.tr-exp a.xp-ext,
.tr-exp .xp-verified,
.tr-exp .xp-allclear,
.tr-exp .xp-pop-title,
.tr-exp legend.lbl {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
}

.tr-exp .xp-verified .ic,
.tr-exp .xp-allclear .ic {
  color: var(--token-color-state-ok-text);
  flex: none;
}

.tr-exp .xp-warn-title > .ic {
  flex: none;
}

.tr-exp .xp-warn.xp-crit {
  background: var(--token-color-state-crit-bg);
  color: var(--token-color-state-crit-text);
}

.tr-exp .xp-warn.xp-crit .xp-warn-text {
  color: var(--token-color-text-secondary);
}

.tr-exp .menu-group a > .ic,
.tr-exp .xp-more .menu a > .ic {
  flex: none;
  margin-right: var(--token-space-2);
  vertical-align: -0.15em;
}

.tr-exp .menu-group + .menu-group {
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
}

/* ---- completeness: the severity glyph in its colour, the row a link with its chevron ---- */
.tr-exp .xp-sev {
  display: inline-flex;
  flex: none;
}

.tr-exp .xp-sev.t-critical { color: var(--token-color-state-crit-text); }
.tr-exp .xp-sev.t-warning { color: var(--token-color-state-warn-text); }
.tr-exp .xp-sev.t-info,
.tr-exp .xp-sev.t-neutral { color: var(--token-color-text-tertiary); }

.tr-exp .xp-warning-row > a {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-2);
  flex: 1 1 auto;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.tr-exp .xp-warning-row > a:hover .grow {
  text-decoration: underline;
}

.tr-exp .xp-warning-row > a > .ic {
  flex: none;
  color: var(--token-color-text-tertiary);
}

/* ---- rows: the original's glyph on the left, verbs as square icon buttons ---- */
.tr-exp .xp-row-icon {
  flex: none;
  display: inline-flex;
  color: var(--token-color-text-tertiary);
  padding-top: var(--token-gap-hair);
}

.tr-exp .xp-edit-actions .btn-glyph.btn-sm,
.tr-exp .xp-edit-actions summary.btn-glyph {
  width: var(--token-layout-control-h-sm);
  padding: 0;
  justify-content: center;
}

.tr-exp .btn.xp-danger:hover,
.tr-exp .xp-more .menu a.is-danger {
  color: var(--token-color-state-crit-text);
}

.tr-exp .btn.is-off {
  opacity: 0.5;
  pointer-events: none;
}

.tr-exp .xp-metric-value {
  font-weight: var(--token-weight-medium);
  font-variant-numeric: tabular-nums;
}

.tr-exp .xp-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.tr-exp .xp-quote {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-2);
}

.tr-exp .xp-quote > .ic {
  flex: none;
  margin-top: var(--token-gap-hair);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-chips.xp-field-chips {
  margin-top: var(--token-space-1);
}

/* ---- the empty section: the dashed box with its own «Додати …» ---- */
.tr-exp .xp-empty-box {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--token-space-3);
  padding: var(--token-space-5);
  border: var(--token-border-hair) dashed var(--token-color-border-strong);
  border-radius: var(--token-radius-md);
}

.tr-exp .xp-empty-box > .xp-muted {
  margin: 0;
}

/* ---- form pieces: inline create, type-to-search, date clear, repeatable rows ---- */
.tr-exp .xp-create,
.tr-exp .xp-filter {
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  margin-top: var(--token-space-2);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-filter {
  margin: 0 0 var(--token-space-2);
}

.tr-exp .xp-create > input,
.tr-exp .xp-filter > input {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--token-layout-control-h-sm);
  padding: 0 var(--token-layout-control-pad-x-sm);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface);
  color: var(--token-color-text-primary);
  font: inherit;
  font-size: var(--token-fs-sm);
}

.tr-exp .xp-create > input:focus,
.tr-exp .xp-filter > input:focus {
  outline: var(--token-border-thick) solid var(--token-focus-ring);
  outline-offset: 0;
}

.tr-exp .xp-filter[hidden],
.tr-exp [data-clear][hidden],
.tr-exp [data-close-details][hidden],
.tr-exp [data-repeat-add][hidden],
.tr-exp [data-repeat-remove][hidden],
.tr-exp [data-dirty-badge][hidden],
.tr-exp [data-preview-busy][hidden],
.tr-exp [data-preview-manual][hidden],
.tr-exp [data-print][hidden] {
  display: none;
}

.tr-exp .xp-repeat-rows {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-2);
}

.tr-exp .xp-repeat-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--token-space-3);
}

.tr-exp .xp-repeat-row .xp-field {
  min-width: 0;
}

.tr-exp .xp-subform [data-repeat-add] {
  align-self: flex-start;
  margin-top: var(--token-space-2);
}

/* ---- pending: the pressed submit's glyph becomes Loader2 ---- */
.tr-exp .btn .xp-spin {
  display: none;
}

.tr-exp .btn[aria-busy='true'] .xp-spin {
  display: inline-flex;
}

.tr-exp .btn[aria-busy='true'] > .ic:not(.ic-spin) {
  display: none;
}

.tr-exp .xp-dirty {
  align-self: center;
}

/* ---- a small form's title over its sentence ---- */
.tr-exp .xp-pop .xp-pop-title {
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  white-space: normal;
}

/* ---- the dialog over the page ---- */
.tr-exp .xp-modal {
  position: fixed;
  inset: 0;
  z-index: var(--token-z-skip);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--token-space-10) var(--token-space-4);
  overflow-y: auto;
}

.tr-exp .xp-modal-scrim {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--token-color-text-primary) 38%, transparent);
}

.tr-exp .xp-modal-box.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  width: min(var(--token-layout-field-max) * 1.4, 100%);
  max-width: 100%;
  min-width: 0;
  margin: 0;
  padding: var(--token-space-5);
  box-shadow: 0 var(--token-space-2) var(--token-space-8) color-mix(in srgb, var(--token-color-text-primary) 22%, transparent);
}

.tr-exp .xp-modal.is-wide .xp-modal-box.panel {
  width: min(calc(var(--token-layout-field-max) * 2 + var(--token-space-16)), 100%);
}

.tr-exp .xp-modal-box:focus {
  outline: none;
}

.tr-exp .xp-modal-head {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-3);
}

.tr-exp .xp-modal-head h2 {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--token-space-2);
  font-family: var(--token-font-body);
  font-size: var(--token-fs-md);
  font-weight: var(--token-weight-medium);
  overflow-wrap: break-word;
}

.tr-exp .xp-modal-head h2 > .ic {
  flex: none;
  color: var(--token-color-accent-text);
}

.tr-exp .xp-modal-x {
  flex: none;
  display: inline-flex;
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-modal-desc {
  margin: 0;
  font-size: var(--token-fs-sm);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-modal-body {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  min-width: 0;
}

.tr-exp .xp-modal-body > * {
  margin: 0;
}

.tr-exp .xp-dlg-verbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
}

.tr-exp .xp-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--token-layout-card-min), 1fr));
  gap: var(--token-space-2) var(--token-space-4);
  margin: 0;
  font-size: var(--token-fs-xs-plus);
}

.tr-exp .xp-meta > div {
  min-width: 0;
}

.tr-exp .xp-meta dt {
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-meta dd {
  margin: 0;
  overflow-wrap: break-word;
}

.tr-exp .xp-meta dd.is-none {
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-modal-body .xp-sub {
  margin: var(--token-space-2) 0 0;
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
}

.tr-exp .xp-link-add .xp-foot {
  padding: 0;
}

/* The row menu: «Ще дії». */
.tr-exp .xp-more > .menu {
  right: 0;
  left: auto;
  min-width: var(--token-layout-card-min);
}

.tr-exp .xp-more .menu a {
  display: flex;
  align-items: center;
  white-space: nowrap;
}

/* ---- the evidence package ---- */
.tr-exp .xp-pkg {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  min-width: 0;
}

.tr-exp .xp-pkg-region {
  display: flex;
  flex-direction: column;
  gap: var(--token-space-3);
  min-width: 0;
}

.tr-exp .xp-pkg-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--token-space-1) var(--token-space-4);
  margin: 0;
  font-size: var(--token-fs-sm);
}

.tr-exp .xp-pkg-summary .t-ok {
  color: var(--token-color-state-ok-text);
  font-weight: var(--token-weight-medium);
}

.tr-exp .xp-pkg-busy {
  display: inline-flex;
  align-items: center;
  gap: var(--token-space-1);
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

.tr-exp .xp-pkg-note {
  margin: 0;
  padding: var(--token-space-2) var(--token-space-3);
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  background: var(--token-color-surface-sunken);
  font-size: var(--token-fs-xs-plus);
  color: var(--token-color-text-secondary);
}

.tr-exp .xp-pkg-list {
  list-style: none;
  margin: 0;
  padding: 0 var(--token-space-1) 0 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--token-space-1) * 1.5);
  max-height: 45vh;
  overflow-y: auto;
}

.tr-exp .xp-pkg-row {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--token-space-2) + var(--token-gap-hair));
  padding: var(--token-space-2) calc(var(--token-space-2) + var(--token-gap-hair));
  border: var(--token-border-hair) solid var(--token-color-border-subtle);
  border-radius: var(--token-radius-md);
  min-width: 0;
}

.tr-exp .xp-pkg-row.row-dim {
  opacity: 0.6;
}

.tr-exp .xp-pkg-row > input {
  flex: none;
  margin-top: var(--token-gap-hair);
}

.tr-exp .xp-pkg-row > label {
  display: flex;
  flex-direction: column;
  gap: var(--token-gap-hair);
  min-width: 0;
  cursor: pointer;
}

.tr-exp .xp-pkg-name {
  display: flex;
  align-items: flex-start;
  gap: var(--token-space-2);
  font-size: var(--token-fs-sm);
  font-weight: var(--token-weight-medium);
  overflow-wrap: anywhere;
}

.tr-exp .xp-pkg-name > .ic {
  flex: none;
  color: var(--token-color-text-tertiary);
  margin-top: var(--token-gap-hair);
}

.tr-exp .xp-pkg-row .xp-badges {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--token-space-1);
  max-width: 45%;
}

.tr-exp .xp-pkg .xp-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--token-space-2);
  padding: 0;
}

/* ---- the card's printed footer: «Strimco · Картка досвіду · дата» ---- */
.tr-exp .xp-card-footer {
  margin: var(--token-space-6) 0 0;
  padding-top: var(--token-space-3);
  border-top: var(--token-border-hair) solid var(--token-color-border-subtle);
  text-align: center;
  font-size: var(--token-fs-xs);
  color: var(--token-color-text-tertiary);
}

/* ---- narrow: the dialog fills the width, rows stack their verbs ---- */
@media (max-width: 900px) {
  .tr-exp .xp-modal {
    padding: var(--token-space-4) var(--token-space-2);
  }

  .tr-exp .xp-repeat-row {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .tr-exp .xp-repeat-row > .xp-field:nth-child(2) {
    grid-column: 1;
  }

  .tr-exp .xp-pkg-row {
    flex-wrap: wrap;
  }

  .tr-exp .xp-pkg-row .xp-badges {
    max-width: none;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
  }
}

@media print {
  .tr-exp .xp-modal,
  .tr-exp .xp-card-refused .ic {
    display: none;
  }
}
