/* TenderRadar components. Built on tokens.css. RTL-first, logical properties. */

/* Visually hidden, still read aloud. The conventional name, added because
   it was NOT here: a template reached for .sr-only, got nothing, and the
   label rendered as 230px of visible text beside a 24px input nobody could
   type into. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  border: 0; }

/* The HTML [hidden] attribute must always win: components like .btn set an
   explicit `display`, which otherwise beats the UA `[hidden]{display:none}` on
   specificity and leaves "hidden" elements visible (e.g. the wizard's Next
   button lingering on the final step). Keep this first so it's overridable
   only by an even more specific intentional rule. */
[hidden] { display: none !important; }

.container { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--s5); padding-block: var(--s6); }

/* ---------- Top bar ---------- */
.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 50;
}
.topbar-inner {
  max-width: var(--maxw); margin-inline: auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); padding: var(--s3) var(--s5);
}
.brand { display: inline-flex; align-items: center; gap: var(--s2); font-family: var(--font-display); font-size: 22px; color: var(--ink); }
.brand:hover { text-decoration: none; }
.brand .mark { color: var(--seal); display: inline-flex; }
/* Bidvane wordmark lockup (UK): two-tone word with a reversed "tenders" bar the
   exact width of the word (flex column + stretch). */
.bv-lock { display: inline-flex; flex-direction: column; align-items: stretch; line-height: 1; }
.bv-word { font-family: var(--font-display); font-size: 25px; line-height: .82; letter-spacing: -.01em;
  white-space: nowrap; -webkit-text-stroke: .6px; paint-order: stroke fill; }
.bv-word .b1 { color: var(--seal); -webkit-text-stroke-color: var(--seal); }
.bv-word .b2 { color: var(--ink); -webkit-text-stroke-color: var(--ink); }
.bv-bar { margin-top: 3px; padding: 2px 0 1px; border-radius: 3px; background: var(--accent);
  color: #fff; font-family: var(--font-body); font-weight: 800; text-transform: uppercase;
  font-size: 11px; letter-spacing: .22em; text-indent: .22em; text-align: center; }
.nav { display: flex; align-items: center; gap: var(--s1); }
.nav a { color: var(--ink-soft); padding: var(--s2) var(--s3); border-radius: var(--r-control); font-weight: 500; font-size: var(--t-sm); }
.nav a:hover { background: var(--paper); color: var(--ink); text-decoration: none; }
.nav a.active { color: var(--ink); background: var(--paper); }
/* The signup CTA is a button inside the nav; .nav a (grey, with a pale hover
   background) would otherwise win on specificity over .btn-primary and make the
   button white-on-white on hover. Pin colour and the hover background so it
   matches the page's other primary CTAs. */
.nav a.btn-primary, .nav a.btn-primary:hover { color: #fff; }
.nav a.btn-primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
.nav-icon { display: inline-flex; vertical-align: -3px; margin-inline-end: 4px; }

/* Expandable "בלוג" menu in the nav (native <details>). */
.nav-dropdown { position: relative; }
.nav-dropdown > summary {
  list-style: none; cursor: pointer; color: var(--ink-soft); font-weight: 500;
  font-size: var(--t-sm); padding: var(--s2) var(--s3); border-radius: var(--r-control);
  display: inline-flex; align-items: center;
}
.nav-dropdown > summary::-webkit-details-marker { display: none; }
.nav-dropdown > summary::marker { content: ""; }
.nav-dropdown > summary:hover { background: var(--paper); color: var(--ink); }
.nav-dropdown[open] > summary { color: var(--ink); background: var(--paper); }
.nav-dropdown-menu {
  position: absolute; top: calc(100% + 6px); inset-inline-end: 0; z-index: 50;
  min-width: 300px; max-width: 86vw; padding: 6px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-card);
  display: flex; flex-direction: column; gap: 2px;
}
.nav-dropdown-menu a {
  display: block; padding: 8px 10px; border-radius: var(--r-control);
  color: var(--ink); font-size: var(--t-sm); line-height: 1.45; font-weight: 500;
}
.nav-dropdown-menu a:hover { background: var(--seal-wash); text-decoration: none; }
.nav-dropdown-all { color: var(--accent-ink) !important; }
.nav-caret { display: inline-flex; margin-inline-start: 3px; transition: transform .15s ease; }
.nav-dropdown[open] > summary .nav-caret { transform: rotate(180deg); }
.nav-dropdown-label { padding: 6px 10px 2px; font-size: var(--t-xs); font-weight: 700; color: var(--ink-soft); }
.nav-dropdown-sep { display: block; height: 1px; background: var(--line); margin: 6px 4px; }

/* Public (logged-out) header: flat destination links; below 860px they fold
   into a single "Menu" dropdown so the bar stays brand · Menu · login · CTA. */
.nav-pub-links { display: flex; align-items: center; gap: var(--s1);
  margin-inline-start: 22px; margin-inline-end: auto; }
/* Sleek public-nav links: crisp ink text with a teal underline that grows in
   on hover (brand --seal, deliberately not the orange accent). */
.nav .nav-pub-link { position: relative; font-weight: 500; color: var(--ink);
  background: transparent; border-radius: 0; }
.nav .nav-pub-link::after { content: ""; position: absolute;
  inset-inline: var(--s3); bottom: 3px; height: 2px; border-radius: 2px;
  background: var(--seal); opacity: 0; transform: scaleX(0);
  transform-origin: center; transition: transform .18s ease, opacity .18s ease; }
.nav .nav-pub-link:hover { background: transparent; color: var(--seal); }
.nav .nav-pub-link:hover::after { opacity: 1; transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .nav .nav-pub-link::after { transition: none; }
}
/* Auth cluster — separated pair, square-angled (6px): Log in as a clean
   framed button ~10% smaller than the solid Sign up. */
.nav-auth { display: inline-flex; align-items: center; gap: 12px; margin-inline-start: 16px; }
.nav .nav-pub-login {
  display: inline-flex; align-items: center;
  padding: 7px 14px; font-size: var(--t-xs);
  border: 1px solid rgba(0, 0, 0, .8);
  border-radius: 6px;
  font-weight: 600; color: var(--ink);
  line-height: 1.2; transition: border-color .12s ease, background .12s ease;
}
.nav .nav-pub-login:hover { background: var(--paper); color: var(--ink); border-color: var(--ink); }
.nav .nav-signup { padding: 9px 18px; font-size: 16px; line-height: 1.2; border-radius: 6px; }
.nav-pub-menu { display: none; }
/* The auth cluster hugs the end; the nav stretches so the destination links
   sit left of the free space (clear of the brand, away from login/CTA). */
.topbar-inner:has(.nav-pub-links) .nav { flex: 1; }
@media (max-width: 860px) {
  .nav-pub-links { display: none; }
  .nav-pub-menu { display: inline-block; margin-inline-end: auto; }
}



/* Account menu (logged-in): workspace/settings/admin/logout behind one control,
   so the bar keeps only the daily work destinations flat. */
.nav-account > summary { gap: 4px; padding-block: 4px; }
.nav-account > summary.active { background: var(--paper); }
.nav-avatar {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  background: var(--seal-wash); color: var(--seal);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13px; line-height: 1;
}
.nav-account > summary.active .nav-avatar,
.nav-account[open] > summary .nav-avatar { background: var(--seal); color: #fff; }
.nav-account-menu { min-width: 210px; }
.nav-account-menu a { display: flex; align-items: center; gap: 8px; }
.nav-account-menu a .nav-icon { margin: 0; color: var(--ink-soft); }
.nav-account-menu a.active { background: var(--paper); }
/* The theme toggle is a <button> — it changes nothing on the server and must
   not navigate — so it has to be told to look like the links it sits with.
   A button carries its own font, background, border and alignment; without
   these it renders as a grey OS button in the middle of a menu. */
.nav-theme {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: var(--r-control);
  background: none; cursor: pointer; text-align: start;
  font-family: inherit; font-size: var(--t-sm); line-height: 1.45;
  font-weight: 500; color: var(--ink);
}
.nav-theme:hover { background: var(--seal-wash); }
.nav-theme .nav-icon { margin: 0; color: var(--ink-soft); flex: none; }
.nav-account-who {
  max-width: 230px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 500; padding-bottom: 6px; border-bottom: 1px solid var(--line); margin-bottom: 4px;
}

/* Laptop widths: before anything wraps, drop the primary-nav labels to icons
   (title attributes keep the names on hover). The account control is already
   just an avatar. */
@media (max-width: 1000px) {
  .nav a .label { display: none; }
  .nav a { padding: var(--s2); }
  .nav-icon { margin: 0; }
  .nav-account-menu a .nav-icon { margin: 0; }
}

/* Public contact page — two clear lanes (sales / support). */
.contact-lanes { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin: var(--s5) 0; }
.contact-lane { border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface);
  padding: var(--s4) var(--s5); }
.contact-lane h2 { display: flex; align-items: center; gap: 7px; font-size: var(--t-md); margin: 0 0 var(--s2); }
.contact-lane .btn { display: inline-flex; align-items: center; gap: 6px; direction: ltr; }
/* .blog-body a colouring would otherwise repaint the primary button's label. */
.contact-lane .btn-primary, .contact-lane .btn-primary:hover { color: #fff; }

/* Public blog — listing + article. */
.blog-article { max-width: 760px; }
.blog-article > h1 { font-size: var(--t-xl); line-height: 1.2; margin-bottom: 6px; }
.blog-article-meta { font-size: var(--t-sm); margin-bottom: var(--s5); }
.blog-body { color: var(--ink); line-height: 1.85; }
.blog-body h2 { font-family: var(--font-display); font-size: var(--t-lg); margin: var(--s5) 0 var(--s2); }
.blog-body p { margin: 0 0 var(--s3); }
.blog-body a { color: var(--accent-ink); }
.blog-refs { font-size: var(--t-sm); color: var(--ink-soft); border-top: 1px solid var(--line); padding-top: var(--s3); margin-top: var(--s4); }
.blog-cta { margin: var(--s6) 0 var(--s4); padding: var(--s5); background: var(--seal-wash); border-radius: var(--r-card); text-align: center; }
/* Comparison table for editorial posts (e.g. approaches to finding tenders). */
.blog-body table.cmp { width: 100%; border-collapse: collapse; margin: var(--s4) 0; font-size: var(--t-sm); line-height: 1.5; }
.blog-body table.cmp th, .blog-body table.cmp td { border: 1px solid var(--line); padding: var(--s2) var(--s3); text-align: start; vertical-align: top; }
.blog-body table.cmp thead th { font-family: var(--font-display); background: var(--bg-soft, var(--seal-wash)); }
.blog-body table.cmp tbody th { font-weight: 500; }
.blog-body table.cmp .cmp-us { background: var(--seal-wash); color: var(--accent-ink); font-weight: 700; }
.blog-cta p { margin: 0 0 var(--s3); font-weight: 500; }
.blog-back { margin-top: var(--s4); }
.blog-back a { color: var(--accent-ink); }
/* About page — "how it works" steps. */
.about-steps { display: flex; flex-wrap: wrap; gap: var(--s4); margin: var(--s3) 0 var(--s4); }
.about-step { flex: 1 1 180px; padding: var(--s4); border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface); }
.about-step-ic { display: inline-flex; color: var(--seal); margin-bottom: var(--s2); }
.about-step h3 { font-size: var(--t-md); margin: 0 0 4px; }
.about-step p { margin: 0; color: var(--ink-soft); font-size: var(--t-sm); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: 10px var(--s4); border-radius: var(--r-control);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: var(--t-sm); font-weight: 500; cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.btn:hover { background: var(--paper); border-color: var(--line-hover); text-decoration: none; }
.btn-primary { background: var(--accent-fill); border-color: var(--accent); color: var(--on-accent); font-weight: 700; }
.btn-primary:hover { background: var(--accent-fill-hover); border-color: var(--accent-fill-hover); color: var(--on-accent); }
.btn-lg { padding: 14px var(--s6); font-size: var(--t-md); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--accent-ink); }
.btn-block { width: 100%; }

/* T-ILBTN: IL public-area button system — seal-blue fill + thin orange base
   line. Scoped to body.il-pub so the logged-in app and all UK pages are
   untouched. --accent is unchanged; orange lives only in the 2.5px base line. */
body.il-pub .btn-primary, body.il-pub button[type=submit], body.il-pub .cta {
  background: var(--btn); color: #fff; border: none;
  box-shadow: inset 0 -2.5px 0 var(--btn-line);
  border-radius: var(--r-control); font-weight: 500;
  font-size: 14px; padding: 7px 16px; line-height: 1.4;
  transition: background .12s ease;
}
body.il-pub .btn-primary:hover  { background: var(--btn-hover); }
body.il-pub .btn-primary:active { transform: translateY(1px); }
body.il-pub .btn-primary:focus-visible { outline: 2px solid var(--seal); outline-offset: 2px; }

body.il-pub .btn-lg   { font-size: var(--t-sm); padding: 9px 22px; }   /* hero CTAs — the ONLY large size */
body.il-pub .btn-sm   { font-size: 13px; padding: 5px 12px; }
body.il-pub .btn-secondary { background: transparent; color: var(--seal);
  border: 1px solid var(--seal); box-shadow: none; }
body.il-pub .btn-secondary:hover { background: var(--seal-wash); }
body.il-pub .btn-primary:disabled { background: var(--line); color: var(--ink-soft);
  box-shadow: none; }
/* De-bulk (§4): no public button larger than .btn-lg. The landing hero CTA had a
   bespoke 13px/16px override — bring it back to the btn-lg scale on IL public. */
body.il-pub .lp-hero .lp-cta-row .btn-lg { font-size: var(--t-sm); padding: 9px 22px; }
/* Submit-in-progress state (set by the form loading handler in base.html): a
   spinner + locked button so the click clearly registered while the server works. */
.btn.is-loading { cursor: progress; opacity: .92; pointer-events: none; }
.btn.is-loading::before {
  content: ""; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: btn-spin .6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn.is-loading::before { animation: none; } }

/* ---------- Forms ---------- */
label { font-weight: 500; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--s4); }
.field > span, .field-label { font-size: var(--t-sm); color: var(--ink); font-weight: 500; }
/* Inline helper line under an input (e.g. the password policy hint). */
.field-hint { font-size: var(--t-xs); line-height: 1.4; margin-top: -2px; }
/* Password field with a reveal (eye) toggle on the trailing edge. */
.pw-wrap { position: relative; display: flex; }
.pw-wrap > input { width: 100%; padding-inline-end: 42px; }
.pw-toggle {
  position: absolute; inset-inline-end: 1px; top: 1px; bottom: 1px; width: 40px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer; color: var(--ink-soft);
  border-radius: var(--r-control);
}
.pw-toggle:hover { color: var(--accent-ink); }
.pw-ic { display: inline-flex; }
.pw-ic-hide { display: none; }
.pw-wrap.is-revealed .pw-ic-show { display: none; }
.pw-wrap.is-revealed .pw-ic-hide { display: inline-flex; }
/* Cloudflare Turnstile widget: center it in the auth card and give it room so it
   sits cleanly between the password fields and the submit button. */
.cf-turnstile { display: flex; justify-content: center; margin: var(--s3) 0 var(--s4); }
input, select, textarea {
  font-family: var(--font-body); font-size: var(--t-sm); color: var(--ink);
  padding: 10px var(--s3); border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); width: 100%;
}
input:hover, select:hover, textarea:hover { border-color: var(--line-hover); }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--seal); outline-offset: 1px; border-color: var(--seal); }
select { cursor: pointer; }

.alert { padding: var(--s3) var(--s4); border-radius: var(--r-control); border: 1px solid var(--bad); background: var(--bad-wash); color: var(--bad); margin-bottom: var(--s4); }
.alert-ok { border-color: var(--ok); background: var(--ok-wash); color: var(--ok); }

/* ---------- Chips (pure-CSS selectable via :has(:checked)) ---------- */
.chip {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  padding: 6px var(--s3); border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-soft); font-size: var(--t-sm); font-weight: 500;
  cursor: pointer; transition: background .12s, border-color .12s, color .12s; user-select: none;
}
.chip:hover { background: var(--paper); }
.chip input { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; margin: 0; }
.chip:has(input:checked), .chip.selected { background: var(--seal-wash); border-color: var(--seal); color: var(--seal); font-weight: 700; }
.chip:has(input:focus-visible) { outline: 2px solid var(--seal); outline-offset: 2px; }

.cert-group { margin-bottom: var(--s4); }
.cert-group > .cert-label { font-size: var(--t-xs); color: var(--ink-soft); font-weight: 700; margin-bottom: var(--s2); display: block; }

/* Deadline chip */
.deadline-chip {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  padding: 4px 10px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
}
.deadline-chip.soon { border-color: var(--check); background: var(--check-wash); color: var(--check); }
.deadline-chip.urgent { border-color: var(--accent); background: var(--accent-fill); color: var(--on-accent); }
.deadline-chip.passed { color: var(--ink-soft); background: var(--paper); }
/* A dynamic market / DPS, or an Israeli מאגר, has no closing date to count down
   to — it takes new members for the life of the market. It is not a point on
   the urgency ramp (neutral → soon → urgent → passed), so it does not take a
   colour from it: green read as "success", which is a different claim. Quiet
   blueprint blue, and a dashed edge that says "ongoing" before the word is
   read. */
.deadline-chip.dl-open {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--seal) 40%, var(--line));
  background: color-mix(in srgb, var(--seal) 6%, transparent);
  color: var(--seal); font-weight: 600;
}
/* In the table the deadline column is ~114px wide, of which ~82px is content
   box. The icon plus its gap costs 18px of that — more than the column can
   spare once a round date is shown — and the type is already stated by the
   "· מאגר" badge on the title. Cards keep the icon; they have the room. */
/* The category column. Its labels are longer than the space the table gives
   them once the window narrows — "שירותים מקצועיים ופיננסיים" wants 212px of an
   81px column — so the text used to overflow the cell and run across the
   deadline beside it.
   
   Wrap first, clamp second. Truncating on one line put the ellipsis at the head
   of the label in RTL, which reads as though the name itself begins mid-word;
   nearly every category is two words that simply fit on two lines. The clamp
   only bites on the rare label that is still too long after wrapping, so the
   "…" is the exception rather than the default. `anywhere` is what lets
   "הסעות/תחבורה" break at all — it carries no space to wrap at. The full label
   stays on hover either way. */
.t-row .t-cat { white-space: normal; }
.t-row .t-cat > span {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; overflow-wrap: anywhere;
}
.t-row .deadline-chip.dl-open svg { display: none; }
.t-row .deadline-chip.dl-open { gap: 0; }
/* Planning / pipeline notice badge — distinct (amber) from the verdict + deadline
   chips so a not-yet-biddable opportunity reads differently at a glance. */
.stage-chip {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 3px 9px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600;
  border: 1px solid #d9a441; background: #fbf1dd; color: #8a5a12;
}
.sc-title .stage-chip, .t-title + .stage-chip { vertical-align: 2px; }

/* UK winnability signal (T2.3): a subtle "how contested?" chip on the fit card,
   in the same family as the stage / deadline chips. Tinted by how concentrated
   the field is — green when open, warm gold when an incumbent holds it, neutral
   when moderate. Rendered only for UK behind uk_winnability (v.winnability). */
.uk-winnability {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 3px 9px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
}
.uk-winnability .ic { flex: none; }
.uk-winnability.win-open { border-color: var(--ok); background: var(--ok-wash); color: var(--ok); }
.uk-winnability.win-concentrated { border-color: #d9a441; background: var(--check-wash); color: #8a5a12; }

/* Planning notices read as a quiet inline annotation right after the tender
   title — soft warm gold, no background, so it sits native to the row and
   doesn't catch the eye. Flows inline, so it never reflows the rest of the row. */
.stage-tag {
  font-size: 10.5px; font-weight: 600; letter-spacing: .3px;
  /* 4.82:1 on white. Was #9a7a2b at 4.04:1 — same hue, taken down until
     it clears AA with room to spare. --check is not the answer here: it
     is #B07905 and measures 3.76 against this ground. */
  color: #8B6E27; white-space: nowrap;
}
/* Dashboard match cards: the planning caption a touch larger than in the table,
   nudged 1px down so the smaller text optically rests on the verdict's line. */
.fitcard-status .stage-tag { font-size: calc(10.5px * 1.1); position: relative; top: 1px; }

/* ---------- Saved pipeline page ---------- */
/* Header row: result count on one side, stage tally chips on the other. */
.saved-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s2) var(--s4); margin-bottom: var(--s4);
}
.saved-head .results-summary { margin: 0; }
.pipeline-summary { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.ps-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
  cursor: pointer; font-family: inherit; transition: opacity .12s ease, background .12s ease;
}
.ps-pill:hover { background: var(--paper); }
.ps-pill b { color: inherit; font-weight: 700; }
/* Each pill is an independent on/off filter. "On" (visible) is the default,
   coloured look; "off" (hidden) dims it and strikes its count. */
.ps-pill.is-off { opacity: .4; background: var(--paper); }
.ps-pill.is-off b { text-decoration: line-through; }
.ps-pill.is-off:hover { opacity: .7; }
/* Show-all chip. */
.ps-clear {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600;
  border: 1px dashed var(--line); background: transparent; color: var(--ink-soft);
  cursor: pointer; font-family: inherit;
}
.ps-clear:hover { background: var(--paper); color: var(--ink); }
.ps-interested { color: var(--seal); border-color: color-mix(in srgb, var(--seal) 30%, var(--line)); }
.ps-preparing { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 30%, var(--line)); }
.ps-submitted { color: var(--seal); border-color: color-mix(in srgb, var(--seal) 30%, var(--line)); }
.ps-won { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, var(--line)); }
.ps-lost { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 30%, var(--line)); }

/* Card list — one clean card per saved tender. */
.saved-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s4); }
.saved-card {
  position: relative; background: var(--surface);
  border: 1px solid var(--line); border-inline-start: 3px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-card); overflow: hidden;
  transition: box-shadow .15s ease, border-color .15s ease;
}
.saved-card:hover { box-shadow: var(--shadow); }
/* Stage accent on the inline-start edge — at-a-glance pipeline color. */
.stage-accent-interested { border-inline-start-color: var(--seal); }
.stage-accent-preparing  { border-inline-start-color: var(--accent); }
.stage-accent-submitted  { border-inline-start-color: var(--seal); }
.stage-accent-won        { border-inline-start-color: var(--ok); }
.stage-accent-lost       { border-inline-start-color: var(--bad); }
.saved-card.is-missed { border-inline-start-color: var(--accent); }

.sc-row { display: flex; align-items: flex-start; gap: var(--s4); padding: var(--s4) var(--s5); cursor: pointer; }
.sc-main { flex: 1; min-width: 0; }
.sc-title { font-family: var(--font-display); font-size: var(--t-md); color: var(--ink); margin: 0 0 7px; line-height: 1.3; }
.sc-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--s2); color: var(--ink-soft); font-size: var(--t-sm); }
.sc-meta .dot { color: var(--line); }
.sc-pub { display: inline-flex; align-items: center; gap: 5px; }
.sc-pub .lucide { color: var(--ink-soft); }
.sc-deadline { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }
.sc-deadline.urgent { color: var(--accent-ink); }
.sc-deadline.soon { color: var(--check); }
.sc-deadline.passed { color: var(--ink-soft); }
.sc-has-note { display: inline-flex; align-items: center; gap: 4px; }

/* At-a-glance AI facts on the collapsed card — compact pills, one wrapping line. */
.sc-facts { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 6px; margin-top: 7px; }
.sc-fact {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--t-xs); color: var(--ink-soft);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 999px; padding: 1px 9px; line-height: 1.7;
}
.sc-fact .lucide { color: var(--ink-soft); }
.sc-fact b { color: var(--ink); font-weight: 700; }
.sc-fact-warn { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-wash); }
.sc-fact-warn .lucide { color: var(--accent-ink); }
.sc-facts .t-conf-chip { line-height: 1.7; }

.sc-side { display: flex; align-items: center; gap: var(--s3); flex: none; }
.sc-caret { color: var(--ink-soft); display: inline-flex; transition: transform .15s ease; }
.t-row[aria-expanded="true"] .sc-caret { transform: rotate(180deg); color: var(--accent); }

/* Stage <select> rendered as a pill — the card's one prominent control. */
.stage-form { margin: 0; }
.stage-select {
  font-size: var(--t-xs); font-weight: 700; padding: 6px 12px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
  -webkit-appearance: none; appearance: none; text-align: center; text-align-last: center;
}
/* The CLOSED control wears the stage colour as a status cue, but the open
   dropdown must stay neutral — otherwise the whole option list renders in the
   current stage's red/green, which reads as broken. <option> styling is
   limited, but color/background are honoured by Chromium/Firefox. */
.stage-select option { color: var(--ink); background: var(--surface); font-weight: 500; }
.stage-interested { border-color: var(--seal); background: var(--seal-wash); color: var(--seal); }
.stage-preparing  { border-color: var(--accent); background: var(--accent-wash); color: var(--accent-ink); }
.stage-submitted  { border-color: var(--seal); background: var(--seal); color: #fff; }
.stage-won        { border-color: var(--ok); background: var(--ok-wash); color: var(--ok); }
.stage-lost       { border-color: var(--bad); background: var(--bad-wash); color: var(--bad); }

/* Expanded detail area. */
.sc-detail { border-top: 1px solid var(--line); background: var(--paper); padding: var(--s4) var(--s5); }
.sc-detail-grid { display: grid; grid-template-columns: 1fr 280px; gap: var(--s5); align-items: start; }
.sc-detail-main { display: flex; flex-direction: column; gap: var(--s3); min-width: 0; }
.sc-actions {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  margin-top: var(--s4); padding-top: var(--s3); border-top: 1px dashed var(--line);
}
.sc-actions .inline { display: inline-flex; margin: 0; }
.note-form { margin: var(--s2) 0 0; }
/* Slim inline note field: borderless auto-growing textarea + a round save
   button sharing one rounded container; a tiny lock hint sits beneath it. */
.note-field {
  display: flex; align-items: flex-end; gap: var(--s2);
  border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); padding: 5px 6px 5px 10px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.note-field:focus-within { border-color: var(--seal); box-shadow: 0 0 0 3px var(--seal-wash); }
.note-input {
  flex: 1; min-width: 0; border: 0; background: transparent; resize: none;
  font: inherit; color: var(--ink); line-height: 1.5; padding: 4px 0;
  max-height: 160px; overflow-y: auto;
}
.note-input:focus { outline: none; }
.note-save-btn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--seal-wash); color: var(--seal); transition: background .12s ease, color .12s ease;
}
.note-save-btn:hover { background: var(--seal); color: #fff; }
.note-save-btn.is-saved { background: var(--ok); color: #fff; }
.note-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); margin-top: 5px; }
.note-hint { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-xs); }
.note-hint .lucide { opacity: .8; }
.note-counter { font-size: var(--t-xs); font-variant-numeric: tabular-nums; flex: none; }
.note-counter.is-low { color: var(--accent-ink); font-weight: 700; }
@media (max-width: 760px) {
  .sc-detail-grid { grid-template-columns: 1fr; }
}

/* Controls row: stage filter then the outcome KPIs, flowing from the start and
   wrapping together as a tidy group (no forced split that isolates a chip). */
.pipeline-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s5); margin-bottom: var(--s4); }
.pipeline-summary { margin-bottom: 0; }

/* ---- View toggle (list / board) ---- */
.view-toggle { display: inline-flex; flex: none; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); }
.vt-btn {
  display: inline-flex; align-items: center; gap: 5px; padding: 5px 12px;
  border: 0; border-radius: 999px; background: transparent; color: var(--ink-soft);
  font: inherit; font-size: var(--t-xs); font-weight: 600; cursor: pointer;
}
.vt-btn:hover { color: var(--ink); }
.vt-btn.is-active { background: var(--seal-wash); color: var(--seal); }

/* ---- Outcome KPI chips (compact, non-clickable; aligned with the filter) ---- */
.pipeline-stats { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); margin: 0; }
.stat-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px; border-radius: 999px;
  background: var(--paper); font-size: var(--t-xs); color: var(--ink-soft);
}
.stat-chip b { color: var(--ink); font-weight: 700; }
.stat-chip .stat-ok { color: var(--ok); }
.stat-chip .stat-bad { color: var(--bad); }
/* The awarded-value KPI: same size as the other chips, set apart by colour.
   (Own class — must not collide with the admin `.stat-value` display number.) */
.stat-chip.stat-money { background: var(--seal-wash); color: var(--seal); }
.stat-chip.stat-money b { color: var(--seal); }

/* ---- Won/lost award capture (compact) ---- */
.award-form {
  margin: var(--s2) 0; padding: var(--s2) var(--s3) var(--s3);
  border: 1px solid var(--line); border-radius: var(--r-control); background: var(--surface);
}
.award-form.stage-won { border-color: color-mix(in srgb, var(--ok) 35%, var(--line)); background: color-mix(in srgb, var(--ok-wash) 50%, var(--surface)); }
.award-form.stage-lost { border-color: color-mix(in srgb, var(--bad) 30%, var(--line)); background: color-mix(in srgb, var(--bad-wash) 50%, var(--surface)); }
.award-head { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; font-size: var(--t-xs); color: var(--ink-soft); margin-bottom: 6px; }
.award-head .lucide { color: var(--check); }
.award-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s2); }
.award-row .field { flex: 1; min-width: 120px; margin: 0; }
.award-row .field span { font-size: var(--t-xs); }
.award-row .field input { padding: 6px 10px; }
.award-save { flex: none; padding: 7px 10px; align-self: flex-end; }

/* ---- Drag handle + reorder states (list + board) ---- */
.drag-handle {
  flex: none; display: inline-flex; align-items: center; align-self: flex-start;
  color: var(--ink-soft); cursor: grab; opacity: .5; margin-top: 2px;
  touch-action: none; transition: opacity .12s ease;
}
.drag-handle:hover { opacity: 1; }
.drag-handle:active { cursor: grabbing; }
.saved-card.is-dragging, .kb-card.is-dragging { opacity: .45; }
.saved-card.drop-target { box-shadow: 0 -2px 0 var(--seal); }

/* ---- Kanban board ---- */
.kanban { display: flex; gap: var(--s3); overflow-x: auto; padding-bottom: var(--s3); align-items: flex-start; }
.kb-col {
  flex: 1 0 240px; min-width: 220px; max-width: 340px;
  background: var(--paper); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--line); border-radius: var(--r-card);
  display: flex; flex-direction: column;
  /* Gentle ease-in-out (soft start AND soft end) reads far calmer than a
     fast-start ease-out; slower + dim fading in step keeps the eye from
     jumping. scroll-margin clears the top nav when we scroll a top card so
     its stage header stays in view. */
  /* One easeOutExpo curve + duration for widen, dim and desaturate so the whole
     column moves as a single gently-decelerating motion (native, not
     mechanical). Paired with per-frame re-centring in the JS. */
  transition: flex-basis .96s cubic-bezier(.16,1,.3,1), max-width .96s cubic-bezier(.16,1,.3,1), opacity .96s cubic-bezier(.16,1,.3,1), filter .96s cubic-bezier(.16,1,.3,1);
  scroll-margin-top: 80px;
}
.kb-col-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.kb-col-title { font-weight: 700; font-size: var(--t-sm); }
.kb-col-count { background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 1px 9px; font-size: var(--t-xs); color: var(--ink-soft); }
.kb-col-body { padding: 10px; display: flex; flex-direction: column; gap: var(--s2); min-height: 64px; transition: background .12s ease; }
.kb-col-body.is-drop { background: var(--seal-wash); outline: 2px dashed var(--seal); outline-offset: -4px; border-radius: var(--r-control); }
.kb-empty { font-size: var(--t-xs); text-align: center; padding: var(--s3) 0; margin: 0; }

.kb-card {
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--line); border-radius: var(--r-control);
  box-shadow: var(--shadow-card);
  /* The focus lift (shadow + border) and the sibling-card dim ease in like a
     hover instead of snapping; transform stays snappy for drag feedback. */
  transition: box-shadow .48s cubic-bezier(.16,1,.3,1), border-color .48s ease, opacity .54s ease, transform .16s ease;
}
.kb-card.is-dragging { opacity: .45; }
/* ── Focus mode ────────────────────────────────────────────────────────────
   Click a card to focus it: its column widens (~30%), the other columns dim,
   and the full detail + editors get room to work. One card at a time. Works in
   both RTL (IL) and LTR (UK) — flex + border-inline-start are direction-aware. */
.kanban.has-focus .kb-col { flex-grow: 0; flex-basis: 244px; }           /* freeze the rest */
.kanban.has-focus .kb-col:not(.is-focus-col) { opacity: .45; filter: saturate(.55); }
/* Qualified with .kanban.has-focus so it outranks the freeze rule above
   (equal-or-higher specificity) — otherwise the focused column stays 244px.
   Capped to 90vw so it never spills past a phone viewport: min() keeps the
   full 588px on any screen wider than ~650px and shrinks to fit on mobile. */
.kanban.has-focus .kb-col.is-focus-col { flex-basis: min(588px, 90vw); max-width: min(588px, 90vw); }
.kanban.has-focus .kb-col.is-focus-col .kb-card:not(.is-focus) { opacity: .5; }
.kb-card.is-focus { position: relative; z-index: 2; box-shadow: var(--shadow);
  border-color: color-mix(in srgb, var(--seal) 32%, var(--line)); outline: 2px solid var(--seal-wash); }
.kb-compact { padding: 10px 11px; cursor: grab; position: relative; }
.kb-compact:active { cursor: grabbing; }
/* Wordless draggability hint: a faint grip pinned to the top corner, brighter
   on hover. Decorative (pointer-events: none) so the grab still drags the whole
   card. Hidden when focused — the ✕ owns that corner then. */
.kb-grip {
  position: absolute; inset-block-start: 8px; inset-inline-end: 9px;
  display: inline-flex; color: var(--ink-soft); opacity: .3;
  pointer-events: none; transition: opacity .15s ease;
}
.kb-card:hover .kb-grip { opacity: .65; }
.kb-card.is-focus .kb-grip { display: none; }
/* The focused card's header is the collapse handle — click it (or the ✕) to
   minimise and leave focus. */
.kb-card.is-focus .kb-compact { cursor: pointer; position: relative; }
.kb-card.is-focus .kb-compact:hover { background: var(--paper); }
.kb-card.is-focus .kb-title { -webkit-line-clamp: unset; padding-inline-end: 28px; }
.kb-card.is-focus .kb-compact::after {
  content: "\00d7"; position: absolute; inset-block-start: 8px; inset-inline-end: 9px;
  width: 22px; height: 22px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 50%; background: var(--surface);
  color: var(--ink-soft); font-size: 14px; line-height: 1;
}
.kb-card.is-focus .kb-compact:hover::after { border-color: var(--seal); color: var(--seal); }
.kb-title {
  font-size: var(--t-sm); font-weight: 700; color: var(--ink); margin: 0 0 5px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  padding-inline-end: 20px;   /* clear the grip in the top corner */
}
.kb-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 7px; font-size: var(--t-xs); color: var(--ink-soft); }
.kb-deadline { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; }
.kb-deadline.urgent { color: var(--accent-ink); }
.kb-deadline.soon { color: var(--check); }
.kb-deadline.passed { color: var(--ink-soft); }
.kb-ic { display: inline-flex; }
.kb-award { color: var(--ok); font-weight: 700; }

.kb-detail { display: none; padding: 10px 12px 12px; border-top: 1px solid var(--line); }
.kb-card.is-focus .kb-detail { display: block; animation: kbReveal .72s cubic-bezier(.16,1,.3,1) .144s both; }
@keyframes kbReveal { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .kb-col { transition: none; }
  .kb-card.is-focus .kb-detail { animation: none; }
}
.kb-detail .t-detail-summary { font-size: var(--t-sm); }
/* The stage pill sizes to its label, not the full card width — the base
   `select { width: 100% }` rule would otherwise stretch it across the whole
   588px focused column. flex keeps it left-aligned at content width. */
.kb-detail-stage { margin: 0 0 var(--s2); display: flex; }
.kb-detail-stage .stage-select { width: auto; min-width: 8.5rem; }
/* Facts read exactly as the list view (same label|value rows, same dashed
   separators, same typography) — the only difference is width: the focused
   card is wide enough to flow them into two columns instead of one. Each fact
   keeps the shared .t-detail-facts > div styling; a long free-text value spans
   the full width. */
.kb-detail .t-detail-facts {
  display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s5); row-gap: 7px;
  margin-top: var(--s3); padding-top: var(--s3); border-top: 1px dashed var(--line);
}
.kb-detail .t-detail-facts > div:has(.t-fact-long) { grid-column: 1 / -1; }
/* Confidence reads as one grouped full-width block: the chip sits beside its
   label (left-aligned — not flung to the far-right edge like a numeric value),
   and the explanation sentence spans the full width directly beneath it. */
.kb-detail .t-detail-facts > .t-conf-row,
.kb-detail .t-detail-facts > .t-conf-note { grid-column: 1 / -1; }
.kb-detail .t-detail-facts > .t-conf-row dd { text-align: start; }
.kb-detail-facts { display: flex; flex-wrap: wrap; gap: 4px 7px; font-size: var(--t-xs); margin-top: var(--s2); }
/* Labelled action row (source / hide / remove) set off by a dashed rule, like
   the list view's .sc-actions. The focus width lets every label breathe. */
.kb-actions {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  margin-top: var(--s3); padding-top: var(--s3); border-top: 1px dashed var(--line);
}
.kb-actions .inline { display: inline-flex; margin: 0; }
.kb-actions .btn { padding: 5px 10px; }

/* ---------- Team / workspace ---------- */
.head-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.ws-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%; font-size: 11px; font-weight: 700;
  background: var(--seal-wash); color: var(--seal); vertical-align: middle;
}
.ws-avatar.sm { width: 24px; height: 24px; font-size: 10px; }
.assignee-badge {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 22px; height: 22px; border-radius: 50%; font-size: 10px; font-weight: 700;
  background: var(--accent-wash); color: var(--accent-ink);
}
.assign-form { margin: var(--s2) 0; display: flex; align-items: center; gap: var(--s2); }
.assign-label { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-xs); }
.assign-select {
  width: auto; max-width: 11rem; font-size: var(--t-xs); font-weight: 600;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer;
}
.notes-block { margin-top: var(--s3); }
.notes-thread { border-top: 1px dashed var(--line); padding-top: var(--s3); }
.notes-head { font-size: var(--t-xs); font-weight: 700; color: var(--ink); margin-bottom: var(--s2); }
.notes-list { list-style: none; margin: 0 0 var(--s2); padding: 0; display: flex; flex-direction: column; gap: var(--s2); }
/* Cap the thread at ~5 notes; scroll the rest so a long thread doesn't take
   over the card. (Newest are at the top.) */
.notes-list { max-height: 17rem; overflow-y: auto; padding-inline-end: 4px; }
.note-item { display: flex; align-items: flex-start; gap: var(--s2); }
.note-item .note-body { flex: 1; min-width: 0; }
.note-meta { font-size: var(--t-xs); color: var(--ink-soft); display: flex; gap: 6px; align-items: baseline; }
.note-text { font-size: var(--t-sm); color: var(--ink); line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.note-del { flex: none; }
.notes-empty { font-size: var(--t-xs); }
.notes-add { display: flex; align-items: center; gap: var(--s2); }
.notes-input-wrap { position: relative; flex: 1; min-width: 0; }
.notes-input-wrap input { width: 100%; min-width: 0; }

/* @-mention chip inside a saved note. */
.note-text .mention {
  color: var(--accent-ink); font-weight: 700;
  background: color-mix(in srgb, var(--seal) 12%, transparent);
  border-radius: 4px; padding: 0 3px; unicode-bidi: plaintext;
}
/* A note that mentions the current viewer — highlighted row. */
.note-item.is-mentioned {
  background: color-mix(in srgb, var(--seal) 9%, transparent);
  border-inline-start: 3px solid var(--seal);
  border-radius: var(--r-control); padding: 6px 8px; margin-inline-start: -2px;
}
.note-item.is-mentioned.is-flash { animation: kbReveal .25s ease; box-shadow: 0 0 0 3px color-mix(in srgb, var(--seal) 30%, transparent); }
.note-mention-tag { display: inline-flex; align-items: center; gap: 3px; color: var(--accent-ink); font-weight: 700; }
.note-mention-tag .lucide { color: var(--seal); }

/* @-mention picker dropdown (anchored under the composer input). */
.mention-pop {
  position: absolute; z-index: 30; inset-inline-start: 0; inset-inline-end: 0; top: calc(100% + 4px);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: var(--shadow-card); padding: 4px; max-height: 210px; overflow-y: auto;
}
.mention-opt {
  display: flex; align-items: center; gap: var(--s2); width: 100%;
  padding: 6px 8px; border: 0; background: transparent; cursor: pointer;
  border-radius: var(--r-control); text-align: start; color: var(--ink); font: inherit;
}
.mention-opt:hover, .mention-opt.is-active { background: var(--seal-wash); }
.mention-opt-name { font-weight: 600; font-size: var(--t-sm); }
.mention-opt-email { font-size: var(--t-xs); margin-inline-start: auto; }
.ws-upgrade { text-align: center; max-width: 560px; margin-inline: auto; padding: var(--s6) var(--s5); }
/* Settings tabs */
.settings-tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--line); margin-bottom: var(--s5); }
.stab { display: inline-flex; align-items: center; gap: 7px; padding: 10px 16px; background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--ink-soft); font: inherit; font-weight: 500; font-size: var(--t-sm); cursor: pointer; border-radius: var(--r-control) var(--r-control) 0 0; }
.stab:hover { color: var(--ink); background: var(--paper); }
.stab.is-active { color: var(--seal); border-bottom-color: var(--seal); }
.stab .lucide { flex: none; }
@media (max-width: 560px) { .stab span { display: none; } .stab { padding: 10px 14px; } }
.settings-panel[hidden] { display: none; }

/* Billing / subscription page */
.billing-card { max-width: 560px; margin-inline: auto; }
.billing-head { display: flex; align-items: flex-start; gap: var(--s4); margin-bottom: var(--s4); }
.billing-head h1 { font-size: var(--t-lg); margin: 0 0 4px; }
.billing-mark { flex: none; display: inline-grid; place-items: center; width: 48px; height: 48px; border-radius: 12px; background: var(--seal-wash); color: var(--seal); }
.billing-mark.ok { background: var(--ok-wash, #E7F3EC); color: var(--ok); }
.billing-meta { display: flex; gap: var(--s5); flex-wrap: wrap; margin: 0 0 var(--s4); }
.billing-meta dt { font-size: var(--t-xs); color: var(--ink-soft); margin-bottom: 2px; }
.billing-meta dd { margin: 0; font-weight: 700; color: var(--ink); }
.billing-trial { margin: 0 0 var(--s3); display: inline-flex; align-items: center; gap: 5px; }
.billing-secure { margin: var(--s3) 0 0; display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-xs); }
.billing-actions { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
.billing-cancel-form { margin: 0; }
.btn-cancel-sub { background: none; border: 0; padding: 0; font: inherit; color: var(--ink-soft); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.btn-cancel-sub:hover { color: #c0392b; }
.ws-upgrade-mark { color: var(--seal); display: inline-flex; }
.ws-upgrade-list { list-style: none; margin: var(--s4) auto; padding: 0; display: inline-flex; flex-direction: column; gap: var(--s2); text-align: start; }
.ws-upgrade-list li { display: flex; align-items: center; gap: var(--s2); color: var(--ink); }
.ws-upgrade-list .lucide { color: var(--ok); }
.auth-actions { display: flex; gap: var(--s2); margin-top: var(--s3); }

/* ---- Workspace settings forms ---- */
.ws-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s3); }
.ws-section-head h2 { margin: 0; }
.ws-seat-pill { display: inline-flex; align-items: center; gap: 5px; flex: none; padding: 4px 11px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line); }
.ws-rename { display: flex; gap: var(--s2); }
.ws-rename input { flex: 1; min-width: 0; }
.ws-name-static { font-weight: 700; color: var(--ink); margin: 0; }
/* Members + pending list */
.ws-members { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ws-member { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) 0; border-top: 1px solid var(--line); }
.ws-member:first-child { border-top: 0; }
.ws-member-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.ws-member-email { color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.ws-you-chip { font-size: var(--t-xs); color: var(--seal); background: var(--seal-wash); padding: 1px 8px; border-radius: 999px; font-weight: 600; }
.ws-member.is-invited .ws-member-email { color: var(--ink-soft); }
.ws-member-role { flex: none; }
.role-pill { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-xs); font-weight: 600; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft); }
.role-pill.role-owner { color: var(--seal); border-color: color-mix(in srgb, var(--seal) 30%, var(--line)); }
.role-pill.role-admin { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 30%, var(--line)); }
.role-select { font-size: var(--t-xs); font-weight: 600; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer; }
.role-select.role-owner { color: var(--seal); border-color: color-mix(in srgb, var(--seal) 30%, var(--line)); }
.role-select.role-admin { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 30%, var(--line)); }
.ws-icon-btn { flex: none; width: 30px; height: 30px; border-radius: 50%; border: 0; background: transparent; color: var(--ink-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.ws-icon-btn:hover { background: var(--paper); color: var(--bad); }
.wn-copy.ws-icon-btn:hover { color: var(--seal); }
/* Invite card */
.ws-invite { display: flex; flex-direction: column; gap: var(--s3); }
.ws-invite-emails textarea { width: 100%; resize: vertical; min-height: 52px; }
.ws-invite-emails textarea.is-invalid { border-color: var(--bad); box-shadow: 0 0 0 3px var(--bad-wash); }
.ws-invite-error { margin: 0; font-size: var(--t-sm); color: var(--bad); word-break: break-all; }
.ws-invite-foot { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.ws-invite-role { flex: none; display: inline-flex; align-items: center; gap: var(--s2); margin: 0; }
.role-inline-label { flex: none; font-size: var(--t-xs); font-weight: 600; color: var(--ink-soft); }
.ws-invite-foot .role-select { height: 40px; padding: 0 12px; }
.ws-invite-foot .btn-primary { height: 40px; }
.ws-invite-hint { font-size: var(--t-xs); display: inline-flex; align-items: flex-start; gap: 5px; margin: 0; }
.ws-sub { font-size: var(--t-sm); margin: var(--s5) 0 var(--s2); color: var(--ink); }
.ws-pending-list { margin-top: var(--s2); }
/* Teams-trial contact prompt (informational, not an error). */
.ws-trial-alert {
  display: flex; align-items: flex-start; gap: var(--s2);
  background: var(--seal-wash); border: 1px solid color-mix(in srgb, var(--seal) 30%, var(--line));
  color: var(--ink); border-radius: var(--r-control); padding: var(--s3) var(--s4); margin-bottom: var(--s4);
}
.ws-trial-alert .lucide { color: var(--seal); flex: none; margin-top: 2px; }
.ws-trial-alert a { color: var(--seal); font-weight: 700; }
/* Admin users table: badge for a user who's a non-owner member of a team. */
.member-team-badge {
  display: inline-flex; align-items: center; gap: 3px; vertical-align: middle;
  margin-inline-start: 5px; padding: 1px 8px; border-radius: 999px;
  font-size: var(--t-xs); font-weight: 600; white-space: nowrap;
  background: var(--seal-wash); color: var(--seal);
  border: 1px solid color-mix(in srgb, var(--seal) 25%, var(--line));
}
.member-team-badge.role-admin { background: var(--accent-wash); color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 25%, var(--line)); }
.member-team-badge .lucide { flex: none; }

/* ---- Admin workspace plan list ---- */
.ws-admin-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; }
.ws-admin-item + .ws-admin-item { border-top: 1px solid var(--line); }
.ws-admin-row { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--s4); cursor: pointer; }
.ws-admin-row:hover { background: var(--paper); }
.ws-admin-caret { color: var(--ink-soft); flex: none; transition: transform .15s ease; }
.ws-admin-row[aria-expanded="true"] .ws-admin-caret { transform: rotate(180deg); color: var(--accent); }
.ws-admin-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ws-admin-owner { font-weight: 700; color: var(--ink); }
.ws-admin-meta { font-size: var(--t-xs); display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.ws-admin-meta .lucide { vertical-align: middle; }
.ws-on { color: var(--ok); font-weight: 700; }
/* Segmented plan picker — click a segment to set the plan. */
.plan-seg { display: inline-flex; flex: none; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; background: var(--surface); }
.plan-seg .inline { margin: 0; }
.seg-btn { border: 0; background: transparent; padding: 6px 12px; font: inherit; font-size: var(--t-xs); font-weight: 600; color: var(--ink-soft); cursor: pointer; white-space: nowrap; }
.seg-btn:hover { background: var(--paper); color: var(--ink); }
.seg-btn.is-active { background: var(--seal); color: #fff; }
.seg-business.is-active { background: var(--ok); }
.ws-admin-detail { padding: var(--s3) var(--s5) var(--s4); background: var(--paper); border-top: 1px dashed var(--line); }
.ws-team-list { list-style: none; margin: 0 0 var(--s3); padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ws-team-list li { display: flex; align-items: center; gap: var(--s2); font-size: var(--t-sm); }
.ws-team-email { flex: 1; min-width: 0; color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.role-ic { flex: none; display: inline-flex; }
.role-owner { color: var(--seal); }
.role-admin { color: var(--accent-ink); }
.role-member { color: var(--ink-soft); }
.invited-chip { flex: none; display: inline-flex; align-items: center; gap: 3px; font-size: var(--t-xs); color: var(--check); background: var(--check-wash); padding: 1px 8px; border-radius: 999px; }
.ws-team-list li.is-invited .ws-team-email { color: var(--ink-soft); }
.ws-seat-form { display: flex; align-items: center; gap: var(--s2); }

/* ---------- Cards ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-card); }
.section-title { margin: var(--s6) 0 var(--s4); display: flex; align-items: baseline; gap: var(--s3); }
.section-title .count { color: var(--ink-soft); font-size: var(--t-sm); font-family: var(--font-body); }

/* ---------- Score seal ---------- */
.seal { position: relative; display: inline-grid; place-items: center; }
.seal svg { display: block; transform: rotate(0deg); }
.seal .seal-num { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.seal .seal-num b { font-family: var(--font-display); color: var(--seal); line-height: 1; }
.seal .seal-tier { position: absolute; left: 0; right: 0; bottom: 0; text-align: center;
  font-size: 7.87px; letter-spacing: .05em; text-transform: uppercase; color: #333333; white-space: nowrap; }
/* Hebrew has no case and its glyphs are denser — drop the letter-spacing that
   suits English caps. */
[dir="rtl"] .seal .seal-tier { letter-spacing: 0; }
.seal.size-lg .seal-num { place-content: center; transform: translateY(-2px); }
.seal.size-lg .seal-num b { font-size: 25.3px; }
.seal.size-sm .seal-num b { font-size: 16.5px; }

/* ---------- Fit Card (תעודת התאמה) ---------- */
.fitcard { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-card); overflow: hidden; }
.fitcard + .fitcard { margin-top: var(--s5); }
.fitcard-head { display: flex; gap: var(--s4); padding: var(--s4) var(--s5); align-items: flex-start; }
.fitcard-head .seal { flex: none; }
.fitcard-main { flex: 1; min-width: 0; }
.fitcard-title { font-family: var(--font-display); font-size: var(--t-md); color: var(--ink); margin: 0 0 6px; }
/* "חדש" corner ribbon — tenders added to the system in the last 24h. A light-red
   diagonal banner across the top-left corner of the card (clipped by the card's
   overflow:hidden), so it's highly visible without covering any tender text.
   Tooltip on hover explains it. */
.new-ribbon {
  position: absolute; top: 14px; left: -44px; z-index: 2;
  width: 140px; text-align: center; transform: rotate(-45deg);
  background: #f4a9a9; color: #7a1414;
  font-family: var(--font-body); font-size: 11px; font-weight: 700;
  letter-spacing: 0.04em; padding: 3px 0; cursor: default;
  box-shadow: 0 1px 3px rgb(28 43 51 / 0.18);
}
/* When the ribbon is present, push the card head clear of the corner so a long
   title never tucks under the diagonal banner (RTL: long lines reach the left
   corner where the ribbon sits). */
.new-ribbon + .fitcard-head { padding-top: 42px; }
.new-ribbon + .fitcard-head .seal { margin-top: -6px; }
/* Two predictable rows under the title: primary signal (verdict + deadline)
   on its own row so it doesn't shift with the publisher line length. */
.fitcard-status { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); margin: 0 0 6px; font-size: var(--t-sm); }
.fitcard-status .verdict-ok { color: var(--ok); font-weight: 700; }
.fitcard-status .verdict-no { color: var(--accent-ink); font-weight: 700; }
.fitcard-context { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--s2); color: var(--ink-soft); font-size: var(--t-sm); }
/* Center each label's icon with its text (icons were sitting slightly high on
   the baseline) — applies wherever these card meta rows render. */
.fitcard-status span, .fitcard-context span { display: inline-flex; align-items: center; gap: 4px; }
.fitcard-status span .lucide, .fitcard-context span .lucide { margin: 0; }
.fitcard-context .dot { color: var(--line); }
.fitcard-summary { margin: var(--s3) 0 0; color: var(--ink); }
/* Key-facts strip under the summary — the real cards' compact inline facts
   (label: value), wrapping so the card stays its normal height. Middots keep
   each fact distinct. */
.fitcard-keyfacts { margin-top: var(--s3); display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--s3); font-size: var(--t-sm); color: var(--ink-soft); }
.fitcard-keyfacts span { display: inline-flex; align-items: center; gap: 5px; }
.fitcard-keyfacts b { color: var(--ink); font-weight: 700; }
.fitcard-keyfacts .kf-sep { color: var(--line); }
.fitcard-keyfacts a { color: var(--seal); font-weight: 700; }
.fitcard-keyfacts a .lucide, .fitcard-keyfacts span .lucide { color: var(--seal); }
/* Demo card footer: secondary metadata split out of the strip (document + tour). */
.fitcard-foot .ff-doc, .fitcard-foot .ff-meta { display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-sm); color: var(--ink-soft); }
.fitcard-foot .ff-doc a { color: var(--seal); font-weight: 700; }
.fitcard-foot .ff-doc .lucide, .fitcard-foot .ff-meta .lucide { color: var(--seal); }
.fitcard-foot .ff-meta b { color: var(--ink); font-weight: 700; }
.fitcard-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); padding: var(--s3) var(--s5); border-top: 1px solid var(--line); background: var(--paper); }
.fitcard-actions { display: inline-flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.fitcard-actions .hide-form { display: inline-flex; margin: 0; }
.fitcard-actions .btn { padding: 6px var(--s3); font-size: var(--t-sm); }
.hide-btn { color: var(--ink-soft); }
.hide-btn:hover { color: var(--bad); background: var(--bad-wash); }
/* Save / bookmark toggle: outline when unsaved, filled accent when saved. */
.save-btn { color: var(--ink-soft); }
.save-btn:hover { color: var(--accent-ink); background: rgba(232, 101, 13, 0.08); }
.save-btn.is-saved { color: var(--accent); }
.save-btn.is-saved .lucide { fill: var(--accent); }
/* Inline AJAX save in progress: the spinner replaces the bookmark glyph so the
   click registers immediately while the save persists (no full page reload). */
.save-btn.is-loading { position: relative; }
.save-btn.is-loading svg { visibility: hidden; }
.save-btn.is-loading::before { position: absolute; top: 50%; inset-inline-start: 50%; margin: -7px 0 0 -7px; }
.saved-chip { border-color: var(--accent); background: rgba(232, 101, 13, 0.10); color: var(--accent-ink); }

/* ---------- Admin tabs ---------- */
.admin-tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--line);
  margin: var(--s4) 0; }
.admin-tab { display: inline-flex; align-items: center; gap: 6px; background: none; border: 0;
  border-bottom: 2px solid transparent; padding: var(--s3) var(--s4); margin-bottom: -1px;
  font: inherit; font-weight: 500; color: var(--ink-soft); cursor: pointer; }
.admin-tab:hover { color: var(--ink); }
.admin-tab.is-active { color: var(--accent-ink); border-bottom-color: var(--accent); }
.tab-panel[hidden] { display: none; }
.tab-panel > .section-title:first-child { margin-top: 0; }
/* Client-sorted admin tables */
.sortable-table th.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.sortable-table th.th-sort:hover { color: var(--accent-ink); }
.sortable-table th.th-sort.sorted::after { content: "▾"; font-size: .7em; margin-inline-start: 4px; }
.sortable-table th.th-sort.sorted[data-dir="asc"]::after { content: "▴"; }

/* ---------- Admin feature flags ---------- */
.admin-hint { margin-bottom: var(--s3); font-size: var(--t-sm); }
.flag-row { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); padding: var(--s3) 0; border-top: 1px solid var(--line); }
.flag-row:first-of-type { border-top: 0; }
.flag-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.flag-label { font-weight: 600; }
.flag-info .muted { font-size: var(--t-sm); }
/* Collapsible group cards. Same <details> idiom as the profile settings, so the
   two admin-ish surfaces read the same way. */
.flag-group { border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface); overflow: hidden; margin-block-end: var(--s3); }
.flag-group + .flag-group { margin-block-start: 0; }
.flag-group > summary { display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s4); cursor: pointer; list-style: none;
  font-weight: 600; user-select: none; }
.flag-group > summary::-webkit-details-marker { display: none; }
.flag-group > summary::marker { content: ""; }
.flag-group > summary:hover { background: var(--paper); }
.flag-group > summary:focus-visible { outline: 2px solid var(--seal); outline-offset: -2px; }
.fg-chev { flex: 0 0 auto; color: var(--ink-soft); transition: transform .15s ease; }
.flag-group[open] .fg-chev { transform: rotate(90deg); }
.fg-name { flex: 1 1 auto; }
/* Count as a quiet pill, so the header reads name-first and the number is a
   detail rather than competing with it. */
.fg-count { flex: 0 0 auto; min-width: 1.5rem; text-align: center;
  padding: 1px 7px; border-radius: 999px; background: var(--paper);
  color: var(--ink-soft); font-size: var(--t-xs); font-weight: 600;
  font-variant-numeric: tabular-nums; }
.flag-group[open] > summary { border-block-end: 1px solid var(--line); }
/* Rows live inside the card now: the card's border is the only outer rule. */
.flag-group .flag-row { padding-inline: var(--s4); border-top: 1px solid var(--line); }
.flag-group .flag-row:first-of-type { border-top: 0; }
/* RTL: the chevron points into the text, so it flips with the writing mode. */
[dir="rtl"] .fg-chev { transform: scaleX(-1); }
[dir="rtl"] .flag-group[open] .fg-chev { transform: scaleX(-1) rotate(-90deg); }
/* Compact toggle switch (replaces the bulky checkbox + save button). */
.switch { position: relative; flex: none; cursor: pointer; line-height: 0; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track { display: inline-block; width: 40px; height: 22px; border-radius: 999px;
  background: var(--line); transition: background .15s; position: relative; }
.switch-track::after { content: ""; position: absolute; top: 2px; inset-inline-start: 2px;
  width: 18px; height: 18px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.25); transition: inset-inline-start .15s; }
.switch input:checked + .switch-track { background: var(--accent); }
.switch input:checked + .switch-track::after { inset-inline-start: 20px; }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--seal); outline-offset: 2px; }

/* ---------- Dashboard unlock banner (flagged) ---------- */
.unlock-banner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4);
  margin-bottom: var(--s5); padding: var(--s3) var(--s4);
  border: 1px solid var(--accent); border-radius: var(--r-card); background: var(--accent-wash); }
.ub-title { display: inline-flex; align-items: center; gap: 6px; font-weight: 700;
  font-size: var(--t-sm); color: var(--accent-ink); }
.ub-title .ic { color: var(--accent); }
.ub-items { display: flex; flex-wrap: wrap; gap: 6px; }
.ub-item { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--accent); background: var(--surface); font-size: var(--t-sm); font-weight: 600;
  color: var(--ink); transition: background .15s ease, color .15s ease; }
.ub-item:hover { background: var(--accent-fill); color: var(--on-accent); text-decoration: none; }
.ub-item .ub-count { font-family: var(--font-display); color: var(--accent); }
.ub-item:hover .ub-count { color: #fff; }

/* Hidden-card fade-out (smooth dismissal feel when a card disappears post-hide) */
.fitcard.fading-out { animation: fade-out .26s ease forwards; }
@keyframes fade-out { to { opacity: 0; transform: translateY(-4px); } }

/* Browse: hidden rows */
.row-hidden { opacity: .58; }
.row-hidden td { background: var(--paper); }
.row-actions { white-space: nowrap; }
.row-actions .inline { display: inline-flex; margin: 0; }
.row-actions .btn { padding: 4px var(--s3); }
/* "למקור המכרז" keeps its text while the actions column is wide enough, and
   collapses to an icon-only button (tooltip preserved) once the column gets too
   narrow — so the label never spills past the cell edge. The browse table
   carries three action buttons so it tightens first (~900px); the demo table
   has fewer buttons and can hold the label down to ~780px. */
@media (max-width: 900px) {
  .row-actions .btn-label { display: none; }
}
@media (min-width: 781px) and (max-width: 900px) {
  .demo-body .row-actions .btn-label { display: inline; }
}
.hidden-chip { background: var(--paper); border-color: var(--line); color: var(--ink-soft); }

details.fitcard-details > summary { list-style: none; cursor: pointer; color: var(--accent-ink); font-weight: 600; font-size: var(--t-sm); display: flex; align-items: center; gap: 6px; padding: var(--s3) var(--s5); }
details.fitcard-details > summary:hover { background: var(--paper); }
details.fitcard-details > summary::-webkit-details-marker { display: none; }
details.fitcard-details > summary .chev { transition: transform .18s ease; }
details.fitcard-details[open] > summary .chev { transform: rotate(180deg); }

.conditions { display: grid; gap: var(--s4); padding: var(--s4) var(--s5) var(--s5); border-top: 1px dashed var(--line); }
.cond-group h4 { display: flex; align-items: center; gap: 6px; font-family: var(--font-body); font-size: var(--t-sm); font-weight: 700; margin: 0 0 var(--s2); }
.cond-group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.cond-group li { display: flex; gap: var(--s2); align-items: flex-start; font-size: var(--t-sm); }
.cond-group li .ic { flex: none; margin-top: 2px; }
.cond-ok h4 { color: var(--ok); } .cond-ok .ic { color: var(--ok); }
.cond-bad h4 { color: var(--bad); } .cond-bad .ic { color: var(--bad); }
.cond-check h4 { color: var(--check); } .cond-check .ic { color: var(--check); }
.fitcard-extra { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5); padding: 0 var(--s5) var(--s4); color: var(--ink-soft); font-size: var(--t-sm); }
.fitcard-extra b { color: var(--ink); font-weight: 600; }
.fitcard-enrichment { padding: 0 var(--s5) var(--s3); display: flex; flex-direction: column; gap: var(--s3); }

/* ---------- Readiness (action plan) — behind the "readiness" flag ---------- */
/* A distinct but quiet summary tile: a neutral (not coloured) inset so it reads
   as a separate block from the flat condition lists below — the level colour
   shows only through the inline-start accent, the badge, and the gauge bar. */
.readiness { margin: var(--s4) var(--s5) 0; padding: var(--s3) var(--s4);
  background: var(--paper); border-radius: var(--r-control);
  border-inline-start: 3px solid var(--line); display: grid; gap: 7px; }
/* Decision summary promoted onto the collapsed UK fit card (above the expandable
   details): needs the bottom margin the in-details copy didn't. */
.fitcard-readiness { margin-bottom: var(--s3); }
.readiness .rd-top { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.rd-badge { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: var(--t-sm); }
.rd-frac { font-weight: 600; font-size: var(--t-xs); color: var(--ink-soft); }
/* clear · to verify · gaps tally (replaces the bare X/X on the UK panel) */
.rd-tally { font-size: var(--t-xs); color: var(--ink-soft); white-space: nowrap; }
.rd-tally b { font-weight: 700; }
.rd-tally .t-ok { color: var(--ok); }
.rd-tally .t-check { color: var(--check); }
.rd-tally .t-bad { color: var(--bad); }
.rd-tally .t-none { color: var(--ink-soft); }
.rd-bar { height: 3px; border-radius: 999px; background: var(--line); overflow: hidden; }
.rd-bar > span { display: block; height: 100%; border-radius: 999px; transition: width .5s ease; }
.rd-sub { margin: 0; font-size: var(--t-xs); line-height: 1.5; color: var(--ink-soft); }
.rd-cta { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-size: var(--t-sm); font-weight: 600; color: var(--accent-ink); }
.rd-cta:hover { text-decoration: underline; }
/* One-click "I have this" quick-add of a required certification. */
.rd-quickadd { display: grid; gap: 6px; }
.rd-qa-label { display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-xs);
  font-weight: 600; color: var(--ink-soft); }
.rd-qa-label .ic { color: var(--ok); }
.rd-qa-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.rd-qa-form { margin: 0; }
.rd-qa-btn { display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: var(--t-xs); font-weight: 600; color: var(--ink); padding: 3px 10px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  transition: background .15s ease, color .15s ease, border-color .15s ease; }
.rd-qa-btn:hover { background: var(--ok); border-color: var(--ok); color: #fff; }
.rd-qa-btn:hover .lucide { color: #fff; }
.rd-qa-btn .lucide { color: var(--ok); }
/* On the UK collapsed card the quick-add sits directly under the read-only
   requirement lists and was blending into them. Set it apart as a tinted,
   bordered action callout so it clearly reads as "do something" rather than
   another checklist line. (Scoped to the UK fit card; IL is unchanged.) */
.fitcard-readiness .rd-quickadd { margin-top: var(--s2); padding: var(--s2) var(--s3);
  background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 28%, var(--line));
  border-radius: var(--r-control); }
.fitcard-readiness .rd-qa-label { color: var(--accent-ink); }
.fitcard-readiness .rd-qa-label .ic { color: var(--accent-ink); }
/* Responsibility reminder shown only when the panel reads "ready". */
.rd-disclaimer { display: flex; align-items: flex-start; gap: 5px; margin: 2px 0 0;
  font-size: var(--t-xs); line-height: 1.45; color: var(--ink-soft);
  border-top: 1px solid var(--line); padding-top: 6px; }
.rd-disclaimer .ic { flex: none; margin-top: 2px; color: var(--ink-soft); }
/* Bid-prep note: attach-at-submission items (past projects, procedural docs) —
   informational, quieter than the met/verify rows and outside the verdict. */
.rd-prep { display: flex; align-items: flex-start; gap: 5px; margin: 2px 0 0;
  font-size: var(--t-xs); line-height: 1.45; color: var(--ink-soft);
  border-top: 1px solid var(--line); padding-top: 6px; }
.rd-prep .ic { flex: none; margin-top: 2px; color: var(--ink-soft); }
/* Per-level accent: the inline-start rule + badge + bar fill carry the colour. */
.rd-ready { border-inline-start-color: var(--ok); }
.rd-ready .rd-badge, .rd-ready .rd-badge .ic { color: var(--ok); }
.rd-ready .rd-bar > span { background: var(--ok); }
.rd-almost { border-inline-start-color: var(--check); }
.rd-almost .rd-badge, .rd-almost .rd-badge .ic { color: var(--check); }
.rd-almost .rd-bar > span { background: var(--check); }
.rd-blocked { border-inline-start-color: var(--bad); }
.rd-blocked .rd-badge, .rd-blocked .rd-badge .ic { color: var(--bad); }
.rd-blocked .rd-bar > span { background: var(--bad); }
.rd-none .rd-badge { color: var(--ink-soft); }

/* UK eligibility verdict badge (T1.3) — compact met/gap chip on the fit card. */
.uk-elig-verdict { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  margin: var(--s3) var(--s5) 0; font-size: var(--t-sm); }
.uk-elig-verdict .uev-badge { display: inline-flex; align-items: center; gap: 6px;
  font-weight: 600; }
.uk-elig-verdict .uev-gaps { color: var(--ink-soft); }
.uk-elig-verdict.elig-ready .uev-badge, .uk-elig-verdict.elig-ready .uev-badge .ic { color: var(--ok); }
.uk-elig-verdict.elig-almost .uev-badge, .uk-elig-verdict.elig-almost .uev-badge .ic { color: var(--check); }
.uk-elig-verdict.elig-blocked .uev-badge, .uk-elig-verdict.elig-blocked .uev-badge .ic { color: var(--bad); }

/* Score-seal gauge draw-on: the value bar grows to the score and the hollow
   indicator rides its tip, both on load. */
.seal-gfill { animation: gaugeFill .55s ease-out both; }
@keyframes gaugeFill { from { stroke-dasharray: 0 999; } }
.seal-gdot { animation: gaugeDot .55s ease-out both; }
@keyframes gaugeDot { from { transform: rotate(135deg); } }

/* Dashboard stagger-in */
.fade-rise { opacity: 0; transform: translateY(8px); animation: fadeRise .4s ease forwards; }
@keyframes fadeRise { to { opacity: 1; transform: none; } }

/* ---------- Page head ---------- */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4); margin-bottom: var(--s5); flex-wrap: wrap; }
/* The title block keeps the row to itself: when the toolbar (Stage + Sort on UK)
   can't fit beside a comfortable title width, it wraps to its own line rather
   than squeezing "Tenders that fit you" onto two lines. Capped at 100% so on a
   phone the heading just goes full-width (no horizontal overflow) and the
   toolbar — which wraps its own groups — drops underneath. */
.page-head-main { flex: 0 1 auto; min-width: min(100%, 24rem); }
.page-sub { margin: var(--s2) 0 0; font-size: var(--t-sm); }

/* Sort toggle (segmented control) */
.dash-toolbar { display: flex; align-items: center; gap: var(--s4) calc(var(--s4) + 20px); flex-wrap: wrap; }
.sort-toggle { display: inline-flex; align-items: center; gap: var(--s2); flex-shrink: 0; }
.sort-label { display: inline-flex; align-items: center; gap: 3px; font-size: var(--t-xs); color: var(--ink-soft); font-weight: 500; }
.sort-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); padding: 2px; }
.sort-seg .sort-opt {
  padding: 3px 10px; border-radius: 999px;
  color: var(--ink-soft); font-size: var(--t-xs); font-weight: 600; line-height: 1.4;
  white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.sort-seg .sort-opt:hover { color: var(--ink); text-decoration: none; }
.sort-seg .sort-opt.is-active { background: var(--accent-fill); color: var(--on-accent); }
/* On phones the labels ("Procurement stage", "Sort") + the multi-word stage
   pills push a single group past the viewport. Drop the text labels — the pills
   are self-describing — so each group fits and the toolbar can't widen the page.
   (Same approach as the .stab control above.) */
@media (max-width: 560px) {
  .dash-toolbar .sort-label { display: none; }
  .dash-toolbar { gap: var(--s3); }
}

.match-list { display: flex; flex-direction: column; gap: var(--s5); }
/* Save-from-matches: the card swipes left and fades, then collapses so the list
   closes the gap. Applied to the .fade-rise wrapper around each card. */
.match-list .fade-rise.is-swiping {
  transition: transform .34s ease, opacity .34s ease;
  transform: translateX(-115%); opacity: 0; pointer-events: none;
}
.match-list .fade-rise.is-removing {
  transition: max-height .26s ease, margin .26s ease, opacity .26s ease;
  max-height: 0 !important; margin: 0 !important; opacity: 0; overflow: hidden;
}
/* Disappearing confirmation toast (e.g. "moved to saved list"). */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 16px);
  z-index: 1000; max-width: 90vw;
  background: var(--ink); color: #fff; font-size: var(--t-sm); font-weight: 500;
  padding: 10px 18px; border-radius: 999px; box-shadow: 0 6px 24px rgb(28 43 51 / 0.28);
  display: inline-flex; align-items: center; gap: 8px;
  opacity: 0; transition: opacity .25s ease, transform .25s ease;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast .ic { color: var(--ok); display: inline-flex; }
@media (prefers-reduced-motion: reduce) {
  .match-list .fade-rise.is-swiping, .match-list .fade-rise.is-removing, .toast { transition: none; }
}

/* Dashboard is a focused work queue — keep it to a comfortable reading column. */
.work-queue { max-width: 760px; margin-inline: auto; }
.work-queue .fitcard-title { font-size: var(--t-lg); }
.work-queue .fitcard-summary { max-width: 60ch; }

/* ---------- Tables (browse / admin) ---------- */
/* overflow must stay visible (not auto) or it becomes a scroll container and
   the page-level sticky <thead> stops working. The 5-column table fits the
   container at desktop widths; mobile switches to the card layout below. */
.table-wrap { overflow: visible; border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface); }

/* Pagination */
.pager { display: flex; align-items: center; justify-content: center; gap: var(--s3); margin-top: var(--s5); flex-wrap: wrap; }
.pager-btn { display: inline-flex; align-items: center; gap: 4px; padding: 6px var(--s3); border-radius: var(--r-control); border: 1px solid var(--line); color: var(--ink); font-size: var(--t-sm); font-weight: 600; }
.pager-btn:hover { background: var(--paper); text-decoration: none; }
.pager-btn.is-disabled { color: var(--ink-soft); opacity: .5; pointer-events: none; }
/* RTL: "הקודם" (prev) points right, "הבא" (next) points left. The chevron icon
   points down by default — rotate it to horizontal arrows. */
/* Down-chevron rotated to a horizontal arrow. RTL: prev → right ›, next → left ‹.
   LTR mirrors it: prev → left ‹, next → right ›. */
.pager-prev { transform: rotate(-90deg); }
.pager-next { transform: rotate(90deg); }
[dir="ltr"] .pager-prev { transform: rotate(90deg); }
[dir="ltr"] .pager-next { transform: rotate(-90deg); }
.pager-pages { display: inline-flex; align-items: center; gap: 2px; }
.pager-num { min-width: 30px; text-align: center; padding: 6px 8px; border-radius: var(--r-control); color: var(--ink-soft); font-size: var(--t-sm); font-weight: 600; }
.pager-num:hover { background: var(--paper); color: var(--ink); text-decoration: none; }
.pager-num.is-current { background: var(--accent-fill); color: var(--on-accent); }
table.data { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
/* Locked column widths (via the colgroup) so expanding a row never reflows the
   table; the actions column is sized to fit 'למקור המכרז' + icons on one line.
   Long detail tokens break so the detail cell can't widen anything either. */
table.data.tenders-table { table-layout: fixed; }
/* break-word (not anywhere): only chop a token that truly can't fit; normal
   multi-word text still wraps at spaces, so values never split mid-word. */
.t-detail, .t-detail * { overflow-wrap: break-word; }
table.data th, table.data td { padding: var(--s3) var(--s4); text-align: start; border-bottom: 1px solid var(--line); vertical-align: middle; }
/* Pin the column headers below the sticky topbar (~61px) while scrolling a
   long table; a bottom border keeps them legible over the rows beneath. */
table.data thead th { position: sticky; top: 64px; z-index: 20; background: var(--paper); color: var(--ink-soft); font-weight: 700; font-size: var(--t-xs); box-shadow: inset 0 -1px 0 var(--line); }
table.data th.sortable { padding: 0; }
table.data th.sortable a {
  display: flex; align-items: center; gap: 4px; padding: var(--s3) var(--s4);
  color: inherit; text-decoration: none; transition: color .12s;
}
table.data th.sortable a:hover { color: var(--ink); text-decoration: none; background: var(--surface); }
table.data th.sort-active a { color: var(--accent-ink); }
/* flex-shrink: 0 is the whole fix. The header link is `display: flex`, so the
   chevron is a flex item, and an SVG sized only by its viewBox has a
   min-content width of 0 — it shrank to nothing and the active column
   looked unsorted. It rendered, it was visible, it was 0px wide. */
.sort-arrow { flex: 0 0 auto; transition: transform .12s ease; opacity: .9; }
.sort-arrow.asc { transform: rotate(180deg); }
table.data tbody tr:hover { background: var(--paper); }
table.data tbody tr:last-child td { border-bottom: none; }
/* Buyer/publisher names can be very long ("The Common Services Agency (more
   commonly known as …) (PSD Scotland)"); the fixed-layout column would wrap and
   bloat the row. Keep it to one line with an ellipsis — the full name shows in
   the title tooltip and in the expanded row. */
table.data.tenders-table td.t-pub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-expired { opacity: .55; }
/* overflow-wrap: a buyer occasionally publishes a bare URL as the title (see
   app/notice_title.py). An unbroken string offers no wrap opportunity, so
   max-width alone can't contain it and the cell overruns the table. The title
   guard fixes the data going forward; this keeps the layout safe regardless. */
.t-title { font-weight: 500; color: var(--ink); max-width: 46ch; overflow-wrap: anywhere; }
/* Discriminator for batch-published notices sharing one title (see
   app/notice_variant.py). Secondary to the title, indented past the caret. */
.t-variant {
  font-size: .82em; color: var(--muted); max-width: 46ch; overflow-wrap: anywhere;
  margin-top: 2px; padding-inline-start: 20px; line-height: 1.35;
}
.status-dot { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.status-dot::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink-soft); }
.status-dot.ok::before { background: var(--ok); }
.status-dot.failed::before { background: var(--bad); }
.status-dot.running::before { background: var(--check); }

/* ---------- Admin stats ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s4); }
.stat-card { padding: var(--s5); }
.stat-card.stat-alert { border-color: var(--bad); background: var(--bad-wash); }
.stat-label { color: var(--ink-soft); font-size: var(--t-sm); }
.stat-value { font-family: var(--font-display); font-size: var(--t-lg); margin-top: 4px; }
.stat-flag { color: var(--bad); font-size: var(--t-xs); margin-top: 6px; display: flex; align-items: center; gap: 4px; }
.err { font-size: var(--t-xs); }
form.inline { display: inline; }

/* ---------- Empty state ---------- */
.empty { text-align: center; padding: var(--s7) var(--s5); color: var(--ink-soft); background: var(--surface); border: 1px dashed var(--line); border-radius: var(--r-card); }
.empty h3 { color: var(--ink); margin-bottom: var(--s2); }

/* Post-onboarding "matching in progress" loading state on the dashboard. */
.match-loading { text-align: center; padding: var(--s7) var(--s5); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); }
.match-loading h3 { color: var(--ink); margin: var(--s4) 0 var(--s2); }
.match-loading p { margin: 0; }
.match-loading-spin {
  display: inline-block; width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid var(--seal-wash); border-top-color: var(--seal);
  animation: matchSpin .8s linear infinite;
}
@keyframes matchSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .match-loading-spin { animation-duration: 2s; } }

/* ---------- Public (SEO) pages: browse + tender detail ---------- */
.crumbs { font-size: var(--t-sm); color: var(--ink-soft); margin-bottom: var(--s3); }
.crumbs a { color: var(--accent-ink); }
.crumb-sep { margin-inline: 6px; color: var(--ink-soft); }
.cat-nav { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s5); }
.cat-chip { padding: 5px var(--s3); border-radius: 999px; border: 1px solid var(--line); font-size: var(--t-sm); color: var(--ink); background: var(--surface); }
.cat-chip:hover { border-color: var(--seal); text-decoration: none; }
.cat-chip.is-active { background: var(--seal); border-color: var(--seal); color: #fff; }
.pub-link { color: var(--ink); font-weight: 500; }
.pub-link:hover { color: var(--accent-ink); }
.cat-cell { color: var(--ink-soft); }
.pub-note { font-size: var(--t-xs); margin-top: var(--s3); }
.pub-cta { text-align: center; margin: var(--s7) auto 0; max-width: 600px; padding: var(--s6) var(--s5); background: var(--seal-wash); border-radius: var(--r-card); }
.pub-cta h2 { margin-bottom: var(--s2); }
.pub-cta p { color: var(--ink-soft); margin-bottom: var(--s4); }
.pub-tender-head h1 { font-size: var(--t-lg); }
.pub-tender-meta { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; margin-top: var(--s2); color: var(--ink-soft); font-size: var(--t-sm); }
.pub-tender-meta > span { display: inline-flex; align-items: center; gap: 5px; }
.pub-tender-body { display: grid; grid-template-columns: 1fr 300px; gap: var(--s5); margin-top: var(--s5); align-items: start; }
.pub-tender-summary { font-size: var(--t-md); line-height: 1.6; }
.pub-tender-side { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s4); display: flex; flex-direction: column; gap: var(--s3); }
@media (max-width: 720px) { .pub-tender-body { grid-template-columns: 1fr; } }
.pub-gate { text-align: center; padding: var(--s6) var(--s5); background: var(--seal-wash); border: 1px solid var(--line); border-radius: var(--r-card); }
.pub-gate-ic { display: inline-grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: var(--surface); color: var(--seal); margin-bottom: var(--s3); }
.pub-gate h2 { font-size: var(--t-md); margin-bottom: var(--s2); }
.pub-gate p { color: var(--ink-soft); margin-bottom: var(--s4); }
.pub-gate-alt { font-size: var(--t-sm); margin-top: var(--s3); margin-bottom: 0; }
.pub-gate-alt a { color: var(--accent-ink); }
/* Trial-countdown bar for signed-in trial users (every app page). */
.trial-bar { background: var(--accent-wash); border-bottom: 1px solid var(--line); }
.trial-bar.is-expired { background: #FDECEC; }
.trial-bar-inner { max-width: var(--maxw); margin-inline: auto; padding: 8px var(--s5);
  display: flex; align-items: center; justify-content: center; gap: var(--s3);
  flex-wrap: wrap; text-align: center; font-size: var(--t-sm); color: var(--ink); }
.trial-bar .lucide { color: var(--accent); flex: none; }
.trial-bar b { font-weight: 700; }
.trial-bar-cta { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap;
  font-weight: 700; color: var(--accent-ink); }
.trial-bar-cta:hover { text-decoration: underline; }
.trial-bar-x { margin-inline-start: var(--s2); flex: none; width: 26px; height: 26px;
  border-radius: 50%; border: 0; cursor: pointer; color: var(--accent-ink);
  background: rgba(177, 74, 5, .14); display: inline-flex; align-items: center; justify-content: center; }
.trial-bar-x:hover { background: rgba(177, 74, 5, .26); color: var(--accent-ink); }

/* ---- "What's new" panel ---- */
.whatsnew { padding: var(--s4) var(--s5) 0; }
.whatsnew-inner {
  max-width: var(--maxw); margin-inline: auto; position: relative;
  background: linear-gradient(180deg, var(--seal-wash), var(--surface));
  border: 1px solid color-mix(in srgb, var(--seal) 25%, var(--line));
  border-radius: var(--r-card); box-shadow: var(--shadow-card);
  padding: var(--s4) var(--s5); animation: kbReveal .2s ease;
}
.wn-head { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s3); }
.wn-badge {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  padding: 2px 10px; border-radius: 999px; font-size: var(--t-xs); font-weight: 700;
  background: var(--seal); color: #fff;
}
.wn-badge .lucide { color: #fff; }
.wn-title { font-family: var(--font-display); font-weight: 400; font-size: var(--t-md); color: var(--ink); }
.wn-x {
  margin-inline-start: auto; flex: none; width: 28px; height: 28px; border-radius: 50%;
  border: 0; cursor: pointer; color: var(--ink-soft); background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
}
.wn-x:hover { background: var(--paper); color: var(--ink); }
.wn-intro { margin: 0 0 var(--s3); font-size: var(--t-sm); color: var(--ink-soft); line-height: 1.55; }
.wn-intro a { color: var(--accent-ink); font-weight: 700; }
.wn-items { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.wn-items li { display: flex; align-items: flex-start; gap: var(--s2); font-size: var(--t-sm); color: var(--ink); line-height: 1.5; }
.wn-items li b { font-weight: 700; }
.wn-ic { flex: none; color: var(--seal); margin-top: 1px; }
.wn-foot { margin-top: var(--s3); }
/* Nav nudge: the tab breathes until its 'what's new' panel is dismissed. A new
   nav item nobody clicks is a feature nobody has. Box-shadow only — animating a
   filter or transform on a flex nav item makes the whole bar shift by a pixel,
   and the halo takes the accent from a token so it is the product's orange in
   both themes rather than a colour picked in isolation. */
.nav a.nav-glow { animation: nav-glow 2.4s ease-in-out infinite; }
@keyframes nav-glow {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 3px var(--accent-glow); }
}
@media (prefers-reduced-motion: reduce) {
  .nav a.nav-glow { animation: none; box-shadow: 0 0 0 2px var(--accent-glow); }
}
.wn-ok {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 14px; border-radius: 999px; cursor: pointer;
  font-size: var(--t-sm); font-weight: 600; line-height: 1;
  color: var(--accent-ink); background: transparent;
  border: 1px solid color-mix(in srgb, var(--seal) 32%, var(--line));
  transition: background .15s ease, border-color .15s ease;
}
.wn-ok:hover { background: var(--seal-wash); border-color: color-mix(in srgb, var(--seal) 50%, var(--line)); }
.wn-ok .lucide { color: var(--seal); }

/* Launch offer banner under the header (landing only). Dark & premium — slim
   navy bar, the offer glowing in orange, a sleek pill CTA. */
.promo-banner { background: linear-gradient(100deg, #14202A 0%, #1E2E3A 100%);
  color: #E9EDEA; border-bottom: 1px solid rgba(255,255,255,.08); }
.promo-banner-inner { max-width: var(--maxw); margin-inline: auto; padding: 9px var(--s5);
  display: flex; align-items: center; justify-content: center; gap: var(--s3);
  flex-wrap: wrap; text-align: center; font-size: var(--t-sm); color: #E9EDEA; }
.promo-badge { display: inline-flex; align-items: center; gap: 5px; flex: none;
  background: rgba(255,255,255,.10); color: #fff; font-weight: 700; font-size: var(--t-xs);
  padding: 3px 10px; border-radius: 999px; letter-spacing: .2px; }
.promo-badge .lucide { color: var(--accent); }
.promo-msg b { color: #FF8A3D; font-weight: 800; text-shadow: 0 0 16px rgb(255 138 61 / .35); }
.promo-sub { color: rgb(233 237 234 / .6); }
.promo-banner-cta { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap;
  background: var(--accent-fill); color: var(--on-accent); font-weight: 700; border-radius: 999px;
  padding: 5px 14px; box-shadow: 0 2px 8px rgb(232 101 13 / .35);
  transition: background .12s ease, transform .12s ease; }
.promo-banner-cta:hover { background: #F4761E; color: #fff; text-decoration: none; transform: translateY(-1px); }

.facet-block { margin-top: var(--s6); }
.facet-block h2 { display: flex; align-items: center; gap: 6px; font-size: var(--t-md); margin-bottom: var(--s3); }
.facet-block h2 .lucide { color: var(--seal); }
.pub-links { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); }
.pub-links a { font-size: var(--t-sm); color: var(--ink); }
.pub-links a:hover { color: var(--accent-ink); }
/* T-ILSEO: public authority (publisher) page + directory hub */
.pub-links-az a { color: var(--ink-soft); }
.arch-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s2); }
.arch-list li { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); padding-bottom: var(--s2); border-bottom: 1px solid var(--line); }
.arch-title { color: var(--ink-soft); }
.arch-month { flex: none; white-space: nowrap; font-size: var(--t-xs); }
.disclaimer { margin-top: var(--s7); padding-top: var(--s4); border-top: 1px solid var(--line); font-size: var(--t-xs); max-width: 760px; }
/* T-ILSEO2: public live-sample rows on the publisher page */
.pub-sample .ps-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s3); }
.ps-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); padding-bottom: var(--s3); border-bottom: 1px solid var(--line); }
.ps-title { font-weight: 500; color: var(--ink); flex: 1 1 100%; }
.ps-meta { display: inline-flex; align-items: center; gap: var(--s2); }
.ps-locked { color: var(--ink-soft); font-size: var(--t-xs); }
/* T-ILSEO: public footer city links + non-affiliation disclaimer (IL) */
.footer-cities { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--line); font-size: var(--t-xs); }
.footer-cities-lead { color: var(--ink-soft); font-weight: 500; }
.footer-cities a { color: var(--ink-soft); }
.footer-cities a:hover { color: var(--ink); }
.footer-cities-all { font-weight: 500; }
.footer-disclaimer { margin-top: var(--s3); font-size: var(--t-xs); color: var(--ink-soft); max-width: 900px; }
/* T-ILSEO: landing "מכרזים לפי רשות" section */
.lp-authorities .lp-shell { text-align: center; }
.lp-auth-chips { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s3); justify-content: center; margin-top: var(--s4); }
.lp-auth-chip { display: inline-flex; align-items: baseline; gap: 6px; padding: 6px var(--s3); border: 1px solid var(--line); border-radius: 999px; font-size: var(--t-sm); color: var(--ink); background: var(--surface); }
.lp-auth-chip:hover { border-color: var(--seal); color: var(--seal); }
.lp-auth-all { display: inline-block; margin-top: var(--s4); font-weight: 500; color: var(--seal); }
/* T-ILSEO2: landing lookup teaser (search an authority, no login) + hub search */
.lp-lookup-il .lp-shell { text-align: center; }
.lp-lookup-card { max-width: 680px; margin: 0 auto; padding: var(--s6) var(--s5); background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card); }
.lp-lookup-form { display: flex; flex-wrap: wrap; gap: var(--s2); justify-content: center; margin-top: var(--s4); }
.lp-lookup-box { position: relative; flex: 1 1 320px; max-width: 460px; text-align: start; }
.lp-lookup-box input { width: 100%; min-height: 46px; padding: 0 var(--s3); border: 1px solid var(--line); border-radius: var(--r-control); background: var(--surface); font-size: var(--t-md); }
.lp-lookup-box input:focus { outline: 2px solid var(--seal); outline-offset: 1px; border-color: var(--seal); }
.lp-lookup-list { position: absolute; z-index: 30; inset-inline: 0; top: calc(100% + 4px); margin: 0; padding: 4px; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-control); box-shadow: 0 8px 28px rgba(0,0,0,.14); max-height: 320px; overflow-y: auto; text-align: start; }
.lp-lookup-list li { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); padding: 8px var(--s3); border-radius: 6px; cursor: pointer; font-size: var(--t-sm); }
.lp-lookup-list li.is-active, .lp-lookup-list li:hover { background: var(--paper); }
.lp-auth-chip-all { border-color: color-mix(in srgb, var(--seal) 40%, transparent); color: var(--seal); font-weight: 500; }
.hub-search { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s4) 0 var(--s2); }
.hub-search input { flex: 1 1 320px; min-height: 44px; padding: 0 var(--s3); border: 1px solid var(--line); border-radius: var(--r-control); background: var(--surface); font-size: var(--t-md); }
.hub-search input:focus { outline: 2px solid var(--seal); outline-offset: 1px; border-color: var(--seal); }
.faq { margin-top: var(--s7); max-width: 760px; }
.faq h2 { font-size: var(--t-lg); margin-bottom: var(--s4); }
.faq details { border-bottom: 1px solid var(--line); padding: var(--s3) 0; }
.faq summary { font-weight: 600; cursor: pointer; }
.faq details p { color: var(--ink-soft); margin-top: var(--s2); line-height: 1.6; }
.footer-nav a { color: var(--ink-soft); font-size: 12px; }
.footer-nav a:hover { color: var(--accent-ink); }

/* ---------- Error page (404 / fallback) ---------- */
.errpage { text-align: center; max-width: 520px; margin-inline: auto; padding: var(--s8) var(--s5); }
.errpage-code { font-family: var(--font-display); font-size: 96px; font-weight: 800; line-height: 1; color: var(--seal); opacity: .22; }
.errpage h1 { margin: var(--s2) 0; }
.errpage p { margin-bottom: var(--s5); }
.errpage-actions { display: flex; gap: var(--s3); justify-content: center; flex-wrap: wrap; }

/* ---------- Wizard ---------- */
.wizard { max-width: 640px; margin-inline: auto; }
.wizard > h1 { margin-bottom: var(--s4); }
.steps { list-style: none; display: flex; gap: var(--s2); padding: 0; margin: 0 0 var(--s5); flex-wrap: wrap; counter-reset: step; }
.step-pill { counter-increment: step; display: flex; align-items: center; gap: 6px; font-size: var(--t-xs); color: var(--ink-soft); padding: 4px 0; flex: 1; min-width: 90px; cursor: pointer; }
.step-pill:hover { color: var(--ink); }
.step-pill:hover::before { border-color: var(--seal); }
.step-pill:focus-visible { outline: 2px solid var(--seal); outline-offset: 2px; border-radius: var(--r-control); }
.step-pill::before { content: counter(step); display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--line); font-weight: 700; background: var(--surface); flex: none; }
.step-pill.active { color: var(--seal); }
.step-pill.active::before { background: var(--seal); color: #fff; border-color: var(--seal); }
.step-pill.current { color: var(--ink); font-weight: 700; }
.wizard-step { padding: var(--s5); }
.wizard-step h2 { font-size: var(--t-md); margin-bottom: var(--s4); }
.wizard-step .field { margin-bottom: var(--s4); }
.chip-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); }
.chip-row .chip { padding: 8px var(--s4); font-size: var(--t-sm); }
.wizard-nav { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s4); }
.preview-note { display: flex; align-items: center; gap: 6px; color: var(--ink-soft); font-size: var(--t-sm); margin: var(--s5) 0 var(--s2); }
.preview-note .lucide { color: var(--ok); }
.preview-card { border-style: dashed; }

/* ---------- Auth ---------- */
.auth-wrap { min-height: calc(100vh - 130px); display: grid; place-items: center; padding: var(--s5); }
.auth-card { width: 100%; max-width: 400px; padding: var(--s6); }
.auth-card h1 { font-size: var(--t-lg); margin-bottom: var(--s5); }
/* "Continue with Google" — white button with the Google mark, per brand guidance. */
.btn-google {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s3);
  background: #fff; color: #3c4043; border: 1px solid var(--line);
  font-weight: 600;
}
.btn-google:hover { background: #f7f8f8; border-color: var(--ink-soft); text-decoration: none; }
.btn-google .g-logo { flex: none; }
/* "or" divider between Google sign-in and the email form. */
.auth-sep { display: flex; align-items: center; gap: var(--s3); margin: var(--s5) 0; color: var(--ink-soft); font-size: var(--t-sm); }
.auth-sep::before, .auth-sep::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ---------- Settings ---------- */
.settings-block { padding: var(--s5); margin-bottom: var(--s4); }
/* A section reachable by #anchor has to clear the sticky top bar, or the jump
   parks its heading behind it — the digest email links to #digest, and landed
   the reader on a card whose title they could not see. Same 80px the other
   anchored cards on this site use. */
.settings-block[id] { scroll-margin-top: 80px; }
.settings-block h2 { font-size: var(--t-md); margin-bottom: var(--s2); }
.settings-intro { font-size: var(--t-sm); color: var(--ink-soft); margin-bottom: var(--s4); }
.settings-readonly-note { display: flex; align-items: center; gap: 6px; }

/* UK qualification profile (/settings/qualification). The global
   input{width:100%} rule stretches each checkbox full-width and drops its label
   onto the next line — reset the checkbox to native size and lay each
   certification out as one left-aligned checkbox+label row. */
.qual-checks { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s4); }
.qual-check { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--t-sm); color: var(--ink); }
.qual-check input { flex: none; width: auto; margin: 0; padding: 0; }
.qual-check input:disabled { cursor: default; }
/* Stacked label + input for Constructionline tier and the insurance fields; the
   block margin also separates the tier input from the checkbox rows above it. */
.qual-field { display: block; margin-bottom: var(--s3); }
.qual-field > span { display: block; font-size: var(--t-xs); color: var(--ink-soft); font-weight: 600; margin-bottom: 4px; }
.qual-field > input { max-width: 340px; }

/* UK qualification-profile callout on /settings: a card-styled <a>. Anchors are
   inline by default, so its .settings-block block padding bled over the profile
   card beneath it — make it a flex row that flows normally (icon · text · arrow)
   and its margin-bottom now separates it cleanly. */
.qual-link { display: flex; align-items: center; gap: var(--s3); text-decoration: none; color: var(--ink); }
.qual-link > span { flex: 1; font-size: var(--t-sm); color: var(--ink-soft); }
.qual-link .lucide { flex: none; color: var(--ink-soft); }
.qual-link:hover { border-color: var(--seal); }
.qual-link:hover .lucide:last-child { color: var(--seal); }

/* Empty-state placeholder (frameworks, content bank). A min-height keeps a short
   "nothing here yet" message from collapsing the page and floating the footer up
   into the middle of the viewport. */
.empty-state {
  display: flex; align-items: center; justify-content: center;
  min-height: 240px; padding: var(--s6); border-radius: var(--r-card);
  border: 1px dashed var(--line); background: var(--paper);
  color: var(--ink-soft); font-size: var(--t-sm); text-align: center;
}

/* Frameworks list (/frameworks): proper cards, not bare bullets. */
.fw-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s3); }
.fw-item { padding: var(--s4) var(--s5); }
.fw-head { display: flex; align-items: center; gap: var(--s3); }
.fw-title { flex: 1; min-width: 0; font-weight: 600; color: var(--ink); }
.fw-meta { margin-top: 6px; font-size: var(--t-sm); display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.fw-kind { font-weight: 600; color: var(--ink); }
/* Membership badge — green when open to join, muted when closed. */
.fw-badge {
  flex: none; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 3px 9px; border-radius: 999px; font-size: var(--t-xs); font-weight: 600;
  border: 1px solid var(--line);
}
.fw-badge.fw-open { border-color: var(--ok); background: var(--ok-wash); color: var(--ok); }
.fw-badge.fw-closed { background: var(--paper); color: var(--ink-soft); }
/* A closed framework under "you could join" is de-emphasised so it reads apart. */
.fw-item.is-closed { opacity: .72; }
.fw-item.is-closed .fw-title { color: var(--ink-soft); }

/* The UK primary nav carries one extra destination (Frameworks), so it runs out
   of room ~1024px and an item would drop off the row. Collapse to icon-only
   there — every link stays on the bar and reachable, with its name as the
   title/tooltip. UK-only; IL's shorter nav is untouched. */
@media (max-width: 1100px) {
  .mkt-uk .nav > a:not(.btn-primary) .label { display: none; }
  .mkt-uk .nav > a:not(.btn-primary) .nav-icon { margin-inline-end: 0; }
}

/* The profile form is wrapped in a <fieldset> so we can disable it wholesale for
   non-admins; strip the element's native chrome so layout is unchanged. */
.settings-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.settings-fieldset[disabled] { opacity: .75; }
.stacked .field { margin-bottom: var(--s4); }
/* Grouped subsections inside the long profile form, divided by a hairline. */
.settings-group { border-top: 1px solid var(--line); padding-top: var(--s4); margin-top: var(--s4); }
.settings-group:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
.settings-group:last-of-type { margin-bottom: var(--s4); }
.settings-subhead { display: flex; align-items: center; gap: 8px; font-size: var(--t-sm);
  font-weight: 700; color: var(--ink); margin-bottom: var(--s3); }
.settings-subhead .lucide { color: var(--seal); flex: none; }
/* "Advanced matching" is a native <details>: make its summary read as an
   expandable menu — pointer, no default triangle, a chevron that rotates open. */
.settings-advanced > summary { cursor: pointer; list-style: none; margin-bottom: 0; }
.settings-advanced[open] > summary { margin-bottom: var(--s3); }
.settings-advanced > summary::-webkit-details-marker { display: none; }
.settings-advanced > summary::marker { content: ""; }
.settings-advanced > summary:hover { color: var(--seal); }
.settings-advanced > summary .chev { margin-inline-start: auto; color: var(--ink-soft); transition: transform .18s ease; }
.settings-advanced[open] > summary .chev { transform: rotate(180deg); }

/* ── UK profile accordion — one card per section, expand to fill ── */
.pf-lead { color: var(--ink-soft); font-size: var(--t-sm); margin: 0 0 var(--s4); max-width: 62ch; }
.pf-accordion { display: flex; flex-direction: column; gap: var(--s3); margin-bottom: var(--s5); }
.pf-card { border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface); overflow: hidden; }
.pf-card[open] { border-color: var(--seal); }
.pf-sum { display: flex; align-items: center; gap: var(--s3); padding: var(--s4); cursor: pointer; list-style: none; }
.pf-sum::-webkit-details-marker { display: none; }
.pf-sum::marker { content: ""; }
.pf-sum:hover { background: var(--paper); }
.pf-ic { flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; background: var(--paper); color: var(--seal); }
.pf-ic .lucide { color: inherit; }
.pf-card[open] .pf-ic { background: var(--seal); color: #fff; }
.pf-tt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pf-tt b { font-size: var(--t-sm); font-weight: 700; color: var(--ink); }
.pf-tt small { color: var(--ink-soft); font-size: var(--t-xs); }
.pf-sum > .chev { flex: none; color: var(--ink-soft); transition: transform .18s ease; }
.pf-card[open] > .pf-sum > .chev { transform: rotate(180deg); }
.pf-body { padding: var(--s4); border-top: 1px solid var(--line); }
.pf-subhead { font-weight: 700; font-size: var(--t-sm); color: var(--ink); margin: var(--s4) 0 var(--s2); }
.pf-subhead .muted { font-weight: 400; }

/* £-amount field with one-tap preset chips (real cover levels are large millions,
   so a spinner would be dozens of clicks). */
.money-field { margin-bottom: var(--s4); }
.money-field > .field-label { display: block; margin-bottom: 6px; }
.money-row { display: flex; align-items: stretch; width: 100%; max-width: 260px; border: 1px solid var(--line); border-radius: var(--r-control); overflow: hidden; background: var(--surface); }
.money-row:focus-within { border-color: var(--seal); }
.money-pre { display: grid; place-items: center; padding: 0 10px; background: var(--paper); color: var(--ink-soft); font-weight: 600; }
.money-input { border: 0 !important; border-radius: 0 !important; box-shadow: none !important; flex: 1; min-width: 0; }
.money-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.money-chip { border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft); border-radius: 999px; padding: 4px 12px; font-size: var(--t-xs); font-weight: 600; cursor: pointer; transition: border-color .12s, color .12s, background .12s; }
.money-chip:hover { border-color: var(--seal); color: var(--seal); }
.money-chip.is-on { background: var(--seal); color: #fff; border-color: var(--seal); }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s4); }
.checkgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--s2); }
.check { display: inline-flex; align-items: center; gap: 6px; font-weight: 400; }
.check input { width: auto; }
/* Inline control rows (digest toggle, change email): control + button on one
   line, button pinned to the end and vertically aligned with its control. */
.settings-row { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.settings-row.align-end { align-items: flex-end; }
.settings-row .field { margin-bottom: 0; }
.settings-row .grow { flex: 1 1 220px; }
.settings-row .btn { margin-inline-start: auto; }
.settings-hint { font-size: var(--t-sm); color: var(--ink-soft); margin-bottom: var(--s3); }
@media (max-width: 720px) {
  .grid-2 { grid-template-columns: 1fr; }
  .settings-row .btn { margin-inline-start: 0; }
}

/* ---------- Filter bar (browse) ---------- */
/* Filters scroll away with the page so the table's own header can stay pinned
   (see table.data thead below). Both being sticky would overlap. */
.filterbar { background: var(--paper); padding-block: var(--s1); margin-bottom: var(--s3); }
/* Stacked sections: search row · divider · filter body · view scope. Kept tight
   vertically so the results table stays in view. */
.filterbar form { display: flex; flex-direction: column; gap: var(--s2); align-items: stretch; }
.filterbar .field { margin: 0; min-width: 0; gap: 3px; }
/* Compact controls + labels so the whole bar takes minimal vertical room. */
.filterbar .field > span, .filterbar .field-label { font-size: var(--t-xs); }
.filterbar .field input, .filterbar .field select,
.filterbar .cpv-toggle, .filterbar .range-row input { padding-block: 7px; }
.filterbar .search-box input { padding-block: 9px; }

/* View scope — instant-apply chips. Sits just above the results table with a
   divider rule so it reads as a control for the table, not part of the filters. */
.view-bar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2);
  margin-top: var(--s2); padding-top: var(--s3); border-top: 1px solid var(--line); }
.view-label { font-size: var(--t-xs); font-weight: 600; margin-inline-end: 2px; }
/* The browse bar borrows the public search's segmented control — one pattern,
   so the same shape means the same thing on both surfaces. Only the type scale
   differs: this bar's chips are smaller. */
.view-bar .ps-seg { padding: 2px; }
.view-bar .ps-seg-opt { font-size: var(--t-xs); padding: 4px 12px; }
.view-bar .ps-seg-opt.is-on { font-weight: 600; }
/* Notice type is a dropdown rather than a fourth, fifth and sixth chip. Three
   kinds plus "all" is four positions, and four pills sitting beside the show/
   hide chips read as the bar's main navigation instead of as one filter. */
/* width:auto is load-bearing — the global `select { width: 100% }` above makes
   a bare select take the whole bar and push every chip onto its own line. */
/* --r-control, the radius every other select on this page uses. The first
   version asked for var(--r2), which is not a token we define — an unresolved
   var() drops the declaration, and the control came out square-cornered among
   round ones.
   Padding is logical, not left/right: the native arrow sits at the inline END,
   which is the LEFT in Hebrew, so a hard `padding-right: 22px` reserved the
   gap on the wrong side and pushed the text off-centre. */
/* align-self:stretch rather than a height of its own: the bar's height is set
   by the chips beside it, and a 26px control among 31px pills reads as
   misaligned however well its centre lines up. This follows them if they
   change. */
.view-select { width: auto; flex: 0 0 auto; min-width: 7.5rem; align-self: stretch;
  font-size: var(--t-xs); padding-block: 0; padding-inline: 8px 22px;
  border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink); }
.view-select:hover { border-color: var(--line-hover); }
.view-select:focus-visible { outline: 2px solid var(--seal); outline-offset: 1px;
  border-color: var(--seal); }

/* Filter body: the controls (basic grid + Advanced) fill the row; Apply/Clear sit
   on the right, vertically centred so it's clear they apply to *all* the filters —
   the visible ones and the Advanced ones. */
.filter-body { display: grid; grid-template-columns: minmax(0, 1fr) max-content;
  gap: var(--s4); align-items: stretch; }
.filter-actions { display: flex; flex-direction: column; justify-content: center;
  gap: var(--s2); }
.filter-actions .btn { width: 100%; justify-content: center; white-space: nowrap; }
/* Clear is secondary — a small, light text button, not a second heavy button. */
.filter-clear-btn { display: inline-flex; align-items: center; justify-content: center;
  gap: 4px; align-self: center; padding: 2px 8px; border: 0; background: none;
  color: var(--ink-soft); font: inherit; font-size: var(--t-xs); cursor: pointer; }
.filter-clear-btn:hover { color: var(--ink); }
.filter-clear-btn .lucide { width: 13px; height: 13px; }
.filter-controls { display: grid; gap: var(--s2); min-width: 0; }
/* Uniform-width fields: tight row gap (low bulk), roomier column gap (legible). */
.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(172px, 1fr));
  gap: var(--s1) var(--s4); align-items: end; }
.field-grid > .field, .field-grid > .multiselect { margin: 0; min-width: 0; }
@media (max-width: 680px) {
  .filter-body { grid-template-columns: 1fr; }
  .filter-actions { flex-direction: row; }
  .filter-actions .btn { flex: 1; }
}

/* Free-text search — full-width row above the filter dropdowns */
.search-row { display: flex; gap: var(--s2); width: 100%; align-items: center; margin-bottom: var(--s1); }
.search-box { position: relative; flex: 1; display: flex; align-items: center; }
.search-box .search-ic { position: absolute; inset-inline-start: var(--s3); color: var(--ink-soft); pointer-events: none; }
.search-box input {
  width: 100%; padding-block: 11px; padding-inline-start: 42px; padding-inline-end: 36px;
  font-size: var(--t-md); border: 1px solid var(--line); border-radius: var(--r-control); background: var(--surface);
}
.search-box input:focus { outline: 2px solid var(--seal); outline-offset: 1px; border-color: var(--seal); }
.search-clear { position: absolute; inset-inline-end: var(--s3); color: var(--ink-soft); display: inline-flex; padding: 0; border: 0; background: none; cursor: pointer; }
.search-clear:hover { color: var(--ink); }
.search-row .btn { padding: 11px var(--s4); flex: none; }
.filterbar .field > span { font-size: var(--t-xs); color: var(--ink-soft); }
.filterbar .actions { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.filter-check { display: inline-flex; align-items: center; gap: var(--s2); font-size: var(--t-sm); }
.filter-check input { width: auto; }

/* CPV multiselect — a compact popover so a 1000+ long list never bloats the bar */
.ms-filter { position: relative; }
.cpv-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  /* Match the native <select> height in the bar. Selects size intrinsically, so
     pin the toggle to the same box height (border-box) rather than chasing
     line-height. */
  width: 100%; min-height: 42px; padding: 0 var(--s3); cursor: pointer; text-align: start;
  border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink); font-size: var(--t-sm);
}
.cpv-toggle:hover { border-color: var(--ink-soft); }
.cpv-toggle.is-active { border-color: var(--seal); color: var(--seal); font-weight: 600; }
.cpv-toggle .cpv-chevron { flex: none; color: var(--ink-soft); }
.cpv-toggle-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cpv-panel {
  position: absolute; z-index: 30; inset-inline-start: 0; top: calc(100% + 4px);
  width: min(360px, 86vw); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-control);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14); overflow: hidden;
}
.cpv-panel-head { display: flex; gap: var(--s2); padding: var(--s2); border-bottom: 1px solid var(--line); }
.cpv-search {
  flex: 1; min-width: 0; padding: 7px var(--s3); font-size: var(--t-sm);
  border: 1px solid var(--line); border-radius: var(--r-control); background: var(--paper);
}
.cpv-search:focus { outline: 2px solid var(--seal); outline-offset: 1px; border-color: var(--seal); }
.cpv-clear-sel { flex: none; padding: 0 var(--s2); border: 0; background: none; color: var(--accent); cursor: pointer; font-size: var(--t-sm); }
.cpv-clear-sel:hover { text-decoration: underline; }
.cpv-list { max-height: 280px; overflow-y: auto; padding: 4px; }
.cpv-opt {
  display: flex; align-items: baseline; gap: var(--s2);
  padding: 6px var(--s2); border-radius: 6px; cursor: pointer; font-size: var(--t-sm); line-height: 1.4;
}
.cpv-opt:hover { background: var(--paper); }
/* Reset the global input{width:100%;padding;border} so the checkbox renders at
   its native size instead of stretching full-width and crushing the labels. */
.cpv-opt input { flex: none; width: auto; align-self: center; padding: 0; margin: 0; border: 0; }
.cpv-opt-code { flex: none; color: var(--ink-soft); }
.cpv-opt-label { color: var(--ink); word-break: break-word; }
.cpv-empty { padding: var(--s3); margin: 0; color: var(--ink-soft); font-size: var(--t-sm); text-align: center; }

/* Tag picker — a combobox that searches a big list (full CPV / NUTS) and builds
   removable chips, plus quick-suggest chips. Used in onboarding + settings. */
.tagpicker { max-width: 520px; }
.tp-control { position: relative; display: flex; align-items: stretch; gap: 0; }
.tp-selected {
  flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 6px 8px; min-height: 42px;
  border: 1px solid var(--line); border-radius: var(--r-control) 0 0 var(--r-control); background: var(--paper);
}
[dir="rtl"] .tp-selected { border-radius: 0 var(--r-control) var(--r-control) 0; }
.tp-control:focus-within .tp-selected { border-color: var(--seal); }
.tp-chip {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  padding: 3px 4px 3px 10px; font-size: var(--t-xs); line-height: 1.3;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
}
[dir="rtl"] .tp-chip { padding: 3px 10px 3px 4px; }
.tp-chip-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-remove {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%;
  background: var(--line); color: var(--ink); cursor: pointer; font-size: 11px; line-height: 1;
}
.tp-remove:hover { background: var(--accent-fill); color: var(--on-accent); }
.tp-input {
  flex: 1; min-width: 120px; width: auto; padding: 4px 2px; margin: 0;
  border: 0; background: none; font-size: var(--t-sm); outline: none;
}
.tp-toggle {
  flex: none; width: 40px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-inline-start: 0;
  border-radius: 0 var(--r-control) var(--r-control) 0; background: var(--surface); cursor: pointer; color: var(--ink-soft);
}
[dir="rtl"] .tp-toggle { border-radius: var(--r-control) 0 0 var(--r-control); }
.tp-toggle:hover { background: var(--paper); color: var(--ink); }
.tp-note { padding: 8px 10px 6px; margin-top: 2px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--ink-soft); cursor: default; }
.tp-results {
  position: absolute; z-index: 60; inset-inline: 0; top: calc(100% + 4px);
  margin: 0; padding: 4px; list-style: none; max-height: 300px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-control);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
}
/* The active picker (and so its dropdown) must sit above the form fields below. */
.tagpicker:focus-within { position: relative; z-index: 5; }
.tp-result {
  display: flex; align-items: baseline; gap: var(--s2);
  padding: 7px var(--s2); border-radius: 6px; cursor: pointer; font-size: var(--t-sm); line-height: 1.4;
}
.tp-result:hover, .tp-result.is-active { background: var(--paper); }
.tp-result.is-picked { opacity: 0.5; }
.tp-result.is-picked::after { content: "✓"; margin-inline-start: auto; color: var(--seal); }
.tp-result-code { flex: none; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.tp-result-label { color: var(--ink); word-break: break-word; }
.tp-empty { padding: var(--s3); margin: 0; color: var(--ink-soft); font-size: var(--t-sm); text-align: center; }
.tp-suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: var(--s2); }
.tp-suggest-label { font-size: var(--t-xs); margin-inline-end: 2px; }
.tp-suggest-chip { padding: 5px 10px; font-size: var(--t-xs); cursor: pointer; }
.tp-suggest-chip.is-picked { opacity: 0.45; pointer-events: none; }

/* Compact "show" toggles (expired / hidden) — chip-style instead of long labels */
.show-toggles { display: inline-flex; align-items: center; gap: var(--s2); margin-inline-end: var(--s2); }
.show-label { font-size: var(--t-xs); color: var(--ink-soft); font-weight: 600; margin-inline-end: 2px; }
.chip-show { padding: 4px 10px; font-size: var(--t-xs); gap: 4px; }
.chip-show svg { vertical-align: -2px; }

/* ---------- Landing ---------- */
.hero { position: relative; overflow: hidden; background: var(--paper); border-bottom: 1px solid var(--line); }
/* Brand gradient glow stretched behind the hero — soft blueprint-blue + warm
   orange light, blurred. Sits beneath the content (z-index). */
.hero::before {
  content: ""; position: absolute; inset: -12% -6%; pointer-events: none; z-index: 0;
  background:
    radial-gradient(46% 60% at 80% 8%, rgba(22, 85, 122, 0.30), transparent 70%),
    radial-gradient(42% 55% at 12% 40%, rgba(232, 101, 13, 0.22), transparent 72%),
    radial-gradient(48% 50% at 96% 88%, rgba(22, 85, 122, 0.16), transparent 72%);
  filter: blur(40px);
}
.hero-inner { position: relative; z-index: 1; max-width: var(--maxw); margin-inline: auto; padding: var(--s8) var(--s5);
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s7); align-items: center; }
/* Nudge the hero copy column (rotating headline + demo button) up slightly. */
.hero-copy { transform: translateY(-10px); }
.hero-copy h1 { font-size: var(--t-2xl); line-height: 1.1; }
/* Rotating headline — items share one grid cell so the box sizes to the
   tallest line (no layout shift). Construction-themed "brick laying": JS splits
   each line into word blocks (.brick) that drop into place with a slight
   overshoot, staggered right-to-left; the outgoing line drops away first. */
.rotator { display: grid; }
.rot-item { grid-column: 1; grid-row: 1; }
/* Each word flies in from a scattered position (JS sets --tx/--ty/--rot per
   brick) and glides into place, staggered — the headline assembles itself. */
.brick {
  display: inline-block;
  opacity: 0;
  transform: translate(var(--tx, 0), var(--ty, -0.6em)) rotate(var(--rot, 0deg)) scale(.92);
  transition:
    opacity .63s ease,
    transform .92s cubic-bezier(.16, 1, .3, 1);    /* slow, smooth glide-and-settle */
  will-change: opacity, transform;
}
.rot-item.is-active .brick { opacity: 1; transform: none; }
.rot-item.is-leaving .brick {
  opacity: 0; transform: translateY(0.5em) scale(.96);
  transition-delay: 0s !important; transition-duration: .35s;
}
@media (prefers-reduced-motion: reduce) {
  .brick { transition: none; transform: none; }
  .rot-item.is-active .brick { opacity: 1; }
}
.hero-copy .lead { font-size: var(--t-md); color: var(--ink-soft); margin: var(--s4) 0 var(--s5); max-width: 30ch; }
.hero-cta { display: flex; gap: var(--s3); flex-wrap: wrap; }
/* Shrink the public hero demo card 10% (scoped here only — the dashboard's real
   fitcards are unaffected). zoom (not transform) so the card's layout box shrinks
   too, keeping the gap to the next section natural instead of leaving slack. */
.hero-demo .fitcard { box-shadow: 0 10px 30px rgb(28 43 51 / 0.08); zoom: .9; }

.strip { border-block: 1px solid var(--line); background: var(--surface); }
.strip-inner { max-width: var(--maxw); margin-inline: auto; padding: var(--s6) var(--s5);
  display: flex; align-items: flex-start; justify-content: center; gap: var(--s4); flex-wrap: wrap; }
.step { text-align: center; max-width: 220px; flex: 1 1 200px; }
.step-ic { display: inline-grid; place-items: center; width: 52px; height: 52px; border-radius: 50%;
  background: var(--seal-wash); color: var(--seal); margin-bottom: var(--s2); }
.step h3 { margin-bottom: 4px; }
.step p { color: var(--ink-soft); font-size: var(--t-sm); margin: 0; }
/* Top-aligned so every step's icon + title line up regardless of text length;
   nudge the connector down to sit at the icons' vertical centre. */
.step-arrow { color: var(--line); transform: rotate(90deg); margin-top: 14px; }

/* Live stats: a few honest, daily-updated counts under the hero. Kept slim and
   transparent — a quiet row that sits on the page, not a heavy coloured band. */
.stats-band { background: transparent; }
.stats-inner { max-width: 760px; margin-inline: auto; padding: calc(var(--s5) * .95) var(--s5) calc(var(--s4) * .95);
  display: flex; justify-content: center; flex-wrap: wrap; text-align: center; }
.stat { padding-inline: var(--s6); }
.stat + .stat { border-inline-start: 1px solid var(--line); }
.stat-num { display: block; font-family: var(--font-display); font-size: var(--t-lg);
  font-weight: 700; line-height: 1.05; color: var(--seal); }
.stat-label { display: block; margin-top: 5px; font-size: var(--t-xs); color: var(--ink-soft); }
@media (max-width: 560px) {
  .stat { flex-basis: 42%; padding-inline: var(--s3); }
  .stat + .stat { border-inline-start: 0; }
}

.coverage { background: var(--ink); color: #E9EDEA; }
.coverage-inner { max-width: var(--maxw); margin-inline: auto; padding: var(--s5);
  display: flex; align-items: center; gap: var(--s3); justify-content: center; text-align: center; font-size: var(--t-sm); }
.coverage b { color: #fff; font-weight: 700; }

.pricing { max-width: var(--maxw); margin-inline: auto; padding: var(--s7) var(--s5); }
.price-grid { display: flex; justify-content: center; margin-top: var(--s5); }
.price-card { position: relative; padding: var(--s6); max-width: 360px; width: 100%; text-align: start; }
/* Floating pill straddling the card's top edge — a clean, designed touch. */
.price-badge { position: absolute; top: 0; inset-inline: 0; margin-inline: auto; width: max-content;
  transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-xs); font-weight: 700;
  color: #fff; background: var(--seal); border-radius: 999px; padding: 5px 14px;
  box-shadow: 0 6px 16px rgba(22, 85, 122, 0.28); letter-spacing: .01em; }
.price-badge .lucide { color: #fff; }
.price-name { color: var(--ink-soft); font-weight: 700; }
.price-amount { font-family: var(--font-display); font-size: var(--t-xl); margin: var(--s2) 0; }
.price-period { font-family: var(--font-body); font-size: var(--t-sm); color: var(--muted); font-weight: 500; }
.price-list { list-style: none; padding: 0; margin: var(--s4) 0; display: grid; gap: var(--s2); font-size: var(--t-sm); }
.price-list li { display: flex; align-items: center; gap: var(--s2); color: var(--ink); }
.price-list .lucide { color: var(--ok); }
.price-seats { display: flex; align-items: center; gap: var(--s2); margin: var(--s2) 0 var(--s3);
  padding: 8px 12px; border-radius: var(--r-control); background: var(--accent-wash);
  color: var(--accent-ink); font-weight: 700; font-size: var(--t-sm); }
.price-seats .lucide { color: var(--accent-ink); }

/* Below ~880px three steps can't sit side-by-side without an ugly 2+1 wrap,
   so stack them into a clean vertical flow with the connector pointing down. */
@media (max-width: 880px) {
  .strip-inner { flex-direction: column; align-items: center; gap: var(--s5); }
  .step { max-width: 360px; flex: none; }
  .step-arrow { transform: rotate(0deg); margin-top: 0; }
}

@media (max-width: 720px) {
  .hero-inner { grid-template-columns: 1fr; padding: var(--s6) var(--s4); gap: var(--s5); }
  .hero-copy h1 { font-size: var(--t-xl); }
}

/* ---------- Footer ---------- */
.footer { border-top: 1px solid var(--line); color: var(--ink-soft); font-size: var(--t-xs); background: var(--surface); }
.footer-inner {
  max-width: var(--maxw); margin-inline: auto; padding: var(--s5);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3);
}
/* Admin user-list email-verification badges. */
.verif-ok { color: var(--ok); font-weight: 700; }
.verif-no { color: var(--bad); font-weight: 700; cursor: help; }

.footer-links { display: inline-flex; align-items: baseline; flex-wrap: wrap; gap: var(--s2) var(--s4); }
/* The legal links are the actual flex row — the parent's gap can't reach them
   (its only child is this nav), so space them here or they crowd together. */
.footer-legal { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s4); }
.footer-nav-link { color: var(--ink-soft); font-size: 12px; }
.footer-nav-link:hover { color: var(--accent-ink); }
.footer-meta { display: inline-flex; align-items: baseline; gap: 6px; }
.footer-rights { color: var(--ink-soft); font-size: var(--t-xs); }
.footer-contact-label { color: var(--ink-soft); font-weight: 500; }
.footer-contact { color: var(--ink); font-weight: 500; }
.footer-contact:hover { color: var(--accent-ink); text-decoration: underline; }
.disclaimer { color: var(--ink-soft); font-size: var(--t-xs); border-top: 1px solid var(--line); padding-top: var(--s3); margin-top: var(--s5); text-align: center; }
/* Where the disclaimer follows a result grid directly, s5 puts its rule right
   under the last card. Used on the publishers directory, which no longer has a
   sign-up panel separating the two. */
.disclaimer.disclaimer-gap { margin-top: var(--s8); padding-top: var(--s5); }

/* Responsive: stack the browse table into cards on narrow screens */
@media (max-width: 600px) {
  .table-wrap { border: none; background: transparent; overflow: visible; }
  table.data thead { display: none; }
  table.data, table.data tbody, table.data tr, table.data td { display: block; width: 100%; }
  table.data tr { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow); margin-bottom: var(--s3); padding: var(--s2) var(--s4); }
  table.data td { border: none; padding: 6px 0; display: flex; justify-content: space-between; gap: var(--s4); align-items: center; }
  table.data td[data-label]::before { content: attr(data-label); color: var(--ink-soft); font-size: var(--t-xs); font-weight: 700; flex: none; }
  table.data td .t-title { white-space: normal; max-width: none; text-align: start; }
  /* On the stacked (card) layout there's vertical room — let the full buyer name
     wrap instead of truncating. */
  table.data.tenders-table td.t-pub { white-space: normal; overflow: visible; text-overflow: clip; text-align: end; min-width: 0; }
  table.data td[data-label="כותרת"] { display: block; }
  table.data td[data-label=""]::before { display: none; }
}

@media (max-width: 720px) {
  .container { padding-inline: var(--s4); padding-block: var(--s5); }
  .topbar-inner { padding: var(--s3) var(--s4); }
  .nav a { padding: var(--s2); }
  .nav a .label { display: none; }
  .nav-icon { margin: 0; }
  /* The public "עוד" menu's 300px min-width overflows the viewport on phones
     (the text gets clipped off-screen). Anchor it to the sticky topbar and pin
     both inline edges so it spans the screen with a 10px margin instead. */
  .nav-dropdown { position: static; }
  .nav-dropdown-menu {
    top: calc(100% + 6px); inset-inline: 10px;
    min-width: 0; max-width: none; width: auto;
  }
  h1 { font-size: var(--t-lg); }
  .fitcard-head { flex-direction: row; padding: var(--s4); }
  .filterbar { position: static; }
}

/* ── Tenders table skeleton (async-load placeholder) ───────────────────── */
.skeleton-table { pointer-events: none; }
.skeleton-table thead th { color: var(--ink-soft); }
.skel {
  display: inline-block; height: 14px; border-radius: 6px; vertical-align: middle;
  background: linear-gradient(90deg, var(--paper) 25%, var(--line) 37%, var(--paper) 63%);
  background-size: 400% 100%;
  animation: skel-shimmer 1.3s ease-in-out infinite;
}
.skel-lg { width: 80%; }
.skel-md { width: 55%; }
.skel-sm { width: 40%; }
.skel-chip { width: 84px; height: 22px; border-radius: 999px; }
@keyframes skel-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; }
}

/* Dashboard match-card skeleton (reuses .skel shimmer) */
.skel-card { pointer-events: none; }
.skel-card .skel { display: block; }
.skel-card .s-seal { width: 72px; height: 72px; border-radius: 50%; flex: none; }
.skel-card .s-l1 { height: 18px; width: 72%; }
.skel-card .s-l2 { height: 13px; width: 45%; margin-top: 10px; }
.skel-card .s-l3 { height: 12px; width: 92%; margin-top: 16px; }

/* ── Table footer: centered pager + page-size selector ─────────────────── */
.table-foot {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: var(--s3); margin-top: var(--s5);
}
.table-foot .pager { margin-top: 0; }                 /* pager sits in the middle column */
.per-page {
  grid-column: 3; justify-self: end;
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: var(--t-sm); white-space: nowrap;
}
.per-page select {
  padding: 6px var(--s3); border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink); font-size: var(--t-sm);
}
@media (max-width: 640px) {
  .table-foot { grid-template-columns: 1fr; justify-items: center; }
  .per-page { grid-column: 1; justify-self: center; }
}

/* ══ Live demo ════════════════════════════════════════════════════════════ */

/* Live-demo launcher — a compact, single-row accent-edge banner under the hero
   text (right column): orange spine, one line + a small CTA. Clean and small;
   clicking pops open the centered demo. */
:root { --ease-pop: cubic-bezier(.34, 1.25, .5, 1); }

.demo-banner {
  position: relative; overflow: hidden; width: auto; max-width: 100%; cursor: pointer; white-space: nowrap;
  margin-top: var(--s5); display: inline-flex; align-items: center; gap: var(--s2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-control);
  padding: 9px var(--s4); padding-inline-start: calc(var(--s4) + 6px);
  color: var(--ink); font-weight: 700; font-size: var(--t-sm);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
  animation: demo-banner-glow 3s ease-in-out infinite;
}
.demo-banner::before {
  content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; width: 5px; background: var(--accent);
}
.demo-banner:hover {
  transform: translateY(-2px); border-color: var(--accent); animation: none;
  box-shadow: 0 8px 20px rgb(28 43 51 / 0.12), 0 0 22px 3px rgb(232 101 13 / 0.30);
}
@keyframes demo-banner-glow {
  0%, 100% { box-shadow: var(--shadow), 0 0 13px 0 rgb(232 101 13 / 0.16); }
  50%      { box-shadow: var(--shadow), 0 0 22px 3px rgb(232 101 13 / 0.30); }
}
.demo-banner:focus-visible { outline: 3px solid var(--seal); outline-offset: 3px; }

.demo-banner-ic {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; background: var(--accent-fill); color: var(--on-accent);
}
.demo-banner-arrow { display: inline-flex; color: var(--accent); transform: rotate(90deg); }   /* chevron → points (RTL) left */
.demo-banner:hover .demo-banner-arrow { animation: demo-nudge .7s ease-in-out infinite; }
@keyframes demo-nudge { 0%, 100% { transform: rotate(90deg) translateY(0); } 50% { transform: rotate(90deg) translateY(3px); } }

@media (prefers-reduced-motion: reduce) {
  .demo-banner { transition: none; animation: none; box-shadow: var(--shadow), 0 0 14px 0 rgb(232 101 13 / 0.2); }
  .demo-banner:hover { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-launch { transition: none; }
  .demo-launch-eyebrow .pulse { animation: none; }
}

@media (max-width: 640px) {
  /* Landing launcher: centered under the (centered) hero text on phones.
     Small bottom gap so it reads as distinct from the tender example below. */
  .demo-banner { display: flex; width: fit-content; max-width: 100%; margin-inline: auto; margin-bottom: 3px; }
}

/* ── Demo chrome (inside the iframe) ── */
.demo-body { background: var(--paper); }
/* Bricks-to-assemble start hidden so a cold load never flashes them in place
   first; the (inline) assemble script reveals them by dropping this class. */
.demo-anim [data-brick] { opacity: 0; }
.demo-topbar {
  position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: var(--s4);
  padding: var(--s3) var(--s5); background: var(--surface); border-bottom: 1px solid var(--line);
}
/* Brand in the demo bar — same look as the real site's top nav. */
.demo-brand { flex: none; }
.demo-topbar-fill { flex: 1; }
.demo-nav { display: flex; gap: var(--s2); flex: 1; }
.demo-nav a {
  display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px;
  border-radius: var(--r-control); color: var(--ink-soft); font-weight: 500; font-size: var(--t-sm);
}
.demo-nav a:hover { background: var(--paper); color: var(--ink); }
.demo-nav a.active { background: var(--seal-wash); color: var(--seal); font-weight: 700; }
.demo-top-right { display: flex; align-items: center; gap: var(--s3); flex: none; }
.demo-profile { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: var(--t-sm); }
.demo-switch { font-size: var(--t-xs); color: var(--seal); }
.demo-close {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 7px 12px; border-radius: var(--r-control);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft); font-size: var(--t-sm);
}
.demo-close:hover { border-color: var(--bad); color: var(--bad); }

.demo-shell { padding: var(--s5); }
.demo-main { min-width: 0; max-width: 820px; margin-inline: auto; }

/* "This is a partial demo" ribbon, under the topbar on every demo screen. */
.demo-notice {
  display: flex; align-items: center; gap: 8px; justify-content: center;
  padding: 10px var(--s5); font-size: var(--t-sm); color: var(--accent-ink);
  background: var(--accent-wash); border-bottom: 1px solid var(--line);
}
.demo-notice .lucide { flex: none; color: var(--accent); }

/* Profile chooser */
.demo-chooser { max-width: 1080px; margin: 0 auto; padding: var(--s7) var(--s5); text-align: center; }
.demo-chooser h1 { font-size: var(--t-xl); margin-bottom: var(--s2); }
.demo-chooser-sub { max-width: 640px; margin: 0 auto var(--s6); }
.demo-disclaimer { display: flex; align-items: flex-start; gap: 6px; justify-content: center; max-width: 680px; margin: var(--s6) auto 0; padding: var(--s3) var(--s4); background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--line)); border-radius: var(--r-card); color: var(--accent-ink); font-size: var(--t-sm); text-align: start; }
.demo-disclaimer .lucide { flex: none; margin-top: 2px; }
.demo-profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s4); }
.demo-profile-card {
  position: relative; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: var(--s2); text-align: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: var(--s5); box-shadow: var(--shadow-card);
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
/* The whole card is the click target. A transparent submit button is stretched
   over it so a click/tap anywhere — and keyboard focus + Enter — starts the demo. */
.demo-profile-go {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; padding: 0; border: 0; background: transparent;
  border-radius: inherit; cursor: pointer; appearance: none;
}
.demo-profile-card:hover { transform: translateY(-3px); border-color: var(--seal); box-shadow: var(--shadow-card-hover, 0 8px 24px rgba(0,0,0,.1)); }
.demo-profile-card:hover .demo-profile-cta { gap: 8px; }
.demo-profile-card:focus-within { border-color: var(--seal); box-shadow: 0 0 0 3px var(--seal-wash); }
.demo-profile-go:focus { outline: none; }
.demo-profile-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; border-radius: 16px; background: var(--seal-wash); color: var(--seal);
}
.demo-profile-card h3 { font-size: var(--t-md); }
.demo-profile-card p { font-size: var(--t-sm); color: var(--ink-soft); min-height: 42px; }
.demo-profile-class { font-size: var(--t-xs); color: var(--accent-ink); font-weight: 700; margin-bottom: var(--s2); }
/* Subtle text CTA (replaces the big orange button — the card itself is clickable). */
.demo-profile-cta {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--accent); font-weight: 700; font-size: var(--t-sm);
  transition: gap .18s ease;
}

/* Source-gated popup */
.demo-modal {
  position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center;
  padding: var(--s4); background: rgb(28 43 51 / 0.5);
}
.demo-modal-card {
  background: var(--surface); border-radius: var(--r-card); padding: var(--s6) var(--s5);
  max-width: 420px; text-align: center; box-shadow: 0 20px 50px rgb(28 43 51 / 0.35);
}
.demo-modal-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 50%; background: var(--seal-wash); color: var(--seal); margin-bottom: var(--s3);
}
.demo-modal-card h3 { font-size: var(--t-md); margin-bottom: var(--s2); }
.demo-modal-card p { color: var(--ink-soft); font-size: var(--t-sm); margin-bottom: var(--s4); line-height: 1.5; }
.demo-modal-actions { display: flex; gap: var(--s2); justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .demo-launch, .demo-stage-frame { transition: none; }
}

@media (max-width: 820px) {
  .demo-nav a span { display: none; }             /* icons-only nav on small */
}

/* Phone: the demo top bar must fit the width so the exit (✕) stays on screen —
   drop the brand/profile/switch, tighten spacing, leaving nav + close. */
@media (max-width: 640px) {
  .demo-topbar { gap: var(--s2); padding: var(--s2) var(--s3); }
  .demo-brand, .demo-profile, .demo-switch { display: none; }
  .demo-shell { padding: var(--s4) var(--s3); }
}

/* ── Browse/saved table: click-to-expand row details ─────────────────────── */
.t-row { cursor: pointer; }
.t-row:hover { background: var(--paper); }
.t-caret {
  display: inline-flex; vertical-align: -2px; margin-inline-end: 6px; color: var(--ink-soft);
  transition: transform .2s ease, color .2s ease;
}
.t-row[aria-expanded="true"] .t-caret { transform: rotate(180deg); color: var(--accent); }
.t-row[aria-expanded="true"] > td { background: var(--paper); }
/* Continue the detail's accent edge up through the expanded row, on its edge
   cell — the last cell in RTL, the first cell in LTR (otherwise the LTR site
   paints a stray orange line down the middle, on the actions column). */
[dir="rtl"] .t-row[aria-expanded="true"] > td:last-child,
[dir="ltr"] .t-row[aria-expanded="true"] > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
/* The detail cell stays a real table-cell so colspan spans the full row width;
   the layout lives on an inner grid. A soft paper panel with an accent edge
   ties it to the row it belongs to. */
.t-detail-row > td.t-detail {
  padding: 0; border-top: 0;
  background: var(--paper); border-bottom: 1px solid var(--line);
  /* Accent on the start edge of the expanded panel. A real border renders
     reliably at the cell edge; an inset box-shadow misrenders (lands mid-cell)
     on border-collapse table cells, which put a stray orange line across the
     description. */
  border-inline-start: 3px solid var(--accent);
}
.t-detail-inner {
  display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: var(--s4) var(--s6); align-items: start;
  padding: var(--s4) var(--s5) var(--s5);
}
.t-detail-main { display: flex; flex-direction: column; gap: var(--s3); min-width: 0; }
/* "This may already have closed" — the public page's .pt-stale, in the app.
   Same amber start-edge, no fill: a caution, not an error, and it sits above
   an analysis the reader is still meant to read. Tokens throughout, so it
   follows the theme; the amber is the one literal, as it is on .pt-stale. */
.t-detail-stale { background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid #C98A2E; border-radius: var(--r-card);
  padding: 11px 14px; }
.t-detail-stale strong { display: block; font-size: var(--t-sm); color: var(--ink);
  margin: 0 0 3px; }
.t-detail-stale span { display: block; font-size: var(--t-xs); color: var(--ink-soft);
  line-height: 1.6; }
/* Placeholder while the panel is fetched. Only ever visible during the request
   itself — the row is hidden until it is expanded, and a hover usually has the
   content in place before the click. */
.t-detail-skel {
  display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: var(--s4) var(--s6); align-items: start;
  padding: var(--s4) var(--s5) var(--s5);
}
.t-detail-skel .skel { display: block; height: 16px; margin-bottom: 10px; }
.t-detail-err { padding: var(--s4) var(--s5); margin: 0; }
.t-detail-summary { font-size: var(--t-sm); color: var(--ink); line-height: 1.6; margin: 0; }

/* UK fit card reuses the table's detail grid, but tighter (narrower column) and
   with the card's own padding. Stacks on a narrow card so nothing crowds. */
.fitcard-grid { padding: var(--s3) var(--s5) var(--s4); gap: var(--s3) var(--s5); grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
.fitcard .t-detail-side { border-inline-start: 1px solid var(--line); padding-inline-start: var(--s4); }
.fitcard-portal { align-self: start; margin-top: var(--s1); }
@media (max-width: 560px) { .fitcard-grid { grid-template-columns: 1fr; } .fitcard .t-detail-side { border-inline-start: 0; padding-inline-start: 0; border-top: 1px solid var(--line); padding-top: var(--s3); } }
/* Readiness action-plan items (what to close / verify before bidding) */
.rd-items { list-style: none; margin: var(--s2) 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.rd-items li { display: flex; align-items: flex-start; gap: 6px; font-size: var(--t-sm); color: var(--ink); line-height: 1.4; }
.rd-items .lucide { flex: none; margin-top: 2px; color: var(--check); }
.rd-items-close .lucide { color: var(--bad); }
/* Merged readiness list: per-item icon colour + collapse-to-4 with a fade cue. */
.rd-i-met .lucide { color: var(--ok); }
.rd-i-cert .lucide { color: var(--seal); }
.rd-i-gap .lucide { color: var(--bad); }
.rd-i-verify .lucide { color: var(--check); }
.rd-listwrap { position: relative; }
.rd-collapsible.collapsed li:nth-child(n+5) { display: none; }
.rd-fade { display: none; }
.rd-collapsible.collapsed ~ .rd-fade { display: block; position: absolute; inset-inline: 0; bottom: 0;
  height: 26px; background: linear-gradient(to bottom, transparent, var(--paper)); pointer-events: none; }
.rd-more { display: inline-flex; align-items: center; gap: 5px; background: none; border: 0; cursor: pointer;
  color: var(--seal); font-weight: 700; font-size: var(--t-xs); padding: 3px 0; }
.rd-more .chev { transition: transform .18s ease; }
.rd-more.open .chev { transform: rotate(180deg); }
/* "Where you stand" panel at the top of a tracked tender's detail (flush, not the
   fitcard's insets). */
.tracked-readiness { margin: 0 0 var(--s4); }
.t-detail-conds h4 { font-size: var(--t-sm); display: flex; align-items: center; gap: 6px; margin: 0 0 var(--s2); color: var(--ink); }
.t-detail-conds h4 .lucide { color: var(--seal); }
.t-detail-conds ul { margin: 0; padding-inline-start: 20px; }
.t-detail-conds li { font-size: var(--t-sm); color: var(--ink-soft); margin: 3px 0; line-height: 1.45; }
.t-detail-conds li b { color: var(--ink); }

/* Facts: a tidy label/value list filling the side column. */
.t-detail-side { display: flex; flex-direction: column; gap: var(--s3); min-width: 0; }
.t-detail-facts { margin: 0; display: flex; flex-direction: column; gap: 7px; }
/* Each fact is a 2-column grid (label | value) so every value starts on the
   same axis and wrapping text stays in its own column — the flex/space-between
   version squeezed values into char-by-char wraps next to two-line labels. */
.t-detail-facts > div {
  display: grid; grid-template-columns: fit-content(46%) 1fr;
  align-items: start; column-gap: var(--s3);
  font-size: var(--t-sm); border-bottom: 1px dashed var(--line); padding-bottom: 6px;
}
.t-detail-facts > div:last-child { border-bottom: 0; padding-bottom: 0; }
.t-detail-facts dt { color: var(--ink-soft); display: inline-flex; align-items: flex-start; gap: 5px; }
.t-detail-facts dt .lucide { color: var(--ink-soft); }
.t-detail-facts dt svg { flex-shrink: 0; margin-top: 3px; }  /* first-line align beside wrapped labels */
.t-detail-facts dd { margin: 0; color: var(--ink); font-weight: 700; text-align: end;
  min-width: 0; overflow-wrap: anywhere; }
/* Sentence-length values (e.g. a free-text contract period) read badly
   right-aligned in a narrow column — give them the full row instead. */
.t-detail-facts dd.t-fact-long { grid-column: 1 / -1; text-align: start;
  font-weight: 600; margin-top: 2px; }
.t-detail-docs { font-size: var(--t-sm); color: var(--ink-soft); position: relative; }
.t-docs-label { display: inline-flex; align-items: center; gap: 4px; }
.t-docs-list { margin-top: 4px; max-height: 128px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.t-doc-link { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--seal); line-height: 1.6; min-width: 0; flex-shrink: 0; }
.t-doc-link:hover { text-decoration: underline; }
/* "more files below" affordance: a soft fade + bobbing chevron pinned to the
   bottom of the scroll area, shown only when the list overflows and hidden
   once the user has scrolled to the end (classes toggled in base.html). */
.t-docs-more {
  position: absolute; inset-inline: 0; bottom: 0; height: 26px;
  display: none; align-items: flex-end; justify-content: center;
  background: linear-gradient(to top, var(--paper) 42%, transparent);
  color: var(--accent); pointer-events: none;
}
.t-detail-docs.has-scroll .t-docs-more { display: flex; }
.t-detail-docs.has-scroll.is-bottom .t-docs-more { display: none; }
.t-docs-more-ic { display: inline-flex; animation: docs-bob 1.5s ease-in-out infinite; }
@keyframes docs-bob { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(2px); } }
@media (prefers-reduced-motion: reduce) { .t-docs-more-ic { animation: none; } }
.t-detail-pending { font-size: var(--t-sm); display: inline-flex; align-items: center; gap: 6px; }

/* ---- CPV codes (main + additional, additional truncated behind <details>) ---- */
.t-detail-cpv { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: var(--s2) 0; font-size: var(--t-sm); }
.t-cpv-label { display: inline-flex; align-items: center; gap: 4px; color: var(--ink-soft); }
.cpv-chip {
  display: inline-flex; align-items: center;
  padding: 3px 9px; border-radius: 999px;
  background: var(--paper); color: var(--ink-soft);
  font-size: var(--t-xs); line-height: 1.5;
}
.cpv-chip.cpv-main { background: var(--seal-wash); color: var(--seal); font-weight: 600; }
.cpv-more { display: inline; }
.cpv-more > summary {
  display: inline-flex; align-items: center; cursor: pointer; list-style: none;
  padding: 3px 9px; border-radius: 999px; background: var(--paper);
  color: var(--accent); font-size: var(--t-xs); font-weight: 600;
}
.cpv-more > summary::-webkit-details-marker { display: none; }
.cpv-more > summary:hover { text-decoration: underline; }
.cpv-more[open] > summary { color: var(--ink-soft); }
.cpv-more[open] { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

/* Key-points / eligibility sections — same visual rhythm as t-detail-conds. */
.t-detail-kpoints h4 { font-size: var(--t-sm); display: flex; align-items: center; gap: 6px; margin: 0 0 var(--s2); color: var(--ink); }
.t-detail-kpoints h4 .lucide { color: var(--seal); }
.t-detail-kpoints ul { margin: 0; padding-inline-start: 20px; }
.t-detail-kpoints li { font-size: var(--t-sm); color: var(--ink-soft); margin: 3px 0; line-height: 1.45; }

/* Confidence row: stacks the label, chip and its plain-language explanation
   as a full-width block instead of the usual label/value flex split. */
.t-detail-facts > div.t-fact-block { flex-direction: column; align-items: stretch; gap: 5px; }
.t-conf-dd { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.t-conf-explain { font-size: var(--t-xs); color: var(--ink-soft); font-weight: 400; line-height: 1.5; }
/* Confidence on the fit card: chip sits on the row with the label (normal fact
   row), the explanation runs full-width underneath. */
/* Confidence chip row + its explanation form ONE block: no dashed separator
   between them (the separator above the chip already opens the section). */
.t-detail-facts > .t-conf-row { border-bottom: 0; padding-bottom: 4px; }
/* display:block overrides the inherited label|value grid (which squeezed the
   explanation into the ~46% first column) so the sentence spans the full width
   of wherever it sits — all-tenders detail, matched cards, and the board. */
.t-detail-facts > .t-conf-note { display: block; font-size: var(--t-xs); color: var(--ink-soft); line-height: 1.5; border-bottom: 0; padding: 0 0 2px; }

/* Head-start provenance: a now-live tender that grew out of a planning notice
   we'd been listing. Full-width, softly accented row so the link between the
   pipeline entry and the opportunity it became reads as one deliberate story
   (radar → "opened for bids", with "spotted in planning {date}" alongside),
   not just another cramped date field. */
.t-detail-facts > .fact-golive {
  grid-column: 1 / -1; border: 1px solid var(--seal); background: var(--seal-wash);
  border-radius: var(--r-card, 8px); padding: 7px 10px;
}
.t-detail-facts > .fact-golive dt { color: var(--accent-ink); font-weight: 700; }
.t-detail-facts > .fact-golive dt svg { color: var(--seal); }
.fact-golive-since { font-weight: 400; font-size: var(--t-xs); color: var(--ink-soft); }

/* Confidence badge in the side-facts panel. */
.t-conf-chip { display: inline-block; font-size: 11px; font-weight: 600; border-radius: 10px; padding: 1px 8px; }
.conf-high   { background: #d1fae5; color: #065f46; }
.conf-medium { background: #fef3c7; color: #92400e; }
.conf-low    { background: #fee2e2; color: #991b1b; }

@media (max-width: 720px) {
  .t-detail-inner { grid-template-columns: 1fr; }
}

/* ---------- Workspace calendar (deadlines) ---------- */
.cal-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s4); }
.cal-nav { display: flex; align-items: center; gap: var(--s2); }
.cal-arrow { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: var(--r-control); border: 1px solid var(--line); color: var(--ink); background: var(--surface); }
.cal-arrow:hover { background: var(--paper); }
/* Month arrows use explicit directional chevrons chosen by text direction in
   the template (chevron-left/right), so no rotation is needed here. */
.cal-month { font-family: var(--font-display); font-size: var(--t-lg); color: var(--ink); min-width: 8.5ch; text-align: center; }
.cal-today { height: 34px; }
.cal-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.cal-toggle { cursor: pointer; }

.cal-grid { border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; background: var(--surface); }
.cal-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); background: var(--paper); border-bottom: 1px solid var(--line); }
.cal-weekdays span { padding: 8px 6px; text-align: center; font-size: var(--t-xs); font-weight: 700; color: var(--ink-soft); }
.cal-weekdays span.is-weekend { color: var(--accent-ink); }
.cal-week { display: grid; grid-template-columns: repeat(7, 1fr); }
/* Fixed, uniform cells so the date grid never shifts; overflow events collapse
   behind a "+N" button that expands the single cell on demand. */
.cal-cell { height: 124px; border-inline-start: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 4px; display: flex; flex-direction: column; gap: 3px; overflow: hidden; position: relative; }
.cal-cell.is-expanded { height: auto; min-height: 124px; z-index: 3; box-shadow: var(--shadow-card); }
.cal-week:last-child .cal-cell { border-bottom: 0; }
.cal-cell:first-child { border-inline-start: 0; }
.cal-cell.is-other { background: var(--paper); }
.cal-cell.is-other .cal-daynum { color: var(--line); }
.cal-cell.is-weekend { background: color-mix(in srgb, var(--paper) 60%, var(--surface)); }
.cal-cell.is-today { background: var(--seal-wash); }
.cal-daynum { font-size: var(--t-xs); font-weight: 700; color: var(--ink-soft); align-self: flex-start; padding: 1px 4px; flex: none; }
.cal-cell.is-today .cal-daynum { background: var(--seal); color: #fff; border-radius: 6px; }
.cal-cell-evs { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cal-cell-rest { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
.cal-more { align-self: stretch; margin-top: auto; border: 0; background: var(--paper); color: var(--ink-soft); font: inherit; font-size: var(--t-xs); font-weight: 700; padding: 2px; border-radius: 5px; cursor: pointer; }
.cal-more:hover { background: var(--seal-wash); color: var(--seal); }

.cal-ev { display: flex; align-items: center; gap: 4px; padding: 1px 6px; min-height: 18px; border-radius: 5px; font-size: 11px; line-height: 1.35; overflow: hidden; }
.cal-ev .cal-ev-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-ev:hover { text-decoration: none; filter: brightness(0.97); }
.cal-ev-time { font-weight: 700; flex: none; }
.cal-ev-who { flex: none; margin-inline-start: auto; width: 17px; height: 17px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 700; background: var(--surface); border: 1px solid var(--line); }
/* Milestones: solid, colored by kind; urgency intensifies the submission one. */
.cal-ms-submission { background: var(--accent-wash); color: var(--accent-ink); font-weight: 700; }
.cal-ms-submission.u-today, .cal-ms-submission.u-soon { background: var(--accent-fill); color: var(--on-accent); }
.cal-ms-submission.u-today .cal-ev-who, .cal-ms-submission.u-soon .cal-ev-who { background: rgba(255,255,255,.25); border-color: transparent; color: #fff; }
.cal-ms-site_tour { background: var(--seal-wash); color: var(--seal); font-weight: 700; }
.cal-ms.u-passed { opacity: .55; }
/* Reminder flags: muted countdown pills. */
.cal-rem { background: var(--paper); color: var(--ink-soft); border: 1px dashed var(--line); }
.cal-rem .lucide { flex: none; }

.cal-agenda { display: flex; flex-direction: column; gap: var(--s2); }
.cal-ag-day { display: grid; grid-template-columns: 11rem 1fr; gap: var(--s3); padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.cal-ag-day.is-today .cal-ag-date { color: var(--seal); font-weight: 700; }
.cal-ag-date { color: var(--ink); font-size: var(--t-sm); }
.cal-ag-evs { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.cal-ag-evs .cal-ev { padding: 5px 10px; font-size: var(--t-sm); border-radius: var(--r-control); }

.cal-subscribe { margin-top: var(--s5); }
/* UK: contour-band variant — band header on top, padded body below, app chips. */
.cal-sub-uk { min-height: 0; }
/* App pages don't define the landing --lp-* vars — pin the band colors here
   (--accent is the same construction orange as the landing's --lp-accent). */
.cal-sub-uk .lpt-head { color: var(--accent); border-bottom-color: var(--line); }
.cal-sub-uk .lpt-head h3 { color: var(--accent); }
.cal-sub-uk .cal-sub-body { padding: var(--s4) var(--s5) var(--s5); }
.cal-sub-uk .cal-sub-hint { margin: 0 0 var(--s3); }
.cal-sub-uk .cal-sub-field { margin-top: 0; }
.cal-app-chip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px;
  margin-inline-end: 6px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 12px; color: var(--ink-soft); background: var(--paper); }
.cal-app-chip svg { color: var(--seal); }
.cal-sub-top { display: flex; align-items: flex-start; gap: var(--s3); }
.cal-sub-ic { flex: none; width: 40px; height: 40px; border-radius: var(--r-control); background: var(--seal-wash); color: var(--seal); display: inline-flex; align-items: center; justify-content: center; }
.cal-sub-intro h2 { margin: 0 0 2px; }
.cal-sub-intro p { margin: 0; }
/* URL + copy as one aligned unit. */
.cal-sub-field { display: flex; align-items: stretch; margin-top: var(--s4); border: 1px solid var(--line); border-radius: var(--r-control); overflow: hidden; background: var(--surface); transition: border-color .12s ease, box-shadow .12s ease; }
.cal-sub-field:focus-within { border-color: var(--seal); box-shadow: 0 0 0 3px var(--seal-wash); }
.cal-sub-url { flex: 1; min-width: 0; border: 0; background: transparent; height: 44px; padding: 0 12px; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: var(--t-sm); color: var(--ink-soft); }
.cal-sub-url:focus { outline: none; }
.cal-sub-copy { flex: none; display: inline-flex; align-items: center; gap: 6px; border: 0; border-inline-start: 1px solid var(--line); background: var(--seal-wash); color: var(--seal); padding: 0 16px; cursor: pointer; font: inherit; font-weight: 700; font-size: var(--t-sm); white-space: nowrap; transition: background .12s ease, color .12s ease; }
.cal-sub-copy:hover { background: var(--seal); color: #fff; }
.cal-sub-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s3); }
.cal-sub-apps { display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-xs); }
.cal-sub-apps .lucide { color: var(--ok); }
.cal-rotate { margin: 0; }
.cal-rotate .btn { padding: 6px 12px; font-size: var(--t-xs); }

@media (max-width: 720px) {
  .cal-cell { height: 96px; padding: 2px; }
  .cal-cell.is-expanded { height: auto; }
  .cal-ev { font-size: 10px; padding: 1px 4px; gap: 2px; }
  .cal-ev-who { display: none; }  /* too tight on a phone-width cell */
  .cal-ag-day { grid-template-columns: 1fr; gap: 4px; }
}
@media (max-width: 460px) {
  .cal-sub-copy-label { display: none; }  /* icon-only copy on tiny screens */
  .cal-sub-copy { padding: 0 12px; }
}

/* Card flashed when arriving from the calendar (?focus=<id>). */
.saved-card.is-focused, .kb-card.is-focused, .award-form.is-focused {
  outline: 2px solid var(--seal); outline-offset: 2px; border-radius: var(--r-card);
  animation: focusFlash 2.4s ease;
}
@keyframes focusFlash {
  0%, 12% { box-shadow: 0 0 0 5px var(--seal-wash); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) { .saved-card.is-focused, .kb-card.is-focused, .award-form.is-focused { animation: none; } }

/* ---------- Notification center — left-edge expander ---------- */
/* A slim tab pinned to the left edge (the "hint"); clicking slides out a drawer
   with the deadline reminders. Kept out of the crowded top nav. */
.notif-dock { position: fixed; left: 0; top: 96px; z-index: 60; display: flex; align-items: flex-start; }
.notif-tab { flex: none; display: flex; flex-direction: column; align-items: center; gap: 3px; background: var(--accent-fill); color: var(--on-accent); border: 0; cursor: pointer; padding: 9px 7px; border-radius: 0 12px 12px 0; box-shadow: 2px 2px 8px rgb(28 43 51 / 0.18); }
.notif-tab:hover { filter: brightness(1.05); }
.notif-tab .lucide { color: #fff; }
.notif-badge { min-width: 18px; height: 18px; padding: 0 4px; border-radius: 999px; background: var(--surface); color: var(--accent); font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.notif-drawer { margin-inline-start: 6px; width: 340px; max-width: calc(100vw - 64px); max-height: 76vh; display: flex; flex-direction: column; background: color-mix(in srgb, var(--surface) 82%, transparent); backdrop-filter: blur(10px) saturate(1.1); -webkit-backdrop-filter: blur(10px) saturate(1.1); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-card); overflow: hidden; }
/* LTR markets (UK): dock the alerts tab on the right edge; the drawer opens
   inward to the left. RTL (Hebrew) keeps the left-edge default above. */
html[dir="ltr"] .notif-dock { left: auto; right: 0; flex-direction: row-reverse; }
html[dir="ltr"] .notif-tab { border-radius: 12px 0 0 12px; box-shadow: -2px 2px 8px rgb(28 43 51 / 0.18); }
html[dir="ltr"] .notif-drawer { margin-inline-start: 0; margin-inline-end: 6px; }
.notif-head { display: flex; align-items: center; gap: 6px; padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); font-weight: 700; color: var(--ink); font-size: var(--t-sm); }
.notif-close { margin-inline-start: auto; width: 26px; height: 26px; border: 0; border-radius: 50%; background: transparent; color: var(--ink-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.notif-close:hover { background: var(--paper); color: var(--ink); }
.notif-head-title { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.notif-filter { display: inline-flex; }
.notif-filter .nf-btn { padding: 3px 9px; font-size: var(--t-xs); font-weight: 700; }
.notif-list { overflow-y: auto; }
.notif-list.mine-only .notif-item[data-mine="0"] { display: none; }
.notif-empty { padding: var(--s5) var(--s4); text-align: center; color: var(--ink-soft); font-size: var(--t-sm); }
.notif-item { display: flex; align-items: center; gap: var(--s2); padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); }
.notif-item:last-child { border-bottom: 0; }
.notif-link { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; color: var(--ink); }
.notif-link:hover { text-decoration: none; }
.notif-when { font-weight: 700; font-size: var(--t-xs); color: var(--accent-ink); }
.notif-item.u-today .notif-when, .notif-item.u-soon .notif-when { color: var(--accent); }
.notif-text { font-size: var(--t-sm); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notif-x { flex: none; width: 24px; height: 24px; border-radius: 50%; border: 0; background: transparent; color: var(--ink-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.notif-x:hover { background: var(--paper); color: var(--ink); }
.notif-foot { display: flex; align-items: center; justify-content: center; gap: 4px; padding: var(--s3); color: var(--accent-ink); font-weight: 700; font-size: var(--t-sm); border-top: 1px solid var(--line); }
.notif-foot:hover { background: var(--paper); text-decoration: none; }

/* Mention alerts: an @-tag + a snippet of the note, distinct from deadline rows. */
.notif-mention { align-items: flex-start; }
.notif-mention .notif-link { flex-direction: row; align-items: flex-start; gap: var(--s2); }
.notif-ic { flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--seal-wash); color: var(--seal); display: inline-flex; align-items: center; justify-content: center; margin-top: 1px; }
.notif-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.notif-mention .notif-text { white-space: normal; }
.notif-sub { font-size: var(--t-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notif-mention .notif-when { flex: none; font-weight: 500; color: var(--ink-soft); }

/* ---------- User guide (manual) ---------- */
.guide-note { display: flex; align-items: flex-start; gap: 6px; background: var(--wash); border-inline-start: 3px solid var(--accent); border-radius: 4px; padding: var(--s3) var(--s4); margin: var(--s4) 0; font-size: var(--t-sm); color: var(--ink-soft); }
.guide-fields { display: grid; gap: var(--s3); margin: var(--s4) 0; }
.guide-fields dt { font-weight: 600; color: var(--ink); }
.guide-fields dd { margin: 2px 0 0 0; color: var(--ink-soft); font-size: var(--t-sm); }
.guide-fields ul { margin: 4px 0 0; padding-inline-start: 18px; }
.guide-fields ul li { margin: 2px 0; }
.guide-toc { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s4) var(--s5); margin: var(--s5) 0; }
.guide-toc h2 { margin: 0 0 var(--s2); font-size: var(--t-md); font-family: var(--font-display); }
.guide-toc ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.guide-toc a { color: var(--accent-ink); }
.guide .blog-body h2, .guide .blog-body h3 { scroll-margin-top: 84px; }  /* clear the sticky header on anchor jumps */
.settings-guide-link {
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s4) var(--s5); margin-bottom: var(--s5);
  text-decoration: none; color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--seal) 18%, var(--line));
  border-radius: var(--r-card);
  background: linear-gradient(135deg, var(--seal-wash), color-mix(in srgb, var(--seal-wash) 40%, var(--surface)));
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.settings-guide-link:hover {
  text-decoration: none;
  border-color: color-mix(in srgb, var(--seal) 45%, var(--line));
  box-shadow: 0 4px 16px -8px color-mix(in srgb, var(--seal) 50%, transparent);
}
.settings-guide-ic {
  flex: none; width: 44px; height: 44px; border-radius: var(--r-control);
  background: var(--surface); color: var(--seal);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 3px color-mix(in srgb, var(--seal) 20%, transparent);
}
.settings-guide-text { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.settings-guide-text strong { font-family: var(--font-display); font-size: var(--t-md); }
.settings-guide-hint { font-size: var(--t-sm); color: var(--ink-soft); }
.settings-guide-cta {
  flex: none; display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--t-sm); font-weight: 700; color: var(--accent-ink);
}
.settings-guide-cta .lucide { transition: transform .15s ease; }
.settings-guide-link:hover .settings-guide-cta .lucide { transform: translate(-2px, -2px); }
@media (max-width: 560px) { .settings-guide-cta { display: none; } }

/* UK profile: contract-value range (two number inputs with a separator). */
.range-row { display: flex; align-items: center; gap: var(--s3); }
.range-row input { flex: 1 1 0; min-width: 0; }
.range-row .range-sep { color: var(--muted); flex: 0 0 auto; }

/* Advanced filters (all-tenders): flows straight on from the basic fields (no
   separator) and expands with a smooth height + chevron animation. */
.adv-filters { display: grid; }
/* Toggle is the bottom handle; the panel above it opens upward. */
.adv-filters { grid-template-rows: auto auto; }
.adv-toggle { order: 2; cursor: pointer; display: inline-flex; align-items: center; gap: var(--s2);
  width: fit-content; border: 0; background: none; font: inherit;
  font-size: var(--t-sm); font-weight: 500; color: var(--ink-soft); user-select: none;
  padding: var(--s2) 0 var(--s1); }
.adv-toggle:hover { color: var(--ink); }
.adv-toggle-label { display: inline-flex; align-items: center; gap: 6px; }
/* Closed → chevron points up ("open upward"); open → points down ("close"). */
.adv-chev { transition: transform .25s ease; opacity: .65; transform: rotate(180deg); }
.adv-filters.is-open .adv-chev { transform: rotate(0deg); }
/* Grid-rows 0fr→1fr is the buttery accordion trick: the panel animates its real
   height with no JS height math, so opening/closing reads naturally. The panel
   sits above the toggle (order:1) so the fields appear between the basic filters
   and the handle. */
.adv-panel { order: 1; display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .28s cubic-bezier(.4, 0, .2, 1); }
.adv-filters.is-open .adv-panel { grid-template-rows: 1fr; }
/* The clipped element must collapse fully to 0 — so no padding/border/margin on
   it (spacing lives on the toggle above). */
.adv-panel > .adv-grid { overflow: hidden; min-height: 0; }
/* While a multiselect dropdown is open inside the (fully-expanded) advanced
   panel, let it overflow so the dropdown isn't clipped. Toggled by the
   multiselect JS; more specific than the clip rule above so order is irrelevant. */
.adv-panel > .adv-grid.ms-overflow { overflow: visible; }
/* Uniform, equal-width fields — matches the basic grid above it. */
.adv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(172px, 1fr));
  gap: var(--s1) var(--s4); align-items: end; }
.adv-grid .adv-span { grid-column: 1 / -1; }
/* Double-width field — gives the contract-value min–max pair room to breathe. */
.adv-grid .field-w2 { grid-column: span 2; }
.adv-grid .field { margin: 0; min-width: 0; }
.adv-grid .chip-row { margin-bottom: 0; margin-top: 6px; }
.adv-grid .chip-none { opacity: .8; }
@media (max-width: 640px) {
  .adv-grid { grid-template-columns: 1fr; }
  /* Reset the double-width value field: its `grid-column: span 2` would force an
     implicit 2nd column here, breaking the single-column intent into two cramped
     columns whose fields crowd/overlap. Span the single column instead. */
  .adv-grid .field-w2 { grid-column: 1 / -1; }
}

/* Bidvane Advanced Search — "?" help button + popover on the all-tenders search. */
.search-help-wrap { position: relative; display: inline-flex; align-items: center; }
.search-help-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--paper); color: var(--ink-soft); cursor: pointer; padding: 0;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.search-help-btn:hover { background: var(--surface); color: var(--seal); border-color: var(--seal); }
.search-help {
  position: absolute; inset-inline-end: 0; top: calc(100% + 8px); z-index: 60;
  width: min(440px, 92vw);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 14px 40px rgba(28,43,51,.16); padding: 12px 14px;
  font-size: var(--t-sm); color: var(--ink); line-height: 1.4; text-align: start;
}
.search-help .sh-head { display: flex; align-items: center; gap: 7px; font-size: 14px; }
.search-help .sh-intro { color: var(--ink-soft); margin: 5px 0 9px; font-size: 12.5px; }
.search-help h5 { margin: 0 0 4px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-soft); }
.search-help .sh-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 9px; }
/* The UI font, not a monospace stack. These chips are mostly HEBREW — field
   names and whole example queries — and ui-monospace/SFMono/Menlo carry no
   Hebrew glyphs, so the browser fell back per-character to a default serif.
   That is the "printed" look: not a design choice, a missing glyph. Heebo has
   the letters, and the chip's border and background are what mark it as
   something you can type, which never depended on the font.
   Size goes 11.5 -> 13px with it, since 11.5 was sized for a monospace face. */
.search-help code {
  font-family: var(--font-body); font-size: 13px; font-weight: 500;
  background: var(--paper); border: 1px solid var(--line); border-radius: 5px;
  padding: 1px 6px; color: var(--seal); white-space: nowrap;
  /* Each chip/example lays out in its own natural direction so mixed
     Hebrew-field + operator + number lines read correctly under RTL (IL).
     No-op for LTR English-only content (UK). */
  unicode-bidi: plaintext;
}
.search-help .sh-fields { display: flex; flex-wrap: wrap; gap: 4px; margin: 0; }
.search-help .sh-fields code { cursor: help; }  /* hover for the field's description */
.search-help .sh-ops { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.search-help .sh-ops li { display: flex; align-items: center; gap: 7px; color: var(--ink-soft); }
.search-help .sh-ex { list-style: none; margin: 4px 0 7px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.search-help .sh-ex code { cursor: pointer; white-space: normal; display: inline-block; }
.search-help .sh-ex code:hover { background: var(--surface); border-color: var(--seal); }
.search-help .sh-tip { color: var(--ink-soft); margin: 0; font-size: 11.5px; }
@media (max-width: 560px) { .search-help { position: fixed; inset-inline: 8px; inset-inline-end: 8px; top: auto; bottom: 12px; width: auto; } }

/* Filter sizing: keep the Procurement stage select to a normal dropdown width
   (don't let it stretch the whole wrapped row), and stop the advanced
   Confidence / Contract-value controls from over-widening for their content. */
/* Advanced fields fill their grid cell so every column is the same width. */
.adv-grid > label.field > select, .adv-grid .range-row { max-width: none; }

/* Blog cover art (shared by the listing cards and the article banner). */
.blog-hero { aspect-ratio: 400 / 190; width: 100%; line-height: 0; }
.blog-hero svg { width: 100%; height: 100%; display: block; }
/* Article-page hero banner (single, wide). */
.blog-article-hero { border-radius: var(--r-card); overflow: hidden; margin: var(--s3) 0 var(--s5);
  line-height: 0; box-shadow: var(--shadow); }
.blog-article-hero .blog-hero { aspect-ratio: 1100 / 300; }
/* ── Blog listing ───────────────────────────────────────────────────────────
   Every card answers the only question a visitor has — is this worth my time?
   — before the click: topic, headline, what it covers, how long it takes.
   Same visual language as the rest of the public site (seal blue, accent
   orange, hairline cards); the cover art is the per-slug SVG set above. */
.blg-head { max-width: 1060px; margin: 0 0 var(--s5); }
.blg-head h1 { font-size: clamp(30px, 4vw, 44px); line-height: 1.1; letter-spacing: -.02em; }
.blg-sub { margin: 10px 0 0; color: var(--ink-soft); font-size: var(--t-md);
  line-height: 1.6; max-width: 62ch; }

/* Topic filter — a table of contents that happens to filter. */
.blg-filters { max-width: 1060px; display: flex; flex-wrap: wrap; gap: 8px;
  margin: 0 0 var(--s5); padding-bottom: var(--s4); border-bottom: 1px solid var(--line); }
.blg-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  color: var(--ink-soft); font: inherit; font-size: var(--t-xs); font-weight: 600;
  cursor: pointer; transition: border-color .14s ease, color .14s ease, background .14s ease; }
.blg-chip:hover { border-color: var(--seal); color: var(--ink); }
.blg-chip.is-on { background: var(--seal); border-color: var(--seal); color: #fff; }
.blg-chip-n { font-size: 11px; font-weight: 700; opacity: .55; }

/* Topic label. A filled badge on all twelve cards read as badge soup next to
   the filter bar that already lists the same topics, so it's a quiet marker
   here — the colour belongs to the artwork and the hover state. */
.blg-topic { align-self: start; display: inline-flex; align-items: center; gap: 6px;
  color: var(--seal); font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; }
.blg-topic::before { content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; flex: none; }
/* …except on the featured card, where it sits beside the "featured" label and
   needs to hold its own. */
.blg-kicker .blg-topic { padding: 3px 9px; border-radius: 6px;
  background: var(--seal-wash); letter-spacing: .04em; }
.blg-kicker .blg-topic::before { display: none; }

/* Featured — art BESIDE the text, so the lead story reads as a lead story. */
.blg-feat { max-width: 1060px; display: grid; grid-template-columns: minmax(300px, 46%) 1fr;
  border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden;
  background: var(--surface); box-shadow: var(--shadow); text-decoration: none;
  margin-bottom: var(--s6, 28px);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.blg-feat:hover { transform: translateY(-3px); border-color: var(--accent);
  box-shadow: 0 18px 44px rgba(28,43,51,.16); text-decoration: none; }
.blg-feat-art { line-height: 0; overflow: hidden; }
.blg-feat-art .blog-hero { height: 100%; min-height: 260px; aspect-ratio: auto; }
.blg-feat-art .blog-hero svg { height: 100%; transition: transform .4s ease; }
.blg-feat:hover .blg-feat-art .blog-hero svg { transform: scale(1.04); }
.blg-feat-body { padding: var(--s5); display: flex; flex-direction: column;
  gap: 12px; justify-content: center; }
.blg-kicker { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.blg-featlbl { font-size: var(--t-xs); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent-ink); }
.blg-feat-title { font-family: var(--font-display); font-weight: 700;
  font-size: clamp(21px, 2.3vw, 29px); line-height: 1.22; color: var(--ink);
  text-wrap: balance; }
.blg-feat-excerpt { color: var(--ink-soft); font-size: var(--t-md); line-height: 1.6;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

.blg-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--t-sm); color: var(--ink-soft); }
.blg-dot { opacity: .5; }
.blg-go { margin-inline-start: auto; color: var(--accent-ink); font-weight: 700;
  display: inline-flex; align-items: center; gap: 6px; }
.blg-go-ic { transition: transform .16s ease; }
.blg-feat:hover .blg-go-ic { transform: translateX(3px); }
[dir="rtl"] .blg-go-ic { transform: scaleX(-1); }
[dir="rtl"] .blg-feat:hover .blg-go-ic { transform: scaleX(-1) translateX(3px); }

.blg-label { max-width: 1060px; font-family: var(--font-body); font-weight: 700;
  font-size: var(--t-xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 var(--s4); }

/* The listing is a menu, not a reading experience: twelve cards each carrying a
   tall illustration, a filled badge, a full paragraph and its own drop shadow
   asked the eye to process everything at once. Shorter art, two lines of
   summary and a flat resting state let the titles do the choosing — the detail
   is one click away, which is where it belongs. */
.blg-grid { max-width: 1060px; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--s5); }
.blg-card { display: flex; flex-direction: column; border: 1px solid var(--line);
  border-radius: var(--r-card); overflow: hidden; background: var(--surface);
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.blg-card:hover { transform: translateY(-3px); border-color: var(--accent);
  box-shadow: 0 16px 40px rgba(28,43,51,.16); text-decoration: none; }
/* Topic colour. Thirteen identical white rectangles read as a spreadsheet, so
   each card and its matching filter chip carry the hue of their subject — the
   same hues the article covers use, so a card and its cover agree. One custom
   property drives the rail, the label, the hover border and the chip. */
.blg-k-seal   { --blg-h: #16557A; }
.blg-k-cyan   { --blg-h: #1B6491; }
.blg-k-blue   { --blg-h: #2F5590; }
.blg-k-green  { --blg-h: #2C6B4C; }
.blg-k-indigo { --blg-h: #384A7C; }
.blg-k-teal   { --blg-h: #0E6E72; }
.blg-k-none   { --blg-h: var(--seal); }

.blg-card { position: relative; }
/* the rail: a hairline at rest, thickening into the hue on hover */
.blg-card::before { content: ""; position: absolute; inset: 0 0 auto; height: 3px;
  background: var(--blg-h, var(--seal)); opacity: .55;
  border-radius: var(--r-card) var(--r-card) 0 0;
  transition: opacity .18s ease; }
.blg-card:hover::before { opacity: 1; }
.blg-card:hover { border-color: var(--blg-h, var(--accent)); }
.blg-card .blg-topic { color: var(--blg-h, var(--seal)); }
.blg-chip:hover { border-color: var(--blg-h, var(--seal)); color: var(--ink); }
.blg-chip.is-on { background: var(--blg-h, var(--seal)); border-color: var(--blg-h, var(--seal)); }
/* the arrow only appears on hover — an affordance, not another glyph to scan */
.blg-card-go { margin-inline-start: auto; display: inline-flex; color: var(--blg-h, var(--seal));
  opacity: 0; transform: translateX(-4px);
  transition: opacity .18s ease, transform .18s ease; }
.blg-card:hover .blg-card-go { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .blg-card-go { transition: none; transform: none; }
}

/* Text-only cards: the cover art lives on the featured card and the article
   pages, not here. Roomier padding since the band no longer opens the card. */
.blg-card-body { padding: var(--s5) var(--s5) var(--s4); display: flex;
  flex-direction: column; gap: 10px; flex: 1 1 auto; }
.blg-card-title { font-family: var(--font-display); font-weight: 700; font-size: var(--t-md);
  line-height: 1.3; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; overflow: hidden; text-wrap: pretty; }
.blg-card-excerpt { color: var(--ink-soft); font-size: var(--t-sm); line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Pins the meta row to the card's bottom edge so dates line up across a row
   of cards whose titles wrap to different heights. */
.blg-card-body .blg-meta { margin-top: auto; padding-top: 2px; }
.blg-empty { max-width: 1060px; color: var(--ink-soft); padding: var(--s5) 0; }

@media (max-width: 720px) {
  .blg-feat { grid-template-columns: 1fr; }
  .blg-feat-art .blog-hero { min-height: 0; aspect-ratio: 400 / 190; }
  .blg-feat-body { padding: var(--s4); }
}
/* One column on a phone means twelve full-width cards stacked — a very long
   thumb. Below 560px each card turns on its side: a square crop of the same
   artwork beside the text, which roughly halves the height of the list without
   dropping anything from it. */
@media (max-width: 560px) {
  .blg-grid { grid-template-columns: 1fr; gap: var(--s4); }
  .blg-card-body { padding: var(--s4); gap: 8px; min-width: 0; }
  .blg-card-title { font-size: var(--t-sm); -webkit-line-clamp: 3; }
}
@media (prefers-reduced-motion: reduce) {
  .blg-feat, .blg-card, .blg-go-ic,
  .blg-feat-art .blog-hero svg { transition: none; }
  .blg-feat:hover, .blg-card:hover { transform: none; }
  .blg-feat:hover .blg-feat-art .blog-hero svg { transform: none; }
}

/* Advanced Search: inline ghost-text completion overlaid on the search field.
   Mirrors the input's box (border + padding + font) so the grey suffix lines up
   exactly after the typed text; the typed part is transparent so the real input
   text shows through. */
.search-ghost { position: absolute; inset: 0; z-index: 2; pointer-events: none;
  display: flex; align-items: center; padding-inline-start: 42px; padding-inline-end: 36px;
  border: 1px solid transparent; font-size: var(--t-md); white-space: pre; overflow: hidden; }
.search-ghost .sg-typed { color: transparent; }
.search-ghost .sg-suffix { color: var(--ink-soft); opacity: .6; }
/* "Tab to complete" keycap hint — only while a completion is showing. */
.search-ghost .sg-tab { display: none; margin-inline-start: 8px; align-self: center;
  font-family: inherit; font-size: 10px; line-height: 1; letter-spacing: .02em;
  color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line);
  border-radius: 5px; padding: 3px 6px; box-shadow: 0 1px 0 var(--line); white-space: nowrap; }
.search-ghost.has-suffix .sg-tab { display: inline-flex; align-items: center; }
@media (max-width: 560px) { .search-ghost .sg-tab { display: none !important; } }
/* Basic/Advanced toggle reuses the dashboard sort-seg pill; reset the <button>. */
.search-mode { flex: none; }
.search-mode .sort-opt { border: 0; background: transparent; cursor: pointer; font-family: inherit; }
@media (max-width: 560px) { .search-mode { display: none; } }

/* Divider between the search row and the filter controls (they're separate). */
.filterbar .search-divider { flex: 0 0 100%; width: 100%; height: 0; border: 0;
  border-top: 1px solid var(--line); margin: 0; }

/* Advanced-search syntax error: a specific, actionable message telling the user
   exactly what to fix in their query. Spans the full filter-bar width. */
.filterbar .search-err { flex: 0 0 100%; width: 100%; display: flex; gap: var(--s2);
  align-items: flex-start; margin: calc(var(--s1) * -1) 0 var(--s1);
  padding: 10px var(--s3); border: 1px solid color-mix(in srgb, var(--bad) 45%, var(--line));
  border-radius: var(--r-control); background: var(--bad-wash);
  color: var(--ink); font-size: var(--t-sm); line-height: 1.45; }
.search-err .search-err-ic { color: var(--bad); flex: none; margin-top: 1px; }
.search-err strong { font-weight: 650; }

/* ════════════════════════════════════════════════════════════════════════
   UK landing (Bidvane) — modern marketing page. Every selector is scoped to
   `.lp` (or the unique `.lp-announce` bar), so the IL landing (landing.html,
   which reuses .hero/.pricing/etc.) is completely unaffected.
   ════════════════════════════════════════════════════════════════════════ */
.lp { --lp-ink:#1C2B33; --lp-soft:#5A6B73; --lp-line:#E3E5DE; --lp-accent:#E8650D;
      --lp-accent2:#F59E2B; --lp-seal:#16557A; --lp-paper:#FAFAF7; }
.lp h1,.lp h2,.lp h3,.lp .lp-eyebrow,.lp .lp-kicker,.lp-announce {
  font-family:"Sora", system-ui, sans-serif; }
.lp-shell { max-width:1140px; margin:0 auto; padding:0 24px; }

/* Hero mock card (marketing-only markup; deliberately NOT the app's component
   classes so view-source doesn't document the product DOM). */
.lpm-card { background:#fff; border:1px solid var(--lp-line); border-radius:14px;
  box-shadow:0 18px 44px rgba(28,43,51,.10); overflow:hidden; }
.lpm-head { display:flex; gap:16px; padding:18px 20px; align-items:flex-start; }
.lpm-ring { position:relative; display:inline-grid; place-items:center; flex:none; }
.lpm-ring-num { position:absolute; inset:0; display:grid; place-content:center; text-align:center; }
.lpm-ring-num b { font-family:"Sora",sans-serif; font-weight:800; font-size:24px; color:var(--lp-seal); line-height:1; }
.lpm-ring-num small { font-size:9px; color:var(--lp-soft); letter-spacing:.06em; text-transform:uppercase; }
.lpm-main { flex:1; min-width:0; }
.lpm-title { font-family:"Sora",sans-serif; font-weight:700; font-size:17px; color:var(--lp-ink); margin:0 0 7px; }
.lpm-status { display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin:0 0 7px; font-size:13.5px; }
.lpm-status span { display:inline-flex; align-items:center; gap:4px; }
.lpm-ok { color:#1E7F4F; font-weight:700; }
.lpm-deadline { border-radius:999px; padding:2px 10px; background:var(--lp-accent); color:#fff; font-weight:600; font-size:12.5px; }
.lpm-context { display:flex; flex-wrap:wrap; align-items:center; gap:8px; font-size:13.5px; color:var(--lp-soft); }
.lpm-context span { display:inline-flex; align-items:center; gap:4px; }
.lpm-dot { color:var(--lp-line); }
.lpm-summary { margin:10px 0 0; color:var(--lp-ink); font-size:14px; line-height:1.5; }
.lpm-facts { margin-top:10px; display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; font-size:13.5px; color:var(--lp-soft); }
.lpm-facts b { color:var(--lp-ink); font-weight:700; }
.lpm-conds { display:grid; gap:14px; padding:14px 20px 18px; border-top:1px dashed var(--lp-line); }
.lpm-cond h4 { display:flex; align-items:center; gap:6px; font-size:13.5px; font-weight:700; margin:0 0 7px; }
.lpm-cond ul { list-style:none; margin:0; padding:0; display:grid; gap:6px; }
.lpm-cond li { display:flex; gap:8px; align-items:flex-start; font-size:13.5px; }
.lpm-cond li svg { flex:none; margin-top:2px; }
.lpm-cond-ok h4, .lpm-cond-ok li svg { color:#1E7F4F; }
.lpm-cond-check h4, .lpm-cond-check li svg { color:#B8860B; }

/* Announce bar */
.lp-announce { background:linear-gradient(90deg,#16557A,#1C6E96); color:#fff; }
.lp-announce-inner { max-width:1140px; margin:0 auto; padding:9px 24px; display:flex;
  align-items:center; gap:14px; justify-content:center; flex-wrap:wrap; font-size:14px; }
.lp-announce-badge { display:inline-flex; align-items:center; gap:5px; background:rgba(255,255,255,.16);
  padding:3px 9px; border-radius:999px; font-weight:600; font-size:12px; }
/* The bar inherits Sora from the .lp block above, which was written for
   Bidvane and carries no Hebrew glyphs — so on the IL page every word here was
   silently falling back. Give the Hebrew bar the body face, and let the lead
   claim carry the weight while the qualifiers stay secondary. */
body:not(.mkt-uk) .lp-announce { font-family:var(--font-body); }
/* Same story for the rest of the page: .lp h1/h2/h3 and the small labels all
   inherit Sora from the block above. Headings take the site's Hebrew display
   face — the one every other h1/h2/h3 uses, and the one the price card's
   "חינם" now uses, so the landing reads as one page.
   Secular One ships a single weight: keeping font-weight:700 would make the
   browser synthesise a fake bold, so the weight is reset with the family.
   letter-spacing goes too — negative tracking is a Latin display trick that
   just crowds Hebrew letterforms. */
body:not(.mkt-uk) .lp h1, body:not(.mkt-uk) .lp h2, body:not(.mkt-uk) .lp h3 {
  font-family:var(--font-display); font-weight:400; letter-spacing:normal; }
/* The eyebrow and kicker are small UI labels, not headlines: they want a real
   600/700, which the body face has and the display face does not. */
body:not(.mkt-uk) .lp .lp-eyebrow, body:not(.mkt-uk) .lp .lp-kicker {
  font-family:var(--font-body); }
/* The two section headings that set Sora directly rather than inheriting it,
   and that carry Hebrew on the IL landing / about / calendar pages. Both are
   already font-weight:400, so the display face drops straight in.
   Left in Sora on purpose: .lp-stat-num and .lp-seal-mini render digits, which
   Sora has and sets well — swapping those would lose the tabular look for no
   gain, since there is no Hebrew in them to fall back. */
body:not(.mkt-uk) .lps-head h3, body:not(.mkt-uk) .lpt-head h3 {
  font-family:var(--font-display); }
.lp-announce-msg { font-weight:700; }
body:not(.mkt-uk) .lp-announce-msg { font-weight:800; letter-spacing:-.01em; }
.lp-announce-sub { opacity:.9; font-weight:400; }
.lp-announce-cta { color:#fff; font-weight:500; display:inline-flex; align-items:center; gap:4px; }
.lp-announce-cta:hover { text-decoration:underline; }
@media (max-width:680px){ .lp-announce-sub{display:none;} }

/* Type */
.lp-eyebrow { display:inline-flex; align-items:center; gap:7px; font-size:13px;
  font-weight:600; color:var(--lp-accent); background:var(--accent-wash); padding:6px 12px;
  border-radius:999px; margin-bottom:18px; }
/* Section kicker: quiet editorial eyebrow (dash + small label), both markets —
   the pill-badge look retired everywhere; UK adds uppercase/letter-spacing
   (Latin-only niceties) via its .mkt-uk override below. */
.lp-kicker { display:inline-flex; align-items:center; gap:10px; font-size:12px;
  font-weight:700; color:var(--lp-seal); margin-bottom:14px; white-space:nowrap; }
.lp-kicker::before { content:""; flex:none; width:26px; height:2px; border-radius:2px;
  background:var(--lp-seal); opacity:.45; }
.lp-h1 { font-size:clamp(34px,5vw,58px); line-height:1.05; font-weight:700; letter-spacing:-.02em;
  color:var(--lp-ink); margin:0 0 18px; }
.lp-mark { color:var(--lp-accent); white-space:nowrap; }
.lp-h2 { font-size:clamp(26px,3.4vw,40px); line-height:1.12; font-weight:700; letter-spacing:-.02em;
  color:var(--lp-ink); margin:0 0 14px; }
.lp-lead { font-size:clamp(16px,1.6vw,19px); line-height:1.6; color:var(--lp-soft); max-width:560px;
  margin:0 0 28px; }
.lp-sub { font-size:17px; line-height:1.6; color:var(--lp-soft); max-width:620px; margin:0; }
.lp-section { padding:84px 0; }
.lp-head { text-align:center; max-width:720px; margin:0 auto 52px; }
.lp-head-left { text-align:left; }

/* CTA + trust */
.lp-cta-row { display:flex; gap:12px; flex-wrap:wrap; }
/* Hero CTA pair, one notch (~10%) smaller than the stock btn-lg. */
.lp-hero .lp-cta-row .btn-lg { padding: 13px 22px; font-size: 16px; }
.lp-btn-ghost { background:#fff; border:1px solid var(--lp-line); color:var(--lp-ink); }
.lp-btn-ghost:hover { border-color:var(--lp-seal); text-decoration:none; }
.lp-trustline { list-style:none; display:flex; flex-wrap:wrap; gap:16px; padding:0; margin:26px 0 0;
  font-size:14px; color:var(--lp-soft); }
.lp-trustline li { display:inline-flex; align-items:center; gap:6px; }
.lp-trustline svg { color:var(--ok); }

/* Hero */
.lp-hero { position:relative; overflow:hidden; padding:64px 0 88px;
  background:linear-gradient(180deg,#FFFDFA,var(--lp-paper)); }
.lp-hero-grid { position:absolute; inset:0; pointer-events:none; opacity:.5;
  background-image:linear-gradient(var(--lp-line) 1px,transparent 1px),
    linear-gradient(90deg,var(--lp-line) 1px,transparent 1px); background-size:34px 34px;
  -webkit-mask-image:radial-gradient(120% 70% at 70% 10%,#000,transparent 70%);
  mask-image:radial-gradient(120% 70% at 70% 10%,#000,transparent 70%); }
.lp-hero-glow { position:absolute; top:-160px; right:-120px; width:640px; height:640px;
  pointer-events:none; border-radius:50%;
  background:radial-gradient(circle,rgba(232,101,13,.14),transparent 62%); }
.lp-hero-inner { position:relative; display:grid; grid-template-columns:1.05fr 1fr; gap:56px;
  align-items:center; }
.lp-hero-copy { min-width:0; }
.lp-hero-visual { position:relative; }
.lp-window { background:#fff; border:1px solid var(--lp-line); border-radius:14px;
  box-shadow:0 30px 60px -20px rgba(28,43,51,.28),0 8px 24px rgba(28,43,51,.08); overflow:hidden;
  transform:perspective(1400px) rotateY(-4deg) rotateX(1.5deg); transition:transform .4s ease; }
.lp-window:hover { transform:perspective(1400px) rotateY(0) rotateX(0); }
.lp-window-bar { display:flex; align-items:center; gap:7px; padding:11px 14px; background:#F4F4EF;
  border-bottom:1px solid var(--lp-line); }
.lp-dot { width:10px; height:10px; border-radius:50%; background:#D6D6CE; }
.lp-dot:nth-child(1){background:#E8650D;} .lp-dot:nth-child(2){background:#F59E2B;} .lp-dot:nth-child(3){background:#1E7F4F;}
.lp-window-url { margin-left:10px; font-size:12px; color:var(--lp-soft); background:#fff;
  border:1px solid var(--lp-line); border-radius:6px; padding:3px 10px; flex:1; text-align:center; }
.lp-window-body { padding:18px; background:var(--lp-paper); }
.lp-window-body .fitcard { margin:0; }
.lp-float { position:absolute; display:flex; align-items:center; gap:9px; background:#fff;
  border:1px solid var(--lp-line); border-radius:12px; padding:10px 13px;
  box-shadow:0 12px 28px rgba(28,43,51,.16); font-size:13px; }
.lp-float b { display:block; line-height:1.1; color:var(--lp-ink); font-weight:700; }
.lp-float small { color:var(--lp-soft); font-size:11px; }
.lp-float-ic { width:30px; height:30px; border-radius:8px; display:grid; place-items:center;
  background:var(--accent-wash); color:var(--lp-accent); flex:none; }
.lp-float-score { top:14px; left:-26px; animation:lp-bob 5s ease-in-out infinite; }
.lp-float-digest { bottom:24px; right:-22px; animation:lp-bob 6s ease-in-out infinite .6s; }
.lp-float-digest .lp-float-ic { background:var(--seal-wash); color:var(--lp-seal); }
@keyframes lp-bob { 0%,100%{transform:translateY(0);} 50%{transform:translateY(-8px);} }

/* Sources */
.lp-sources { padding:30px 0; border-top:1px solid var(--lp-line); border-bottom:1px solid var(--lp-line);
  background:#fff; }
.lp-sources-label { text-align:center; font-size:13px; color:var(--lp-soft); text-transform:uppercase;
  letter-spacing:.06em; margin:0 0 16px; }
.lp-source-row { display:flex; flex-wrap:wrap; gap:12px 28px; justify-content:center; }
.lp-source { display:inline-flex; align-items:center; gap:8px; font-weight:600; color:var(--lp-ink);
  font-size:15px; }
.lp-source svg { color:var(--lp-seal); }

/* Stats */
.lp-stats { padding:54px 0; }
.lp-stats-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:20px; }
.lp-stat { text-align:center; background:#fff; border:1px solid var(--lp-line); border-radius:14px;
  padding:28px 18px; box-shadow:var(--shadow-card); }
.lp-stat-num { display:block; font-family:"Sora",sans-serif; font-weight:700;
  font-size:clamp(32px,4vw,46px); color:var(--lp-seal); line-height:1; letter-spacing:-.02em; }
.lp-stat-label { display:block; margin-top:8px; color:var(--lp-soft); font-size:14px; }

/* Steps */
.lp-steps { display:flex; align-items:stretch; gap:18px; justify-content:center; }
.lp-step { flex:1; max-width:320px; background:#fff; border:1px solid var(--lp-line); border-radius:16px;
  padding:28px 24px; position:relative; box-shadow:var(--shadow-card); }
.lp-step-n { position:absolute; top:-14px; left:24px; width:28px; height:28px; border-radius:50%;
  background:var(--lp-seal); color:#fff; font-weight:700; font-size:14px; display:grid; place-items:center; }
.lp-step-ic { width:48px; height:48px; border-radius:12px; display:grid; place-items:center;
  background:var(--accent-wash); color:var(--lp-accent); margin:8px 0 14px; }
.lp-step h3 { font-size:19px; margin:0 0 8px; }
.lp-step p { color:var(--lp-soft); margin:0; font-size:15px; }
.lp-step-line { display:flex; align-items:center; color:var(--lp-line); flex:none; }
@media (max-width:860px){ .lp-steps{flex-direction:column; align-items:stretch;} .lp-step{max-width:none;}
  .lp-step-line{justify-content:center; transform:rotate(90deg);} }

/* Features */
/* minmax(0,1fr), not 1fr: a 1fr track's automatic minimum is its content's
   MIN-CONTENT size, so one long unbreakable run inside the column pushes the
   track wider than the grid and the whole page scrolls sideways. It did — by
   27px on a 378px screen. minmax(0,…) lets the track shrink and the text
   wrap, which is what it should have been doing. */
.lp-feature-grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:56px; align-items:center; }
.lp-checks { list-style:none; padding:0; margin:22px 0 0; display:grid; gap:12px; }
.lp-checks li { display:flex; align-items:flex-start; gap:10px; font-size:16px; color:var(--lp-ink); }
.lp-checks svg { color:var(--ok); flex:none; margin-top:3px; }
.lp-mock { background:#fff; border:1px solid var(--lp-line); border-radius:16px;
  box-shadow:0 20px 50px -22px rgba(28,43,51,.26); padding:16px; }
.lp-mock-matches { display:grid; gap:10px; }
.lp-mock-row { display:flex; align-items:center; gap:12px; padding:12px; border:1px solid var(--lp-line);
  border-radius:12px; background:var(--lp-paper); }
.lp-mock-row.is-plan { border-style:dashed; }
.lp-seal-mini { width:38px; height:38px; border-radius:50%; flex:none; display:grid; place-items:center;
  font-weight:700; font-size:14px; color:#fff; font-family:"Sora",sans-serif; }
.lp-seal-mini.good{background:var(--ok);} .lp-seal-mini.mid{background:var(--check);} .lp-seal-mini.plan{background:var(--lp-seal);}
.lp-mock-main { flex:1; min-width:0; }
.lp-mock-main b { display:block; font-size:14px; color:var(--lp-ink); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; }
.lp-mock-main small { color:var(--lp-soft); font-size:12px; }
.lp-pill { display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600; padding:4px 9px;
  border-radius:999px; flex:none; }
.lp-pill.ok{background:var(--ok-wash); color:var(--ok);} .lp-pill.warn{background:var(--check-wash); color:var(--check);}
.lp-pill.plan{background:var(--seal-wash); color:var(--lp-seal);}
.lp-mock-elig { display:grid; gap:12px; }
.lp-elig-head { display:flex; align-items:center; gap:8px; font-weight:700; color:var(--lp-ink); font-size:15px; }
.lp-elig-group { border-left:3px solid; border-radius:10px; padding:12px 14px; }
.lp-elig-group.ok { border-color:var(--ok); background:var(--ok-wash); }
.lp-elig-group.warn { border-color:var(--check); background:var(--check-wash); }
.lp-elig-label { display:inline-flex; align-items:center; gap:5px; font-weight:600; font-size:12px;
  text-transform:uppercase; letter-spacing:.04em; margin-bottom:6px; }
.lp-elig-group.ok .lp-elig-label{color:var(--ok);} .lp-elig-group.warn .lp-elig-label{color:var(--check);}
.lp-elig-group p { margin:0; font-size:14px; color:var(--lp-ink); }
.lp-elig-group p + p { margin-top:4px; }
.lp-mock-board { display:grid; grid-template-columns:repeat(3,1fr); gap:10px; }
.lp-col { background:var(--lp-paper); border:1px solid var(--lp-line); border-radius:12px; padding:10px; }
.lp-col-h { display:flex; justify-content:space-between; font-size:12px; font-weight:600; color:var(--lp-soft);
  margin-bottom:8px; }
.lp-col-h em { font-style:normal; background:#fff; border:1px solid var(--lp-line); border-radius:6px; padding:0 6px; }
.lp-kcard { background:#fff; border:1px solid var(--lp-line); border-radius:8px; padding:9px 10px;
  font-size:12.5px; color:var(--lp-ink); margin-bottom:8px; box-shadow:var(--shadow); border-left:3px solid var(--lp-line); }
.lp-kcard.accent{border-left-color:var(--lp-accent);} .lp-kcard.ok{border-left-color:var(--ok);}

/* Bento */
.lp-bento { display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
.lp-tile { background:#fff; border:1px solid var(--lp-line); border-radius:16px; padding:26px 24px;
  box-shadow:var(--shadow-card); transition:transform .2s,box-shadow .2s; }
.lp-tile:hover { transform:translateY(-3px); box-shadow:0 16px 32px -16px rgba(28,43,51,.24); }
.lp-tile-ic { width:46px; height:46px; border-radius:12px; display:grid; place-items:center;
  background:var(--accent-wash); color:var(--lp-accent); margin-bottom:16px; }
.lp-tile h3 { font-size:18px; margin:0 0 6px; }
.lp-tile p { color:var(--lp-soft); margin:0; font-size:14.5px; }
.lp-tile code { background:var(--lp-paper); border:1px solid var(--lp-line); border-radius:5px; padding:1px 5px; font-size:12px; }

/* Compare */
.lp-compare-sec { background:#fff; border-top:1px solid var(--lp-line); border-bottom:1px solid var(--lp-line); }
.lp-compare { display:grid; grid-template-columns:1fr 1fr; gap:22px; max-width:880px; margin:0 auto; align-items:start; }
.lp-compare-col { border:1px solid var(--lp-line); border-radius:16px; padding:26px; }
.lp-compare-col.old { background:var(--lp-paper); }
.lp-compare-col.new { background:linear-gradient(180deg,#fff,#FFF7F0);
  border-color:color-mix(in srgb,var(--lp-accent) 30%,var(--lp-line));
  box-shadow:0 18px 40px -22px rgba(232,101,13,.35); }
.lp-compare-col h3 { font-size:18px; margin:0 0 16px; display:flex; align-items:center; gap:7px; }
.lp-compare-col.new h3 { color:var(--lp-accent); }
.lp-compare-col ul { list-style:none; padding:0; margin:0; display:grid; gap:12px; }
.lp-compare-col li { display:flex; align-items:flex-start; gap:10px; font-size:15px; }
.lp-compare-col.old svg { color:var(--bad); flex:none; margin-top:2px; }
.lp-compare-col.new svg { color:var(--ok); flex:none; margin-top:2px; }

/* Pricing */
.lp-pricing { background:linear-gradient(180deg,var(--lp-paper),#FFFDFA); }
.lp-price-wrap { max-width:760px; margin:0 auto; }
.lp-price-card { position:relative; background:#fff; border-radius:22px; padding:38px;
  border:1px solid var(--lp-line); box-shadow:0 40px 80px -30px rgba(28,43,51,.3); }
.lp-price-card::before { content:""; position:absolute; inset:-1px; border-radius:22px; padding:1.5px;
  background:linear-gradient(135deg,var(--lp-accent),var(--lp-accent2),var(--lp-seal));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0); -webkit-mask-composite:xor;
  mask-composite:exclude; pointer-events:none; }
.lp-price-ribbon { position:absolute; top:-14px; left:50%; transform:translateX(-50%); background:var(--lp-accent);
  color:#fff; font-weight:700; font-size:13px; padding:6px 16px; border-radius:999px; display:inline-flex;
  align-items:center; gap:6px; box-shadow:0 8px 18px -6px rgba(232,101,13,.6); white-space:nowrap; }
.lp-price-top { display:flex; justify-content:space-between; align-items:flex-end; gap:16px; margin-top:8px; flex-wrap:wrap; }
/* Sora + uppercase + tracking is a Latin small-caps treatment: Sora ships no
   Hebrew glyphs (so the text silently falls back), uppercase is a no-op in
   Hebrew, and letter-spacing pulls the word apart. Keep it for Bidvane, give
   the Hebrew card the body face at a normal rhythm. */
.lp-price-name { font-family:var(--font-body); font-weight:700; color:var(--lp-soft);
  font-size:15px; letter-spacing:normal; }
.mkt-uk .lp-price-name { font-family:"Sora",sans-serif; font-weight:600;
  text-transform:uppercase; letter-spacing:.05em; }
.lp-price-amount { font-family:"Sora",sans-serif; font-weight:800; font-size:54px; color:var(--lp-ink);
  line-height:1; letter-spacing:-.03em; }
.lp-price-period { font-size:16px; font-weight:500; color:var(--lp-soft); letter-spacing:0; }
.lp-price-period small { font-size:13px; }
/* "חינם" sits where the number used to. It is the headline claim on the page,
   so it gets the accent colour rather than the muted ink a price carried.
   The family has to be overridden: .lp-price-amount is set in Sora, which
   carries no Hebrew glyphs — fine for "₪149" (digits render) but a Hebrew word
   falls back to whatever the system picks, which is why it looked wrong next
   to the rest of the card. Use the display face the Hebrew headings use. */
.lp-price-free { color:var(--seal, var(--lp-ink)); font-family:var(--font-display);
  font-weight:400; letter-spacing:normal; }
/* The qualifier rides under it, not inline — "חינם לתקופה מוגבלת" on one line
   would read as a single hedged phrase and bury the word that matters. */
.lp-price-amount:has(.lp-price-free) { display:flex; flex-direction:column; gap:2px; }
.lp-price-amount:has(.lp-price-free) .lp-price-period { font-size:15px; }
/* המחיר העתידי, מתחת לכותרת "חינם". שורה אחת, שקטה — הנקודה היא שיש תשובה
   למספר, לא שהוא מתחרה במילה "חינם". רק ₪149 המחוק ו־₪74 החי נושאים הדגשה. */
.lp-price-later { margin:4px 0 0; font-size:14px; color:var(--lp-soft);
  display:flex; align-items:baseline; gap:5px; flex-wrap:wrap; }
.lp-price-later s { text-decoration-thickness:1.5px; opacity:.75; }
.lp-price-later b { font-size:17px; color:var(--lp-ink); font-weight:700; }
.lp-price-seats { display:inline-flex; align-items:center; gap:7px; background:var(--seal-wash);
  color:var(--lp-seal); font-size:14px; padding:8px 14px; border-radius:999px; }
.lp-price-note { color:var(--lp-soft); font-size:14px; margin:14px 0 24px; }
.lp-price-fineprint { margin-top:8px; font-size:12px; line-height:1.5; color:var(--lp-soft); opacity:.9; }
.lp-price-cols { display:grid; grid-template-columns:repeat(3,1fr); gap:22px; padding:24px 0;
  border-top:1px solid var(--lp-line); border-bottom:1px solid var(--lp-line); margin-bottom:26px; }
.lp-price-gh { font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.06em;
  color:var(--lp-accent); display:block; margin-bottom:12px; }
.lp-price-list { list-style:none; padding:0; margin:0; display:grid; gap:10px; }
.lp-price-list li { display:flex; align-items:flex-start; gap:8px; font-size:14px; color:var(--lp-ink); line-height:1.4; }
.lp-price-list svg { color:var(--ok); flex:none; margin-top:2px; }
.lp-price-act { text-align:center; }
.lp-price-reassure { display:flex; flex-wrap:wrap; gap:8px 18px; justify-content:center; margin-top:18px;
  font-size:13px; color:var(--lp-soft); }
.lp-price-reassure span { display:inline-flex; align-items:center; gap:6px; }
.lp-price-reassure svg { color:var(--lp-seal); }

/* FAQ */
.lp-faq-inner { display:grid; grid-template-columns:300px 1fr; gap:48px; align-items:start; }
.lp-faq-list { display:grid; gap:12px; }
.lp-q { background:#fff; border:1px solid var(--lp-line); border-radius:12px; padding:0 18px; }
.lp-q summary { list-style:none; cursor:pointer; display:flex; justify-content:space-between; align-items:center;
  gap:12px; padding:18px 0; font-weight:600; color:var(--lp-ink); font-size:16px; }
.lp-q summary::-webkit-details-marker { display:none; }
.lp-q-ic { color:var(--lp-soft); transition:transform .2s; flex:none; }
.lp-q[open] .lp-q-ic { transform:rotate(180deg); }
.lp-q p { color:var(--lp-soft); margin:0; padding:0 0 18px; font-size:15px; line-height:1.6; max-width:640px; }
@media (max-width:820px){ .lp-faq-inner{grid-template-columns:1fr; gap:24px;} .lp-head-left{text-align:center;} }

/* Final CTA */
.lp-cta { background:linear-gradient(135deg,#16557A,#1C2B33); color:#fff; padding:80px 0; }
.lp-cta-inner { text-align:center; max-width:680px; margin:0 auto; }
.lp-cta .lp-h2 { color:#fff; }
.lp-cta .lp-sub { color:rgba(255,255,255,.8); margin:0 auto 28px; }
.lp-cta-btn { background:var(--lp-accent); color:#fff; border:none; box-shadow:0 14px 30px -10px rgba(232,101,13,.7); }
.lp-cta-btn:hover { background:var(--accent-ink); text-decoration:none; }
.lp-cta-fine { margin-top:18px; font-size:13px; color:rgba(255,255,255,.7); }
/* Final CTA — "market lights up" radar dot-field band (ported from the UK
   landing). Light paper backdrop; the seal/orange dot field + illumination
   wave live behind the CTA copy. IL landing only (the .lp-cta-radar modifier). */
.lp2-radar-band { position:relative; overflow:hidden; }
.lp2-radar { position:absolute; inset:0; z-index:0; }
.lp2-radar-canvas, .lp2-radar-svg { position:absolute; inset:0; width:100%; height:100%; }
.lp2-radar-canvas { display:none; }
.lp-cta-radar { background:var(--paper); color:var(--lp-ink); }
.lp-cta-radar .lp-cta-inner { position:relative; z-index:1; }
.lp-cta-radar .lp-h2 { color:var(--lp-ink); }
.lp-cta-radar .lp-sub { color:var(--lp-soft); }
.lp-cta-radar .lp-cta-fine { color:var(--lp-soft); }
/* Compact authority-lookup teaser (relocated below pricing, before FAQ) */
.lp-lookup-compact { padding-top: var(--s6); padding-bottom: var(--s6); }
.lp-lookup-compact .lp-lookup-card { padding: var(--s5); }
.lp-lookup-compact .lp-head { margin-bottom: 0; }
.lp-lookup-compact .lp-head h2 { font-size: var(--t-lg); margin-bottom: var(--s2); }
.lp-lookup-compact .lp-head p { margin: 0; }
.lp-lookup-compact .lp-lookup-form { margin-top: var(--s3); }
.lp-lookup-compact .lp-auth-chips { margin-top: var(--s3); }
/* The way through to the public search, under the authority chips. A sentence
   rather than a fourth button: the card already has a primary action, and a
   second one of equal weight would just split the click. */
/* The free search in the hero. Sits under the two CTAs and stays a step
   quieter than either: a bordered field and a neutral button, not a third
   thing shouting. It is still a real box, because a box invites a query where
   a link only announces that one exists. */
.lp-hero-search { display: flex; gap: var(--s2); margin: var(--s5) 0 0;
  max-width: 480px; }
.lp-hero-search input { flex: 1; min-width: 0; font: inherit; font-size: var(--t-sm);
  padding: 11px 14px; border-radius: var(--r-control); border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); }
.lp-hero-search input::placeholder { color: var(--ink-soft); opacity: .8; }
.lp-hero-search input:focus { outline: 0; border-color: var(--seal);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--seal) 13%, transparent); }
.lp-hero-search .btn { flex: none; }
.lp-hero-search-note { margin: var(--s2) 0 0; font-size: var(--t-xs);
  color: var(--ink-soft); }
@media (max-width: 560px) {
  .lp-hero-search { flex-wrap: wrap; }
  .lp-hero-search .btn { width: 100%; }
}

.lp-lookup-search { margin: var(--s4) 0 0; text-align: center; font-size: var(--t-sm);
  color: var(--ink-soft); }
.lp-lookup-search a { color: var(--seal); font-weight: 500; text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--seal) 35%, transparent); }
.lp-lookup-search a:hover { border-bottom-color: currentColor; }

/* Responsive */
@media (max-width:920px){
  .lp-hero-inner,.lp-feature-grid{grid-template-columns:minmax(0,1fr); gap:40px;}
  .lp-hero-visual{max-width:520px; margin:0 auto;}
  .lp-window{transform:none;}
  .lp-float-score{left:0;} .lp-float-digest{right:0;}
  .lp-bento,.lp-price-cols{grid-template-columns:1fr 1fr;}
}
@media (max-width:620px){
  .lp-section{padding:60px 0;}
  .lp-stats-grid,.lp-bento,.lp-price-cols,.lp-compare,.lp-mock-board{grid-template-columns:1fr;}
  .lp-price-card{padding:26px 20px;}
  .lp-float{display:none;}
  .lp-hero{padding:40px 0 60px;}
}

/* ════════════════════════════════════════════════════════════════════════
   RTL + Hebrew adaptation of the `.lp` landing (IL / מכרזיה reuses the same
   marketing layout). Every rule is scoped to `[dir="rtl"]`, so the UK (dir=ltr)
   page is byte-identical — this block only fixes physical-direction props and
   swaps the display font (Sora isn't loaded on IL) for the Hebrew display face.
   ════════════════════════════════════════════════════════════════════════ */
[dir="rtl"] .lp h1, [dir="rtl"] .lp h2, [dir="rtl"] .lp h3,
[dir="rtl"] .lp-announce { font-family: var(--font-display); }
[dir="rtl"] .lp-h1, [dir="rtl"] .lp-h2 { letter-spacing: normal; }
/* Decorative hero glow → mirror to the start (right in RTL) side. */
[dir="rtl"] .lp-hero-glow { right:auto; left:-120px; }
/* Browser-window URL chip spacing (logical). */
[dir="rtl"] .lp-window-url { margin-left:0; margin-right:10px; }
/* Step number badge sits on the reading-start corner. */
[dir="rtl"] .lp-step-n { left:auto; right:24px; }
/* Banded-step (lps) number disc sits on the reading-start (right) corner too. */
[dir="rtl"] .lps-num { left:auto; right:16px; }
/* Section kicker: Hebrew has no uppercase to borrow prominence from (UK relies
   on it), so size the RTL eyebrow up a touch to read as strong as the UK one. */
[dir="rtl"] .lp-kicker { font-size:13.5px; }
/* Connector arrows between steps point along the RTL reading flow. */
[dir="rtl"] .lp-step-line svg { transform:scaleX(-1); }
/* Accent rule on the reading-start edge of eligibility groups / kanban cards. */
[dir="rtl"] .lp-elig-group { border-left:0; border-right:3px solid; }
[dir="rtl"] .lp-kcard { border-left:0; border-right:3px solid var(--lp-line); }
[dir="rtl"] .lp-kcard.accent { border-right-color:var(--lp-accent); }
[dir="rtl"] .lp-kcard.ok { border-right-color:var(--ok); }
/* FAQ heading aligns to the start (right) in RTL. */
[dir="rtl"] .lp-head-left { text-align:right; }

/* ════════════════════════════════════════════════════════════════════════
   UK public pages (auth + legal) — same look & feel as the Bidvane landing.
   Scoped to `.mkt-uk` (UK market body class) + page-specific component classes
   (.auth-card / .legal-doc), so the IL site and the UK *app* pages are
   untouched (those component classes never appear there). Blogs are excluded
   (they use .blog-article without .legal-doc).
   ════════════════════════════════════════════════════════════════════════ */
.mkt-uk .auth-card h1,
.mkt-uk .legal-doc > h1,
.mkt-uk .legal-doc .blog-body h2,
.mkt-uk .legal-doc .blog-body h3 { font-family:"Sora", system-ui, sans-serif; letter-spacing:-.01em; }

/* ── Auth pages: login / signup / forgot / reset / verify ───────────────── */
.mkt-uk .auth-wrap { position:relative; isolation:isolate; }
.mkt-uk .auth-wrap::before { content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:34px 34px; opacity:.5;
  -webkit-mask-image:radial-gradient(110% 60% at 50% 0%,#000,transparent 72%);
  mask-image:radial-gradient(110% 60% at 50% 0%,#000,transparent 72%); }
.mkt-uk .auth-wrap::after { content:""; position:absolute; top:-120px; left:50%; transform:translateX(-50%);
  width:560px; height:420px; z-index:-1; pointer-events:none; border-radius:50%;
  background:radial-gradient(circle,rgba(232,101,13,.13),transparent 62%); }
.mkt-uk .auth-card { max-width:420px; border:1px solid var(--line); border-radius:18px; overflow:hidden;
  position:relative; box-shadow:0 30px 70px -34px rgba(28,43,51,.4), 0 4px 12px rgba(28,43,51,.05); }
.mkt-uk .auth-card::before { content:""; position:absolute; top:0; left:0; right:0; height:3px;
  background:linear-gradient(90deg,var(--accent),var(--accent-ink)); }
.mkt-uk .auth-card h1 { font-size:26px; }

/* ── Legal / policy pages: privacy / terms / cookies / security / refunds /
      about / accessibility (all use .blog-article.legal-doc) ─────────────── */
.mkt-uk .legal-doc > h1 { font-size:clamp(30px,4vw,42px); line-height:1.1; letter-spacing:-.02em; }
.mkt-uk .legal-doc .blog-article-meta { display:inline-block; background:var(--seal-wash); color:var(--seal);
  font-size:13px; padding:4px 11px; border-radius:999px; margin-bottom:var(--s5); }
.mkt-uk .legal-doc .blog-body { font-size:16px; line-height:1.8; }
.mkt-uk .legal-doc .blog-body h2 { font-size:22px; margin-top:var(--s6); padding-top:var(--s4);
  border-top:1px solid var(--line); }
.mkt-uk .legal-doc .blog-body h2:first-of-type { border-top:0; padding-top:0; margin-top:var(--s5); }
.mkt-uk .legal-doc .blog-body h3 { font-size:17px; margin-top:var(--s4); margin-bottom:var(--s1); }
.mkt-uk .legal-doc .blog-body ul { padding-left:1.1em; }
.mkt-uk .legal-doc .blog-body li { margin-bottom:6px; }
.mkt-uk .crumbs a { font-weight:600; }
.mkt-uk .legal-doc .legal-table { width:100%; border-collapse:collapse; margin:var(--s4) 0; font-size:14px; }
.mkt-uk .legal-doc .legal-table th, .mkt-uk .legal-doc .legal-table td { border:1px solid var(--line);
  padding:9px 12px; text-align:left; vertical-align:top; }
.mkt-uk .legal-doc .legal-table th { background:var(--paper); font-weight:650; }
.mkt-uk .legal-doc .blog-back a { font-weight:600; }

/* ── Awards & Buyers intelligence (UK, Preview) ────────────────────────────── */
/* "Bidvane Edge" — the capability brand for the market-intelligence layer.
   Lockup heads /market; the badge marks every Edge-powered surface. */
.edge-lockup { display: inline-flex; align-items: center; gap: 7px; }
.edge-lockup .edge-star { color: var(--accent); }
.edge-word { color: var(--accent); }
.edge-badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px;
  border-radius: 999px; font-size: 11px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; background: var(--accent-fill); color: var(--on-accent);
  font-family: var(--font-body); vertical-align: 4px; }
.edge-badge-sm { padding: 1px 7px; font-size: 10px; vertical-align: 1px;
  background: var(--accent-wash); color: var(--accent-ink);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); }
.pv-pill { display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px;
  border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; background: var(--seal-wash); color: var(--seal);
  border: 1px solid color-mix(in srgb, var(--seal) 25%, transparent); }
/* Header — compact, name + chips left, Edge pill right */
.bp-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); }
.bp-head h1 { display: flex; align-items: center; gap: var(--s2); }
.bp-headrow { display: flex; align-items: center; gap: var(--s2); margin-top: 6px; flex-wrap: wrap; }
.bp-type { text-transform: capitalize; }
.bp-alt { color: var(--ink-soft); }
.bp-edgepill { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 3px 10px; border-radius: 999px; font-size: var(--t-xs);
  background: var(--accent-wash); color: var(--accent-ink); }
.bp-edgepill svg { color: var(--accent); }
.bp-coverage { font-size: var(--t-sm); margin: 0 0 var(--s4); }
.bp-coverage svg { vertical-align: -2px; margin-right: 4px; }
/* KPI tiles — Live-now tile is the accent, actionable one */
.bp-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s3); margin: 0 0 var(--s4); }
.bp-tile { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: var(--s3) var(--s4); display: flex; flex-direction: column; gap: 2px; }
.bp-tile b { font-size: 1.5rem; line-height: 1.1; color: var(--ink);
  min-width: 0; overflow-wrap: anywhere; }
.bp-tile span { color: var(--ink-soft); font-size: var(--t-sm); }
/* Trillion-scale sums are 17+ characters: scale with the viewport on small
   screens (and overflow-wrap above is the never-overflow last resort). */
.bp-tile-money b { color: var(--seal); font-size: clamp(1.1rem, 4.8vw, 1.5rem); }
.bp-tile-live { text-decoration: none; background: var(--accent-wash); border-color: var(--accent);
  transition: transform .12s ease; }
.bp-tile-live:hover { transform: translateY(-1px); }
.bp-tile-live b { color: var(--accent-ink); }
.bp-tile-live span { color: var(--accent-ink); display: inline-flex; align-items: center; gap: 4px; }

/* Verdict — the "how to proceed" line, first-class */
.bp-verdict { display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4); border-radius: var(--r-card); margin: 0 0 var(--s4);
  border: 1px solid var(--line); }
.bp-verdict p { margin: 0; font-size: var(--t-sm); color: var(--ink); }
.bp-verdict svg { flex: none; }
.bp-verdict-go { background: var(--accent-wash); border-color: var(--accent); }
.bp-verdict-go svg { color: var(--accent); }
.bp-verdict-go b { color: var(--accent-ink); }
.bp-verdict-watch { background: var(--seal-wash); border-color: var(--seal); }
.bp-verdict-watch svg { color: var(--seal); }

/* Sections */
.bp-sec { padding: var(--s4) var(--s5); margin: 0 0 var(--s4); }
.bp-sec h2 { display: flex; align-items: center; gap: 8px; font-size: 1.05rem; margin: 0 0 var(--s3); }
.bp-radar { border: 1px solid var(--accent); }           /* the radar is the hero card */
.bp-radar h2 svg { color: var(--accent); }
.bp-radar-n { font-weight: 400; margin-inline-start: 4px; }
.bp-radar-empty { margin: 0; }

/* Expiring-soon block, nested inside the radar (§6) */
.bp-expiring { margin-top: var(--s4); padding-top: var(--s3); border-top: 1px dashed var(--line); }
.bp-subh { display: flex; align-items: center; gap: 6px; font-size: .95rem; margin: 0 0 4px; }
.bp-subh svg { color: var(--check); }
.bp-expiring-intro { font-size: var(--t-sm); margin: 0 0 var(--s2); }

/* Likely-incumbent callout above the suppliers table */
.bp-incumbent { display: flex; align-items: flex-start; gap: 8px; margin: 0 0 var(--s3);
  padding: 10px 12px; border-radius: var(--r-control);
  background: var(--check-wash); color: var(--check); font-size: var(--t-sm); }
.bp-incumbent svg { flex: none; margin-top: 1px; }
.bp-incumbent b { color: var(--ink); }
.bp-incumbent a { color: var(--accent-ink); }

/* Context row — two charts side by side, collapses on narrow */
/* minmax(0, 1fr), not 1fr. A grid item defaults to min-width:auto, so a plain
   `1fr` column can never shrink below its content's min-content width — and the
   content here is an activity chart with ~190 columns and a category row with
   four. On a phone that floored the single column at 665px inside a 360px
   container, so the WHOLE page scrolled sideways and every panel in it looked
   broken. minmax(0, …) lets the column shrink and hands the overflow decision
   back to the panels, which each know how to handle their own. */
.bp-2col { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s4); align-items: start; }
.bp-2col > * { min-width: 0; }
.bp-2col .bp-sec { margin: 0; }
@media (max-width: 760px) { .bp-2col { grid-template-columns: minmax(0, 1fr); } }
/* "How this body works" — the notice-derived panel. It is the whole page for
   the 537 of 568 IL buyers that publish no winners, so it is styled as a
   first-class section rather than a fallback. */
.bp-notices .bp-2col { margin-top: var(--s4); }
.bp-half { min-width: 0; }
.bp-nsum { margin: 0 0 var(--s3); font-size: var(--t-sm); color: var(--ink); }
.bp-nsum b { color: var(--ink); }

/* The decision facts. Each states its denominator beside it — a percentage
   with nothing behind it is a decoration, and `pct` is None below the floor. */
.bp-nfacts { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s3); }
.bp-nfacts li { display: flex; flex-direction: column; gap: 2px; min-width: 0;
  padding: 10px 12px; border-radius: var(--r-control);
  background: var(--surface-2, var(--surface)); border: 1px solid var(--line); }
.bp-nfacts b { font-size: 1.25rem; line-height: 1.1; color: var(--ink);
  overflow-wrap: anywhere; }
.bp-nfacts span { font-size: var(--t-sm); color: var(--ink-soft); }
/* RTL breaks a parenthetical across lines and orphans the closing bracket,
   which reads as a typo rather than as a wrap. The denominator is short. */
.bp-nfacts small { white-space: nowrap; }

/* What they publish, as a share of their own record. The bar is scaled to the
   buyer's TOP category, not to the total: a body spread over eight fields
   would otherwise draw eight stubs and say nothing. */
.bp-ncats { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 6px; }
.bp-ncats li { display: grid; grid-template-columns: minmax(0, 9rem) 1fr auto;
  align-items: center; gap: 8px; font-size: var(--t-sm); }
.bp-ncat-label { color: var(--ink); text-decoration: none; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.bp-ncat-label:hover { color: var(--accent-ink); text-decoration: underline; }
.bp-ncat-bar { display: block; height: 8px; border-radius: 4px;
  background: var(--line); overflow: hidden; }
.bp-ncat-bar i { display: block; height: 100%; background: var(--accent);
  border-radius: 4px; }
.bp-nregions { margin: var(--s3) 0 0; font-size: var(--t-sm); }

/* Closing calendar. Empty months are drawn deliberately — a buyer that
   published nothing for half a year is the finding, and a chart built only
   from the months that HAVE a deadline hides it. */
.bp-nmonths { list-style: none; margin: 0; padding: 0; display: flex;
  align-items: flex-end; gap: 3px; height: 96px; overflow-x: auto; }
.bp-nmonths li { flex: 1 1 0; min-width: 14px; height: 100%;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 4px; }
.bp-nmonths i { display: block; background: var(--accent); border-radius: 2px 2px 0 0;
  min-height: 2px; }
.bp-nmonths li span { font-size: 10px; color: var(--ink-soft); text-align: center;
  font-variant-numeric: tabular-nums; }
.bp-nhint, .bp-nportals { margin: var(--s2) 0 0; font-size: var(--t-sm); }
.bp-nportals { margin-top: var(--s3); }

.bp-table td, .bp-table th { vertical-align: middle; }
.aw-table .aw-title { max-width: 420px; }
.ch-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 11px;
  color: var(--ink-soft); border: 1px dashed var(--line); border-radius: 999px;
  padding: 1px 8px; white-space: nowrap; }
.ch-badge.ch-ok { color: var(--ok); border-style: solid;
  border-color: color-mix(in srgb, var(--ok) 35%, transparent);
  background: color-mix(in srgb, var(--ok) 8%, transparent); }
/* month chart */
/* A TIME AXIS RUNS LEFT TO RIGHT, in Hebrew as much as in English. This is a
   flex row, so in an RTL page it laid the OLDEST bar on the right and read
   backwards against every other timeline a reader has ever seen. It belongs on
   the base rule and not on one variant: every .bp-chart on the site — the
   market dashboard, the buyer profile's "פעילות", the supplier's — is a series
   over time. The labels inside are numerals and short month names, which read
   correctly either way. */
.bp-chart { display: flex; align-items: flex-end; gap: 6px; height: 130px;
  padding: var(--s2) 0 0; direction: ltr; }
.bp-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; height: 100%; min-width: 0; }
.bp-bar { width: 100%; max-width: 34px; background: var(--seal); opacity: .8;
  border-radius: 4px 4px 0 0; min-height: 2px; transition: opacity .15s; }
.bp-col:hover .bp-bar { opacity: 1; }
.bp-mlabel { font-size: 10px; color: var(--ink-soft); line-height: 1.15;
  text-align: center; margin-top: 4px; }
.bp-chart-hint { font-size: var(--t-sm); margin: var(--s2) 0 0; }
/* cpv bars */
.bp-cpv { display: flex; flex-direction: column; gap: 8px; }
/* The label column used to floor at 180px. With the track's 2fr and the two
   content-sized columns beside it (a count and a figure as long as
   ₪17,856,524,254) that gave the whole row a hard ~665px minimum, so below
   roughly 640px "what they buy" stopped shrinking and pushed the page sideways.
   The label already ellipsizes, so it does not need a floor that large. */
.bp-cpvrow { display: grid; grid-template-columns: minmax(96px, 1.2fr) 2fr auto auto;
  align-items: center; gap: var(--s3); }
/* Narrower still, a four-column row cannot stay legible whatever the floor: the
   label takes its own line and the track, count and figure share the next. */
@media (max-width: 560px) {
  .bp-cpvrow { display: flex; flex-wrap: wrap; align-items: center; row-gap: 4px; }
  .bp-cpvrow .bp-cpvlabel { flex: 1 1 100%; }
  .bp-cpvrow .bp-cpvtrack { flex: 1 1 auto; min-width: 60px; }
  .bp-cpvrow .bp-cpvnum, .bp-cpvrow .bp-cpvspend { flex: 0 0 auto; }
}
.bp-cpvlabel { font-size: var(--t-sm); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.bp-cpvtrack { height: 10px; background: var(--seal-wash); border-radius: 999px;
  overflow: hidden; }
.bp-cpvfill { display: block; height: 100%; background: var(--seal); opacity: .85;
  border-radius: 999px; }
.bp-cpvnum { font-weight: 700; }
.bp-cpvspend { font-size: var(--t-sm); min-width: 90px; text-align: end; }
/* live tenders list */
.bp-live { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 8px; }
.bp-live li { display: flex; align-items: center; gap: var(--s3);
  justify-content: space-between; border-bottom: 1px dashed var(--line);
  padding-bottom: 8px; }
.bp-live li:last-child { border-bottom: 0; padding-bottom: 0; }
.bp-live-title { flex: 1; min-width: 0; }
/* footer */
.bp-foot { margin: var(--s5) 0 0; padding-top: var(--s3); border-top: 1px solid var(--line); }
.bp-foot .bp-coverage { margin: 0 0 var(--s2); }
.aw-pager { margin-top: var(--s3); display: flex; justify-content: center;
  align-items: center; gap: var(--s3); }
/* locked stub (dark until the entitlement flips) */
.bp-locked .bp-tile-locked { min-height: 72px; justify-content: center; filter: blur(1px); }
.bp-locked-note { display: flex; align-items: center; gap: var(--s3);
  justify-content: center; padding: var(--s5); color: var(--ink-soft); }
/* compact buyer-intel line on match cards */
/* compact buyer-intel strip — original card design, now inside the detail */
.fitcard-buyerintel { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 8px var(--s5) 0; padding: 8px 12px; border-radius: 10px;
  background: var(--seal-wash); font-size: var(--t-sm); color: var(--ink-soft); }
.fitcard-buyerintel b { color: var(--ink); }
.fitcard-buyerintel .dot { opacity: .5; }
/* in the facts sidebar the card-width side margins don't apply */
.t-detail-side .fitcard-buyerintel { margin: 12px 0 0; }
.awarded-chip { color: var(--ok); font-weight: 600; }
/* buyers browse */
.bb-search { display: flex; gap: var(--s3); margin: 0 0 var(--s3); max-width: 560px; }
.bb-search input { flex: 1; }
/* market intelligence */
/* Directory filter bar: a card with an aligned grid — the labeled search spans
   the full first row, then uniform filter columns, with Apply pinned at the end
   of the last row. Every control is a labeled .field so baselines line up. */
.dir-filters { display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s3) var(--s4); align-items: end; margin: 0 0 var(--s4);
  padding: var(--s4); background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-card); }
.dir-filters .field { margin: 0; min-width: 0; }
/* The label lines up with the control's TEXT, not its border. Form controls are
   padded `10px var(--s3)`, so a label flush to the box edge sits var(--s3)
   outside the value beneath it — the same token, not a copied number, so the two
   cannot drift apart. */
.dir-filters .field > span { display: block; margin-bottom: 4px;
  font-size: var(--t-sm); color: var(--ink-soft); }
/* The label lines up with the control's TEXT, not its border: form controls are
   padded `10px var(--s3)`, so a label flush to the box edge sits var(--s3)
   outside the value beneath it. Same token, not a copied number, so the two
   cannot drift apart.
   `:not(.df-search-box)` because the search input's wrapper is also a direct
   child span — padding it indents the input instead of its label. */
.dir-filters .field > span:not(.df-search-box) { padding-inline-start: var(--s3); }
.dir-filters .field input, .dir-filters .field select { width: 100%; display: block; }
.dir-filters .df-search { grid-column: 1 / -1; }
.dir-filters .df-apply { align-self: end; height: 44px; white-space: nowrap; }
/* Free-text search with an inline clear (✕), same pattern as all-tenders'
   .search-box: relative box, input padded so text clears the button. */
.dir-filters .df-search-box { position: relative; display: flex; align-items: center; width: 100%; }
.dir-filters .df-search-box input { padding-inline-end: 30px; }
.dir-filters .df-search-clear { top: 50%; transform: translateY(-50%); }
/* Wide screens: the whole bar on one line. The grid above gives the search its
   own full-width row, which is right when the selects would otherwise be 90px
   stumps — but past ~1100px it just spends 90 vertical pixels saying nothing.
   Flex, not more grid columns, because the search should take the slack while
   the selects share what is left.
   `flex-basis: 0` + `min-width: 0` on the selects is load-bearing: sized by
   content they take the width of their longest option (a full Hebrew category
   name), which pushes the row into a horizontal scroll. */
@media (min-width: 1100px) {
  .dir-filters { display: flex; flex-wrap: nowrap; gap: var(--s3); }
  .dir-filters .df-search { grid-column: auto; flex: 3 1 240px; min-width: 170px; }
  .dir-filters .field { flex: 1 1 0; min-width: 0; }
  /* A field that holds a two-digit number does not need a share of the slack. */
  .dir-filters .df-min { flex: 0 0 7em; }
  .dir-filters .df-apply { flex: 0 0 auto; }
}
/* Slim sub-tabs for the intelligence pages (Dashboard / Buyers / Suppliers):
   underline style, no chrome, one text-line tall. */
.subtabs { display: flex; gap: var(--s4); border-bottom: 1px solid var(--line);
  margin: 0 0 var(--s4); }
.subtabs a { padding: 4px 2px 8px; font-size: var(--t-sm); font-weight: 500;
  color: var(--ink-soft); text-decoration: none; margin-bottom: -1px;
  border-bottom: 2px solid transparent; transition: color .12s, border-color .12s; }
.subtabs a:hover { color: var(--ink); }
.subtabs a.is-active { color: var(--accent-ink); border-bottom-color: var(--accent);
  font-weight: 600; }
.subtabs a.subtab-radar { display: inline-flex; align-items: center; gap: 4.25px; }
.subtabs a.subtab-radar svg { opacity: .8; }
/* Under the tab bar: coverage note on the left, scope switch on the right,
   one compact row that wraps on narrow screens. */
.mk-scope { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3) var(--s4); flex-wrap: wrap; margin: 0 0 var(--s4); }
.mk-scope .bp-coverage { margin: 0; flex: 1 1 260px; }
/* Period bar: presets on one side, the custom From/To pair on the other. It
   wraps to two rows before either group breaks up, because a segmented control
   split across a line stops reading as one choice. */
.mk-period { display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--s2) var(--s4); margin: 0 0 var(--s4); }
.mk-period-lbl { display: inline-flex; align-items: center; gap: 5px;
  font-size: .82rem; font-weight: 600; color: var(--muted); }
.mk-period-lbl svg { opacity: .75; }
.mk-period .sort-seg { flex: 0 1 auto; }
.mk-period-range { display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--s2); margin-inline-start: auto; }
.mk-period-range label { display: inline-flex; align-items: center; gap: 5px;
  font-size: .8rem; color: var(--muted); }
.mk-period-range input[type="month"] { font: inherit; font-size: .8rem;
  padding: 3px 6px; border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink); min-width: 0; width: 9.5em;
  /* The picker's own widget is LTR whatever the page direction is; letting it
     inherit RTL puts the year on the wrong side of the field. */
  direction: ltr; }
.mk-period-clear { font-size: .8rem; color: var(--muted); }
.mk-period-now { flex: 1 0 100%; margin: 0; font-size: .8rem; }
.mk-alltime { font-weight: 400; font-size: .78rem; }
/* Public search: a mistyped query is worth interrupting for, so it reads as a
   notice rather than a caption — but it sits under the box it refers to. */
.ps-search-err { margin: var(--s2) 0 0; padding: 8px 12px; font-size: var(--t-sm);
  color: var(--bad); background: var(--bad-wash); border: 1px solid var(--bad);
  border-radius: var(--r-control); }
.ps-search-err strong { font-weight: 700; }
@media (max-width: 620px) {
  .mk-period-range { margin-inline-start: 0; }
}
.mk-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--s4); }
.mk-leaders { margin: 0; padding: 0 0 0 1.2em; display: flex; flex-direction: column;
  gap: 6px; }
.mk-leaders li { display: flex; align-items: center; gap: 8px; }
.mk-leaders li a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.mk-seeall { display: inline-flex; align-items: center; gap: 4px; margin-top: var(--s3);
  font-size: var(--t-sm); }
.mk-share { color: var(--seal); font-weight: 600; white-space: nowrap; }
.sort-opt.is-disabled { opacity: .45; cursor: not-allowed; }
/* ── UK public-site polish ──────────────────────────────────────────────── */
/* "New" tag on landing + auth features */
.lp-new-tag { display: inline-block; padding: 1px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  background: var(--seal); color: #fff; vertical-align: 2px; font-style: normal; }
/* landing: market-intelligence mock */
.lp-mock-intel { display: flex; flex-direction: column; gap: 12px; }
.lp-intel-head { display: flex; align-items: center; gap: 8px; font-weight: 700; }
.lp-intel-stats { display: flex; gap: var(--s4); }
.lp-intel-stats span { display: flex; flex-direction: column; }
.lp-intel-stats b { font-size: 1.25rem; line-height: 1.1; }
.lp-intel-stats small { color: var(--ink-soft); font-size: 11px; }
.lp-intel-inc { display: flex; align-items: center; gap: 6px; padding: 8px 12px;
  border-radius: 10px; background: var(--seal-wash); font-size: var(--t-sm); }
.lp-intel-inc small { color: var(--ink-soft); }
.lp-intel-bars { display: flex; flex-direction: column; gap: 6px; }
.lp-intel-bar { position: relative; height: 22px; border-radius: 6px;
  background: var(--seal-wash); overflow: hidden; font-size: 11px;
  display: flex; align-items: center; padding: 0 8px; gap: 6px; color: var(--ink); }
.lp-intel-bar::before { content: ""; position: absolute; inset: 0; width: var(--w);
  background: color-mix(in srgb, var(--seal) 22%, transparent); }
.lp-intel-bar i { font-style: normal; font-weight: 700; position: relative; }
.lp-intel-bar { z-index: 0; } .lp-intel-bar > * { position: relative; z-index: 1; }
/* IL award-intelligence block on the landing page. The stat values here are
   Hebrew money strings ("₪133.3 מיליארד"), not the short "£48.2m" the UK card
   was sized for, so the row wraps instead of forcing a horizontal scroll. */
.lp-intel-sec .lp-intel-stats { flex-wrap: wrap; gap: var(--s3) var(--s4); }
.lp-intel-sec .lp-intel-stats span { min-width: 0; }
.lp-intel-sec .lp-intel-stats b { font-size: 1.05rem; }
.lp-intel-sec .lp-intel-bar { height: 26px; }
/* The bar label is the buyer's name and can be long; the money stays whole and
   the name is what gives way. */
.lp-intel-sec .lp-intel-bar { overflow: hidden; white-space: nowrap; }
.lp-intel-sec .lp-intel-bar i { flex: none; }
.lp-intel-cta { margin-top: var(--s4); }
.lp-intel-note { margin-top: var(--s3); font-size: var(--t-sm);
  color: var(--ink-soft); line-height: 1.55; }
/* auth: branded split layout (UK only) */
.auth-wrap-split { display: grid; grid-template-columns: minmax(300px, 420px) minmax(320px, 400px);
  gap: var(--s6); align-items: center; justify-content: center; }
.auth-side { border-radius: var(--r-card); padding: var(--s6);
  background: linear-gradient(160deg, color-mix(in srgb, var(--seal) 10%, var(--surface)),
              color-mix(in srgb, var(--seal) 3%, var(--surface)));
  border: 1px solid color-mix(in srgb, var(--seal) 18%, var(--line)); }
.auth-side-kicker { display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--seal); }
.auth-side h2 { margin: var(--s2) 0 var(--s4); font-size: 1.5rem; line-height: 1.2; }
.auth-side-points { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 12px; }
.auth-side-points li { display: flex; gap: 10px; align-items: flex-start;
  font-size: var(--t-sm); line-height: 1.45; }
.auth-side-points svg { flex: none; margin-top: 2px; color: var(--seal); }
.auth-side-trust { margin: var(--s5) 0 0; display: flex; align-items: center; gap: 6px;
  color: var(--ink-soft); font-size: 12px; }
@media (max-width: 860px) { .auth-wrap-split { grid-template-columns: 1fr; }
  .auth-side { display: none; } }
/* legal hub nav */
.legal-nav { display: flex; flex-wrap: wrap; gap: 8px; margin: var(--s3) 0 var(--s4); }
.legal-nav a { padding: 5px 14px; border-radius: 999px; border: 1px solid var(--line);
  font-size: var(--t-sm); color: var(--ink-soft); text-decoration: none;
  transition: border-color .15s, color .15s, background .15s; }
.legal-nav a:hover { border-color: var(--seal); color: var(--seal); text-decoration: none; }
.legal-nav a.is-active { background: var(--seal); border-color: var(--seal); color: #fff; }
/* UK kickers add uppercase + letter-spacing on top of the shared quiet-eyebrow
   base (Latin-only niceties — Hebrew must not be letterspaced). */
.mkt-uk .lp-kicker { letter-spacing: .14em; text-transform: uppercase; }
.mkt-uk .lp-kicker .lp-new-tag { letter-spacing: .05em; vertical-align: 1px; }
/* framework-operator hint on buyer profiles */
.bp-fw-hint { display: flex; align-items: flex-start; gap: 8px; margin: 0 0 var(--s4);
  padding: 10px 14px; border-radius: 10px; background: var(--seal-wash);
  color: var(--ink-soft); font-size: var(--t-sm); line-height: 1.5; max-width: 720px; }
.bp-fw-hint svg { flex: none; margin-top: 2px; color: var(--seal); }
/* competition intensity */
.comp-panel { margin-top: var(--s3); padding: 10px 14px; border-radius: 10px;
  background: var(--seal-wash); font-size: var(--t-sm); line-height: 1.5;
  border-inline-start: 3px solid var(--seal); max-width: 720px; }
.comp-panel.comp-open { border-inline-start-color: var(--ok); }
.comp-panel.comp-concentrated { border-inline-start-color: var(--bad); }
.comp-head { display: flex; align-items: center; gap: 8px; font-weight: 700;
  margin-bottom: 4px; }
.comp-panel p { margin: 2px 0; }
.comp-basis { font-size: 12px; }
.comp-more > summary { list-style: none; cursor: pointer; margin-top: 4px;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--t-xs); font-weight: 600; color: var(--seal); }
.comp-more > summary::-webkit-details-marker { display: none; }
.comp-more > summary::marker { content: ""; }
.comp-more > summary:hover { text-decoration: underline; }
.comp-more > summary .chev { transition: transform .15s ease; }
.comp-more[open] > summary .chev { transform: rotate(180deg); }

/* ── Support desk (admin) ─────────────────────────────────────────────── */
.sd-filters { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); }
.sd-filters select, .sd-filters input[type="search"] {
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); font-size: var(--t-sm); font-family: inherit;
  inline-size: auto; flex: 0 1 auto;
}
.sd-filters input[type="search"] { min-inline-size: 220px; flex: 1 1 220px; }
.sd-billing-head { margin-top: var(--s3); }
.sd-row-billing td { background: var(--accent-wash); }
.chip.sd-type, .chip.sd-urg, .chip.sd-st, .chip.sd-flag {
  padding: 2px 9px; font-size: var(--t-xs); cursor: default; white-space: nowrap;
}
.chip.sd-type-billing { background: var(--accent-wash); border-color: var(--accent); color: var(--accent-ink); font-weight: 700; }
.chip.sd-urg-urgent { background: var(--bad-wash); border-color: var(--bad); color: var(--bad); font-weight: 700; }
.chip.sd-urg-high { border-color: var(--accent); color: var(--accent-ink); }
.chip.sd-st-open, .chip.sd-st-awaiting_admin { background: var(--seal-wash); border-color: var(--seal); color: var(--seal); }
.chip.sd-st-resolved { color: var(--ok); border-color: var(--ok); }
.chip.sd-st-archived, .chip.sd-st-awaiting_user { color: var(--ink-soft); }
.chip.sd-flag { background: var(--check-wash); border-color: var(--check); color: var(--check); }
.chip.sd-flag-err { background: var(--bad-wash); border-color: var(--bad); color: var(--bad); }

/* Thread page: work pane (left, sticky) + correspondence pane (right). */
.sd-cols { display: grid; grid-template-columns: minmax(340px, 5fr) minmax(0, 7fr);
  gap: var(--s5); align-items: start; }
.sd-col-work { display: flex; flex-direction: column; gap: var(--s4);
  position: sticky; top: var(--s4); max-block-size: calc(100vh - var(--s6));
  overflow-y: auto; }
.sd-col-thread { display: flex; flex-direction: column; gap: var(--s3);
  border-inline-start: 1px solid var(--line); padding-inline-start: var(--s5); }
.sd-thread-title { font-size: var(--t-md); margin: 0 0 var(--s2); }
@media (max-width: 980px) {
  .sd-cols { grid-template-columns: 1fr; }
  .sd-col-work { position: static; max-block-size: none; overflow: visible; order: 2; }
  .sd-col-thread { border-inline-start: 0; padding-inline-start: 0; order: 1; }
}
.sd-who { padding: var(--s3) var(--s4); }
.sd-who-name { margin: 0; display: flex; flex-wrap: wrap; gap: var(--s2); align-items: baseline; }
.sd-who-meta { margin: 4px 0 0; font-size: var(--t-xs); }
.sd-notes h2 { display: flex; align-items: center; gap: 6px; }
.sd-notes-list { list-style: none; margin: 0 0 var(--s3); padding: 0;
  display: flex; flex-direction: column; gap: var(--s2); }
.sd-notes-list li { background: var(--check-wash); border: 1px dashed var(--line);
  border-radius: var(--r-control); padding: var(--s2) var(--s3); font-size: var(--t-xs); }
.sd-note-body { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--t-sm); }
.sd-msg-when { margin-inline-start: auto; }
.sd-msg { border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s3) var(--s4);
  background: var(--surface); max-inline-size: 88%; box-shadow: var(--shadow); }
.sd-msg-inbound { align-self: flex-start; }
.sd-msg-outbound { align-self: flex-end; background: var(--seal-wash); }
.sd-msg-note { align-self: stretch; max-inline-size: none; background: var(--check-wash); border-style: dashed; box-shadow: none; }
.sd-msg-auto { opacity: .65; }
.sd-msg-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); font-size: var(--t-sm); margin-bottom: var(--s2); }
.sd-msg-body { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--t-sm); }
.sd-atts { list-style: none; padding: 0; margin: var(--s2) 0 0; font-size: var(--t-xs); color: var(--ink-soft); }
.sd-reply textarea, .sd-note-form textarea {
  inline-size: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: var(--r-control); font-family: inherit; font-size: var(--t-sm); resize: vertical;
}
.sd-reply-actions { display: flex; gap: var(--s2); margin-top: var(--s2); }
.sd-note-form { display: flex; gap: var(--s2); align-items: flex-start; }
.sd-note-form textarea { flex: 1; }
.sd-status-actions { display: flex; gap: var(--s2); }
.sd-side .card p { margin: 0 0 var(--s2); font-size: var(--t-sm); }

/* Public contact form (support lane) */
.contact-form .field { margin-bottom: var(--s3); }
.contact-form input, .contact-form select, .contact-form textarea {
  padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); font-family: inherit; font-size: var(--t-sm);
  inline-size: 100%; box-sizing: border-box;
}
.contact-form textarea { resize: vertical; }
/* Honeypot: visually gone but still submittable by naive bots. */
.hp-field { position: absolute !important; inset-inline-start: -9999px !important;
  inline-size: 1px; block-size: 1px; opacity: 0; pointer-events: none; }

/* Support desk — AI draft card */
.sd-draft { border: 1px dashed var(--seal); background: var(--seal-wash); }
.sd-draft-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); margin-bottom: var(--s2); }
.sd-draft-mark { font-weight: 700; color: var(--seal); font-size: var(--t-sm); }
.sd-draft-refs { font-size: var(--t-xs); margin: 0 0 var(--s2); }
.sd-draft textarea { inline-size: 100%; box-sizing: border-box; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--r-control); font-family: inherit;
  font-size: var(--t-sm); resize: vertical; background: var(--surface); }
.sd-draft-note { font-size: var(--t-xs); margin: var(--s2) 0 0; }
.sd-draft-stale-body { text-decoration: line-through; color: var(--ink-soft);
  white-space: pre-wrap; font-size: var(--t-sm); }
.sd-draft-nh .sd-draft-head { margin-bottom: 0; }
.sd-draft-regen { margin-inline-start: auto; }
.sd-draft-badge { color: var(--seal); font-weight: 700; margin-inline-start: 4px; }
.sd-draft-filter { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; }
.sd-draft-filter input { position: static; inline-size: auto; block-size: auto; opacity: 1; margin: 0; }

/* Awards table: "View source" link column (all-tenders pattern) */
.aw-table .aw-src { white-space: nowrap; text-align: end; }
.aw-table .aw-src a { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-xs); }

/* ══ Public contact — one form, live explainer pane ═══════════════════════ */
.ct-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 28px; align-items: start; margin: 18px 0 26px; }
.ct-form { margin: 0; }
.ct-info { position: sticky; top: 84px; }
.ct-info-inner { background: var(--seal-wash); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: 20px 22px;
  transition: opacity .12s ease, transform .12s ease; }
.ct-info-inner.is-switching { opacity: 0; transform: translateY(4px); }
.ct-info-kicker { display: inline-block; font-weight: 700; color: var(--seal);
  font-size: var(--t-sm); margin: 0 0 8px; }
.ct-info-desc { margin: 0 0 14px; color: var(--ink); font-size: var(--t-sm);
  line-height: 1.55; }
.ct-info-note { margin: 0; padding-top: 12px; border-top: 1px solid var(--line);
  color: var(--ink-soft); font-size: var(--t-xs); line-height: 1.5; }
@media (max-width: 760px) {
  .ct-grid { grid-template-columns: 1fr; }
  .ct-info { position: static; order: -1; }   /* explainer above the form on mobile */
}

/* Support desk: source + registered-user + sales chips */
.sd-src { background: var(--paper); border: 1px solid var(--line); color: var(--ink-soft); }
.sd-src-public_form { border-color: var(--seal); color: var(--seal); background: var(--seal-wash); }
.sd-src-email_orphan { border-style: dashed; }
.sd-known { background: var(--ok-wash); color: var(--ok); border: 1px solid var(--ok); }
.sd-type-sales { background: var(--accent-wash); color: var(--accent-ink);
  border: 1px solid var(--accent-ink); font-weight: 700; }

/* Public contact page — fit one screen: tight rhythm, side-by-side fields */
.ct-grid { margin: 12px 0 14px; }
.ct-form .field { margin-bottom: 10px; }
.ct-form textarea { min-height: 96px; }
.ct-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.ct-pair .field { margin-bottom: 10px; }
.legal-doc.ct-page h1 { margin: 4px 0 6px; font-size: 30px; }
.ct-page .blog-body > p:first-child { margin: 0 0 12px; }
.ct-page .crumbs { margin-bottom: 4px; }
.ct-page .muted:last-child { font-size: 12.5px; margin: 6px 0 0; }
@media (max-width: 640px) { .ct-pair { grid-template-columns: 1fr; } }

/* ══ How-it-works step headers — contour-line bands ═══════════════════════ */
.lp-steps-hdr .lps { padding: 0; overflow: hidden; }
.lps-head { position: relative; display: flex; align-items: center;
  justify-content: center; gap: 10px; padding: 14px 48px;
  min-height: 56px; color: var(--lp-ink); border-bottom: 1px solid var(--lp-line);
  background-color: #F4F4EF;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='80' viewBox='0 0 220 80'%3E%3Cg fill='none' stroke='%231C2B33' stroke-opacity='.10' stroke-width='1'%3E%3Cpath d='M-10 66 C 40 30 90 86 140 50 S 240 40 250 60'/%3E%3Cpath d='M-10 52 C 40 16 90 72 140 36 S 240 26 250 46'/%3E%3Cpath d='M-10 38 C 40 2 90 58 140 22 S 240 12 250 32'/%3E%3Cpath d='M-10 24 C 40 -12 90 44 140 8 S 240 -2 250 18'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 220px 80px; }
.lps-head-2 { background-position: 60px 0; }
.lps-head-3 { background-position: 130px 0; }
.lps-head h3 { margin: 0; font-family: "Sora", sans-serif; font-size: 17px; color: var(--lp-accent); font-weight: 400; }
.lps-head svg { flex: none; }
/* Stage number in the header: same ink-on-paper palette, unmistakably a step
   marker — filled ink disc, paper-white numeral. */
.lps-num { position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; background: #FAFAF7;
  border: 1.5px solid var(--lp-ink);
  color: var(--lp-ink); font-family: "Sora", sans-serif; font-weight: 700; font-size: 13px; }
.lps-title { display: inline-flex; align-items: center; gap: 9px; }
.lps-body { padding: 16px 20px 22px; }
.lps-body p { margin: 0; }

/* ══ Everything-included tiles — same contour-band headers ════════════════ */
.lpt { padding: 0 !important; overflow: hidden; min-height: 160px; }
.lpt-head { display: flex; align-items: center; justify-content: center;
  padding: 8px 16px; min-height: 44px; color: var(--lp-accent);
  border-bottom: 1px solid var(--lp-line);
  background-color: #F4F4EF;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='80' viewBox='0 0 220 80'%3E%3Cg fill='none' stroke='%231C2B33' stroke-opacity='.10' stroke-width='1'%3E%3Cpath d='M-10 66 C 40 30 90 86 140 50 S 240 40 250 60'/%3E%3Cpath d='M-10 52 C 40 16 90 72 140 36 S 240 26 250 46'/%3E%3Cpath d='M-10 38 C 40 2 90 58 140 22 S 240 12 250 32'/%3E%3Cpath d='M-10 24 C 40 -12 90 44 140 8 S 240 -2 250 18'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 220px 80px; }
.lp-bento .lpt:nth-child(3n+2) .lpt-head { background-position: 60px 0; }
.lp-bento .lpt:nth-child(3n) .lpt-head { background-position: 130px 0; }
.lpt-title { display: inline-flex; align-items: center; gap: 9px; }
.lpt-head h3 { margin: 0; font-family: "Sora", sans-serif; font-size: 15.5px; color: var(--lp-accent); font-weight: 400; }
.lpt-body { padding: 13px 16px 17px; }
.lpt-body p { margin: 0; }

/* Readiness: matched-certification reassurance rows (award icon, met styling) */

.onb-editable-note { margin: 14px 2px 0; font-size: 13px; display: flex; align-items: center; gap: 6px; }
/* Onboarding fine-tune step: the two strict keyword filters sit in one bordered
   group with a compact amber caption, so the caution reads as part of the fields. */
/* UK wizard option chips (sector / regions / buyer types) run ~15% smaller than
   the default chip — the full-size rows read as oversized buttons. */
.mkt-uk .wizard-step .chip-row .chip { padding: 7px 14px; font-size: var(--t-xs); }
.kw-group { margin-top: var(--s4); padding: 10px 12px 12px; border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--lp-accent, #d97706) 22%, var(--line));
  background: color-mix(in srgb, var(--lp-accent, #d97706) 4%, var(--surface)); }
.kw-group .field { margin-bottom: var(--s3); }
.kw-group .field:last-child { margin-bottom: 0; }
.kw-note { display: flex; align-items: flex-start; gap: 6px; margin: 0 0 10px;
  font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
.kw-note .kw-note-ic { flex: none; margin-top: 2px; color: var(--lp-accent, #d97706); }
.cert-other { margin-top: var(--s3); }

/* Mid-trial subscribe confirmation dialog */
.sub-confirm-overlay { position: fixed; inset: 0; background: rgba(28, 43, 51, .45);
  z-index: 320; display: flex; align-items: center; justify-content: center; padding: 20px; }
.sub-confirm-overlay[hidden] { display: none; }
.sub-confirm { max-width: 460px; width: 100%; padding: 22px 24px; }
.sub-confirm h3 { margin: 0 0 10px; }
.sub-confirm p { margin: 0 0 18px; line-height: 1.55; }
.sub-confirm-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }

/* Help & contact form — compact rhythm, hint and send on one footer row */
.support-form .field { margin-bottom: 10px; }
.support-form .settings-row { gap: 12px; }
.support-form textarea { min-height: 96px; }
.support-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-top: 6px; }
.support-foot .settings-hint { margin: 0; flex: 1 1 260px; }
.support-foot .btn { flex: none; }

/* ══ User guide (UK) — internal-site card layout with contour-band headers ══ */
.gd { max-width: 860px; margin: 0 auto; }
.gd .gd-sec { padding: 0; overflow: hidden; margin-bottom: var(--s5); }
.gd-band { display: flex; align-items: center; gap: 10px; padding: 10px 18px; min-height: 46px;
  color: var(--accent); border-bottom: 1px solid var(--line);
  background-color: var(--wash);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='80' viewBox='0 0 220 80'%3E%3Cg fill='none' stroke='%231C2B33' stroke-opacity='.10' stroke-width='1'%3E%3Cpath d='M-10 66 C 40 30 90 86 140 50 S 240 40 250 60'/%3E%3Cpath d='M-10 52 C 40 16 90 72 140 36 S 240 26 250 46'/%3E%3Cpath d='M-10 38 C 40 2 90 58 140 22 S 240 12 250 32'/%3E%3Cpath d='M-10 24 C 40 -12 90 44 140 8 S 240 -2 250 18'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 220px 80px; }
.gd-band h2 { margin: 0; font-family: "Sora", sans-serif; font-size: 17px; font-weight: 640; color: var(--accent); }
.gd-band svg { flex: none; }
html[data-theme="dark"] body.app .gd-band {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='80' viewBox='0 0 220 80'%3E%3Cg fill='none' stroke='%23E7EDF1' stroke-opacity='.10' stroke-width='1'%3E%3Cpath d='M-10 66 C 40 30 90 86 140 50 S 240 40 250 60'/%3E%3Cpath d='M-10 52 C 40 16 90 72 140 36 S 240 26 250 46'/%3E%3Cpath d='M-10 38 C 40 2 90 58 140 22 S 240 12 250 32'/%3E%3Cpath d='M-10 24 C 40 -12 90 44 140 8 S 240 -2 250 18'/%3E%3C/g%3E%3C/svg%3E");
}
.gd-body { padding: var(--s4) var(--s5) var(--s5); }
.gd-body > :first-child { margin-top: 0; }
.gd-body > :last-child { margin-bottom: 0; }
.gd-body h3 { margin: var(--s5) 0 var(--s2); font-size: var(--t-md); }
.gd-body li { margin-bottom: 6px; }

/* "On this page" contents box — a quiet card with a multi-column link grid */
.gd-toc { margin: 0 0 var(--s5); padding: var(--s4) var(--s5); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-card); }
.gd-toc-title { display: block; margin-bottom: 10px; font-family: "Sora", sans-serif;
  font-size: var(--t-sm); font-weight: 640; color: var(--ink); }
.gd-toc-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--s4) 28px; }
.gd-toc-col { display: flex; flex-direction: column; gap: 7px; }
.gd-toc-cat { font-size: 11.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); opacity: .75; margin-bottom: 2px; }
.gd-toc-col a { font-size: 13.5px; color: var(--ink-soft); text-decoration: none;
  padding-inline-start: 12px; position: relative; transition: color .12s; }
.gd-toc-col a::before { content: ""; position: absolute; inset-inline-start: 0; top: 50%;
  transform: translateY(-50%); width: 5px; height: 5px; border-radius: 999px;
  background: var(--accent); opacity: .55; }
.gd-toc-col a:hover { color: var(--accent-ink); text-decoration: underline; }

/* Quick-start numbered steps — the paper/ink disc numbering */
.gd-qs-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.gd-qs-steps li { display: flex; align-items: flex-start; gap: 12px; }
.gd-num { flex: none; width: 28px; height: 28px; border-radius: 999px; margin-top: -2px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--paper); border: 1.5px solid var(--ink); color: var(--ink);
  font-family: "Sora", sans-serif; font-weight: 640; font-size: 14px; }

/* Amber tip callout (same visual family as the onboarding strict-filter note) */
.gd-tip { display: flex; align-items: flex-start; gap: 8px; margin: var(--s4) 0;
  padding: 10px 12px; border-radius: 8px; font-size: 13px; line-height: 1.55;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--line));
  background: color-mix(in srgb, var(--accent) 4%, var(--surface)); }
.gd-tip svg { flex: none; margin-top: 2px; color: var(--accent); }

/* Numbered flow lists inside sections keep plain numbering (steps, not sections) */
.gd-flow { padding-inline-start: 22px; }
.gd-flow li { margin-bottom: 6px; }

/* Flat docs-style sections (the band card is reserved for the quick start):
   accent icon chip + Sora title over a thin rule, generous separation. */
.gd-s { margin: 0 0 44px; }
/* Anchor jumps must clear the sticky topbar, or it hides the section title. */
.gd-s[id] { scroll-margin-top: 78px; }
.gd-h { display: flex; align-items: center; gap: 10px; margin: 0 0 var(--s3);
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
  font-family: "Sora", sans-serif; font-size: 19px; font-weight: 640; color: var(--ink); }
.gd-h .gd-h-ic { flex: none; width: 30px; height: 30px; border-radius: 8px;
  background: var(--accent-wash); color: var(--accent-ink);
  display: inline-flex; align-items: center; justify-content: center; }
.gd-s .gd-body { padding: 0; }
.gd-s .gd-body h3 { margin-top: var(--s4); }


/* Grouped sector picker (onboarding "תחום עיסוק עיקרי"): 22 flat chips are hard
   to scan, so they're bucketed into families with a light heading. */

/* ── Public authority pages (T-ILSEO) — the buyer-page design language ported
   from the UK public pages so both markets read as one product. Markup is
   .bh2-* (hub) and .bp2-* (detail); the UK wow band (.bw-*) is deliberately
   NOT ported — it renders award history + spend, which IL has no data for.
   RTL-safe as written: the only directional rules use logical properties
   (inset-inline-start / margin-inline-end), so they mirror automatically. */
.seo-page { max-width: 860px; padding-block: var(--s5) var(--s6); }
.seo-crumb { font-size: var(--t-sm); color: var(--ink-soft); margin-bottom: var(--s3); }
.seo-crumb a { color: var(--ink-soft); }
.seo-crumb a:hover { color: var(--seal); }

.seo-head2 { display: flex; gap: var(--s4); align-items: flex-start; margin: var(--s4) 0 var(--s5); }
.seo-head-ic { flex: none; width: 54px; height: 54px; border-radius: 14px;
  background: var(--seal-wash); color: var(--seal); display: grid; place-items: center; }
.seo-head-main { min-width: 0; }
.seo-head2 h1 { font-size: clamp(24px, 3.4vw, 33px); line-height: 1.14; margin: 0;
  font-weight: 600; letter-spacing: -.015em; text-wrap: balance; }
.seo-h1-light { color: var(--ink-soft); font-weight: 500; }
.seo-idline { color: var(--ink-soft); font-size: var(--t-sm); margin: 8px 0 0; }
.seo-idtype { text-transform: capitalize; color: var(--ink); font-weight: 600; }
.seo-iddot { opacity: .5; margin: 0 2px; }

/* ── T-UKSEO4 v2 — slick buyer-page dossier (below the untouched band + strip).
   Restrained: white panels, hairline separators, one seal-blue accent, quiet
   premium teases. Eyebrow labels give the page an intelligence-report rhythm. */
.bp2 { display: grid; grid-template-columns: 1.7fr 1fr; gap: 20px; margin-top: 22px; align-items: start; }
@media (max-width: 760px) { .bp2 { grid-template-columns: 1fr; } }
.bp2-main, .bp2-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.bp2-panel { background: var(--surface); border: 1px solid rgba(28,43,51,.08); border-radius: 14px;
  padding: 18px 20px; box-shadow: 0 1px 2px rgba(28,43,51,.03); }
.bp2-panel-soft { background: var(--seal-wash); border-color: transparent; box-shadow: none; }
.bp2-head { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; }
.bp2-head h2 { font-size: 15px; font-weight: 700; color: var(--ink); margin: 0; letter-spacing: -.01em; }
.bp2-eyebrow { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--seal); background: var(--seal-wash);
  padding: 3px 8px; border-radius: 6px; }
.bp2-eyebrow.bp2-live { color: var(--live); background: rgba(26,127,75,.10); }
.bp2-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--live); box-shadow: 0 0 0 3px rgba(26,127,75,.18); }
.bp2-count { margin-inline-start: auto; font-size: 13px; font-weight: 700; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }
/* "כמה זמן נותנים להגיש": the number leads, because it is the one fact on the
   panel a supplier acts on — 14 days and 59 days are different decisions about
   whether to start writing at all. */
.bp2-window { margin: 0; display: flex; flex-direction: column; gap: 3px; }
.bp2-window b { font-size: 22px; font-weight: 700; line-height: 1.1;
  letter-spacing: -.01em; color: var(--ink); font-variant-numeric: tabular-nums; }
.bp2-window span { font-size: 12px; color: var(--ink-soft); line-height: 1.4; }
/* rows */
.bp2-rows { list-style: none; margin: 0; padding: 0; }
.bp2-row { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 0; border-top: 1px solid rgba(28,43,51,.07); }
.bp2-row:first-child { border-top: 0; padding-top: 2px; }
.bp2-row-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.bp2-row-title { font-weight: 600; color: var(--ink); font-size: 14px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.bp2-row-sub { font-size: 11.5px; color: var(--ink-soft); }
.bp2-row-sm .bp2-row-title { font-weight: 500; font-size: 13.5px; }
.bp2-due { flex: none; font-size: 11.5px; font-weight: 600; color: var(--seal); background: var(--seal-wash);
  border-radius: 999px; padding: 4px 11px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.bp2-when { flex: none; font-size: 11.5px; color: var(--ink-soft); white-space: nowrap; }
/* "View source" — every row links back to the notice on the government service
   that published it: checkable provenance for a reader, a real citation for a
   crawler. Same wording + external icon as the in-app source links, and the same
   --accent-ink orange those links inherit from the base `a` rule (the AA-contrast
   text orange, not the bright --accent) — visible enough to find, quiet enough
   not to compete with the signup CTA. Deliberately NOT inline-flex: that would
   make the label one unbreakable box and push a narrow phone sideways. */
.bp2-src { color: var(--accent-ink); text-decoration: none;
  border-bottom: 1px solid transparent; transition: border-color .15s ease; }
.bp2-src:hover, .bp2-src:focus-visible { border-bottom-color: currentColor; }
.bp2-src-ic { vertical-align: -1px; margin-inline-start: 3px; opacity: .65; }
.bp2-src:hover .bp2-src-ic, .bp2-src:focus-visible .bp2-src-ic { opacity: 1; }
.bp2-sep { margin: 0 5px; opacity: .45; }
.bp2-more { margin: 14px 0 0; font-size: 12.5px; color: var(--ink-soft); }
/* ---- browse-the-grid, on the search empty state -------------------------
   Three quiet columns BELOW the search band, behind a rule. This is where the
   ~200 scope pages are linked from, so it has to be scannable rather than
   decorative: no cards, no icons, just names and real counts — and quiet
   enough that it never competes with the box someone came here to type in. */
.ps-browse-sec { max-width: 760px; margin: 0 auto; padding-top: 32px;
  border-top: 1px solid var(--line); }
.ps-browse { display: grid; gap: 26px 34px; margin: 0 auto;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  max-width: 760px; text-align: start; }
.ps-browse h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-soft); margin: 0 0 8px; font-weight: 600; font-family: var(--font-body); }
.ps-browse ul { list-style: none; margin: 0; padding: 0; }
.ps-browse li { margin: 0; }
/* Soft ink, not full ink: these are an alternative to searching, not the
   invitation. They come forward on hover, which is when they are wanted. */
.ps-browse a { display: flex; justify-content: space-between; gap: 10px;
  padding: 6px 0; font-size: 13px; color: var(--ink-soft); text-decoration: none;
  transition: color .12s ease; }
.ps-browse a:hover { color: var(--seal); text-decoration: underline;
  text-underline-offset: 3px; }
.ps-browse .muted { color: var(--ink-soft); font-size: 12.5px; }
@media (max-width: 560px) { .ps-browse { gap: 22px; } }

/* ---- the alert box (T-ILALERT) -----------------------------------------
   Sits under the results, where the reader has just seen what this search
   returns. Styled as a quiet panel rather than a banner: it is an offer, not an
   interruption, and a search page that shouts loses the search. */
.ps-alert { margin: 28px 0 0; padding: 18px 20px; border-radius: var(--r-card);
  background: color-mix(in srgb, var(--seal) 5%, var(--surface));
  border: 1px solid var(--line); }
.ps-alert-copy { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.ps-alert-copy strong { font-size: 15px; }
.ps-alert-copy span { font-size: 13px; color: var(--ink-soft); }
.ps-alert-row { display: flex; gap: 8px; margin: 12px 0 0; }
body.ps-body .ps-alert-input { flex: 1; min-width: 0; font: inherit; font-size: 14.5px;
  padding: 10px 12px; border-radius: var(--r-control); border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); }
body.ps-body .ps-alert-input:focus { outline: 0; border-color: var(--seal);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--seal) 13%, transparent); }
.ps-alert-btn { flex: none; border: 0; cursor: pointer; font: inherit; font-weight: 500;
  font-size: 14px; padding: 0 20px; border-radius: var(--r-control);
  background: var(--btn); color: #fff; box-shadow: inset 0 -2.5px 0 var(--btn-line); }
.ps-alert-btn:hover { background: var(--btn-hover); }
.ps-alert-fine { margin: 10px 0 0; font-size: 11.5px; color: var(--ink-soft); }
.ps-alert-title { font-size: clamp(24px, 4vw, 32px); margin: 0 0 10px;
  font-family: var(--font-display); color: var(--ink); }
@media (max-width: 560px) {
  .ps-alert-row { flex-wrap: wrap; }
  .ps-alert-btn { width: 100%; padding: 11px 20px; }
}

/* Where this tender sits in the grid — quiet, above the back link, and wrapping
   rather than scrolling on a phone. */
.pt-scopes { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 26px 0 0; padding-top: 16px; border-top: 1px solid var(--line); }
.pt-scopes-label { font-size: 12.5px; color: var(--ink-soft); }
.pt-scopes a { font-size: 13px; padding: 5px 11px; border-radius: 999px;
  text-decoration: none; color: var(--ink);
  background: color-mix(in srgb, var(--seal) 6%, var(--surface));
  border: 1px solid transparent; transition: background .14s ease, color .14s ease,
    border-color .14s ease; }
.pt-scopes a:hover { background: var(--seal-wash); color: var(--seal);
  border-color: color-mix(in srgb, var(--seal) 22%, transparent); }

/* ---- the scope pages (category / region / both) -------------------------
   The intro is the one paragraph a search engine quotes, so it gets reading
   width and body-size type rather than the muted caption treatment. */
.scope-intro { max-width: 70ch; margin: 0 0 var(--s5); color: var(--ink-soft);
  font-size: var(--t-sm); line-height: 1.6; }
/* The cross-link grid: dense enough to scan, not a wall of blue. */
.scope-grid { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 2px 18px; }
.scope-grid a { display: block; padding: 7px 0; text-decoration: none;
  color: var(--ink); font-size: 13.5px; }
.scope-grid a:hover { color: var(--seal); text-decoration: underline;
  text-underline-offset: 3px; }

/* The authority page hosts real search-result cards when the public search is
   live. The cards bring their own border and padding, so the panel drops the
   inner gutter it uses for hairline rows and lets them sit flush. */
.bp2-panel-rows .ps-results { margin-top: 4px; }
.bp2-morelink { display: inline-block; margin: 14px 0 0; font-size: 13px;
  color: var(--seal); text-decoration: none; font-weight: 500; }
.bp2-morelink:hover { text-decoration: underline; text-underline-offset: 3px; }

/* The signup in the alerts panel. btn-primary is the app's seal blue over a
   construction-orange base line — right on a pricing page, far too loud for a
   sidebar note on a free reference page, where it read as the point of the
   page rather than an aside. Quiet, small, and still obviously pressable. */
.bp2-cta { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px;
  padding: 7px 14px; border: 1px solid var(--ink-soft); border-radius: 8px;
  background: var(--surface); color: var(--ink); font-size: 13px; font-weight: 600;
  text-decoration: none; }
.bp2-cta:hover { border-color: var(--ink); background: var(--wash); }
/* A category row that is a link must not lose the row's own colour. */
.bp2-row a.bp2-row-title { color: inherit; text-decoration: none; }
.bp2-row a.bp2-row-title:hover { color: var(--seal); text-decoration: underline;
  text-underline-offset: 3px; }
.bp2-sub { margin: 0 0 10px; font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }
/* quiet premium tease — a lock glyph + one muted line above a hairline */
.bp2-tease { display: flex; align-items: flex-start; gap: 7px; margin: 14px 0 0; padding-top: 12px;
  border-top: 1px dashed rgba(28,43,51,.13); font-size: 12px; color: var(--ink-soft); line-height: 1.55; }
.bp2-tease svg { flex: none; margin-top: 1px; color: var(--seal); opacity: .7; }
.bp2-panel-soft .bp2-tease { border-top-color: rgba(28,43,51,.12); }
/* framework links */
.bp2-links { list-style: none; margin: 0; padding: 0; }
.bp2-links li { padding: 9px 0; border-top: 1px solid rgba(28,43,51,.07); }
.bp2-links li:first-child { border-top: 0; padding-top: 0; }
.bp2-links a { color: var(--seal); font-weight: 500; font-size: 13.5px; }
.bp2-links a:hover { text-decoration: underline; }
/* related buyers — a clean link list (names vary in length; pills would stretch) */
.bp2-orglist { list-style: none; margin: 0; padding: 0; }
.bp2-orglist li { border-top: 1px solid rgba(28,43,51,.07); }
.bp2-orglist li:first-child { border-top: 0; }
.bp2-orglist a { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 0; color: var(--ink); font-size: 13px; font-weight: 500; transition: color .14s ease; }
/* The NAME truncates; the count never does. The rule used to target every
   span in the row, and the only span there was the count — so a long name
   ("משרד הבריאות - הקריה הרפואית לבריאות האדם, ביה"ח רמב"ם") pushed the count
   out of the row and clipped it to "(..", which is the one part of the line
   that is useless when abbreviated. */
.bp2-orgname { min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.bp2-orgcount { flex: none; white-space: nowrap; }
.bp2-orglist a svg { flex: none; color: var(--ink-soft); opacity: .45;
  transition: transform .14s ease, color .14s ease, opacity .14s ease; }
.bp2-orglist a:hover { color: var(--seal); }
.bp2-orglist a:hover svg { color: var(--seal); opacity: 1; transform: translateX(2px); }

/* ── Buyers hub (/organisations) — same slick language as the buyer page:
      refined header, soft featured cards with a live "open" dot, and a clean
      two-column A–Z directory of hairline rows. New .bh2-* namespace only. ── */
.bh2-head{margin:2px 0 6px;max-width:72ch}
.bh2-head h1{font-size:clamp(26px,3.6vw,34px);font-weight:600;line-height:1.14;margin:0;
  letter-spacing:-.015em;text-wrap:balance}
.bh2-intro{color:var(--ink-soft);line-height:1.6;font-size:14.5px;margin:11px 0 0}
.bh2-updated{font-size:12px;color:var(--ink-soft);margin:9px 0 0}
.bh2-sect{margin-top:34px}
.bh2-sect .bp2-head{margin-bottom:14px}
/* shared monogram avatar — soft seal-wash tile with the buyer's initials */
.bh2-mono,.bh2-az-mono{flex:none;display:grid;place-items:center;font-weight:800;color:var(--seal);
  background:var(--seal-wash);font-variant-numeric:tabular-nums;letter-spacing:.01em}
.bh2-mono{width:40px;height:40px;border-radius:11px;font-size:14.5px}
.bh2-az-mono{width:24px;height:24px;border-radius:7px;font-size:10px}
/* featured cards — full-card link: monogram · name+stats · hover arrow */
.bh2-cards{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:12px}
.bh2-card{position:relative}
/* Uniform-height cards: a fixed floor + stretch so every panel in the grid is
   the same size regardless of name length. align-items:stretch lets the body
   fill the height so the stats can sit on a shared baseline. */
.bh2-card-link{display:flex;align-items:stretch;gap:13px;min-height:98px;
  background:#fff;border:1px solid rgba(28,43,51,.08);border-radius:15px;padding:15px 15px 15px 16px;
  box-shadow:0 1px 2px rgba(28,43,51,.03);
  transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease}
.bh2-card-link:hover{transform:translateY(-2px);border-color:rgba(22,85,122,.28);
  box-shadow:0 12px 26px -14px rgba(28,43,51,.28)}
.bh2-card-link:hover .bh2-mono{background:var(--seal);color:#fff}
.bh2-mono{transition:background .16s ease,color .16s ease}
.bh2-card-body{min-width:0;flex:1;display:flex;flex-direction:column;gap:9px}
/* Name fills up to two lines, then truncates with an ellipsis (full name in the
   title tooltip) — a very long name shortens instead of enlarging the panel. */
.bh2-card-name{font-weight:600;font-size:14.5px;line-height:1.3;color:var(--ink);
  transition:color .14s ease;display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;line-clamp:2;overflow:hidden}
.bh2-card-link:hover .bh2-card-name{color:var(--seal)}
/* Stats stay on ONE line (nowrap) so the card height never grows for a long
   count; overflow is clipped inside the body rather than wrapping. */
.bh2-card-stats{margin-top:auto;display:flex;flex-wrap:nowrap;gap:14px;overflow:hidden;
  font-size:11.5px;color:var(--ink-soft)}
.bh2-stat{white-space:nowrap}
.bh2-stat b{font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
.bh2-stat-live b{color:var(--live)}
.bh2-stat-live::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%;
  background:var(--live);margin-inline-end:5px;vertical-align:middle;box-shadow:0 0 0 2px rgba(26,127,75,.18)}
.bh2-card-go{flex:none;color:var(--ink-soft);opacity:.35;margin-top:1px;
  transition:transform .16s ease,color .16s ease,opacity .16s ease}
.bh2-card-link:hover .bh2-card-go{color:var(--seal);opacity:1;transform:translateX(3px)}
/* A–Z directory — two-column list of monogram rows with two live counts */
.bh2-az{list-style:none;margin:0;padding:0;columns:2;column-gap:26px}
@media(max-width:640px){.bh2-az{columns:1}}
.bh2-az li{break-inside:avoid;border-top:1px solid rgba(28,43,51,.07)}
.bh2-az a{display:flex;align-items:center;gap:11px;padding:9px 8px 9px 6px;border-radius:9px;
  color:var(--ink);font-size:13.5px;font-weight:500;
  transition:color .14s ease,background .14s ease}
.bh2-az a:hover{color:var(--seal);background:var(--seal-wash)}
.bh2-az a:hover .bh2-az-mono{background:var(--seal);color:#fff}
.bh2-az-mono{transition:background .14s ease,color .14s ease}
.bh2-az-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bh2-az-stats{flex:none;display:flex;align-items:baseline;gap:10px;font-size:11px;
  color:var(--ink-soft);font-variant-numeric:tabular-nums}
.bh2-az-open{font-weight:600;color:var(--ink)}
.bh2-az-open::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%;
  background:var(--live);margin-inline-end:5px;vertical-align:middle}
.bh2-az-exp{position:relative;padding-inline-start:11px}
.bh2-az-exp::before{content:"";position:absolute;inset-inline-start:0;top:50%;transform:translateY(-50%);
  width:1px;height:10px;background:rgba(28,43,51,.16)}
@media (prefers-reduced-motion: reduce){.bh2-card-link{transition:none}}

/* The IL authority header tile carries a two-letter monogram, where the UK page
   uses a generic building glyph — a monogram identifies the authority, and with
   235 of them a repeated glyph would say nothing. Same 54px tile either way. */
.seo-head-ic { font-size: 21px; font-weight: 700; letter-spacing: .01em; }
/* The card chevron should travel along the reading direction, which is RTL here. */
[dir="rtl"] .bh2-card-link:hover .bh2-card-go { transform: translateX(-3px); }

/* T-PUBSTATS — admin public-site analytics dashboard (scoped .psx). Utilitarian
   but scannable: a conversion funnel on top, a KPI strip, a prominent insights
   callout, then grouped cards of tables with inline magnitude bars. */
.psx { --psx-good: #1a7f4b; }
.psx-note { margin: 0 0 var(--s5); font-size: var(--t-xs); color: var(--ink-soft);
  line-height: 1.5; max-width: 70ch; }
.psx-muted { color: var(--ink-soft); }

/* Conversion funnel — the headline. Steps shrink-illustrate the drop-off. */
.psx-funnel { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
  margin: 0 0 var(--s4); }
.psx-funnel-3 { grid-template-columns: repeat(3, 1fr); }
.psx-step { position: relative; background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 16px 14px 14px; text-align: center; }
.psx-step.is-goal { background: var(--seal-wash); border-color: transparent; }
.psx-step-n { font-size: 28px; font-weight: 800; color: var(--ink); line-height: 1;
  font-variant-numeric: tabular-nums; }
.psx-step.is-goal .psx-step-n { color: var(--seal); }
.psx-step-l { margin-top: 5px; font-size: var(--t-sm); font-weight: 600; color: var(--ink); }
.psx-step-h { font-size: 10.5px; color: var(--ink-soft); margin-top: 2px; }
.psx-step-drop { position: absolute; top: 10px; inset-inline-end: 10px;
  font-size: 10.5px; font-weight: 700; color: var(--ink-soft);
  background: var(--paper); border: 1px solid var(--line); border-radius: 999px;
  padding: 1px 6px; }
.psx-step.is-goal .psx-step-drop { color: var(--seal); background: #fff; }

/* KPI strip. */
/* Fits the strip it is given rather than five columns whatever happens: the
   jobs board's strip and the scraping one both carry six readings, and a hard
   repeat(5) stranded the sixth alone on a second row. auto-fit keeps the
   five-tile strips on this page laid out exactly as before. */
.psx-kpis { display: grid; gap: 10px; margin: 0 0 var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.psx-kpi { background: var(--surface); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 12px; }
.psx-kpi b { display: block; font-size: 19px; font-weight: 800; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.psx-kpi .psx-accent { color: var(--seal); }
.psx-kpi span { display: block; font-size: 11px; color: var(--ink-soft); margin-top: 1px; }

/* Insights callout. */
.psx-insights { background: var(--seal-wash); border-radius: 10px;
  padding: 14px 18px; margin: 0 0 var(--s5); }
.psx-insights-h { font-size: var(--t-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--seal); margin-bottom: 6px; }
.psx-insights ul { margin: 0; padding-inline-start: 1.1rem;
  display: flex; flex-direction: column; gap: 5px; }
.psx-insights li { font-size: var(--t-sm); line-height: 1.5; color: var(--ink); }

/* Grouped card layout. */
.psx-group { margin: var(--s6) 0 var(--s3); font-size: var(--t-sm); font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.psx-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4); }
.psx-card { background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 14px 16px; min-width: 0; }
.psx-card.psx-wide { grid-column: 1 / -1; }
.psx-trend-card { margin-bottom: var(--s4); }
.psx-card-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  margin-bottom: 10px; }
.psx-card-h h3 { margin: 0; font-size: var(--t-base); font-weight: 700; color: var(--ink); }
.psx-sub { font-size: 11px; color: var(--ink-soft); line-height: 1.4; }

/* Compact tables with an inline bar column. */
.psx-tbl { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.psx-tbl th { text-align: start; font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .02em; color: var(--ink-soft);
  padding: 0 8px 6px 0; border-bottom: 1px solid var(--line); }
.psx-tbl td { padding: 6px 8px 6px 0; border-bottom: 1px solid rgba(28,43,51,.05);
  vertical-align: middle; }
.psx-tbl tr:last-child td, .psx-tbl tbody tr:last-child td { border-bottom: 0; }
.psx-tbl .psx-r { text-align: end; }
.psx-tbl b { font-weight: 700; color: var(--ink); }
.psx-path { max-width: 240px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--ink); }
.psx-linklabel { color: var(--ink); font-weight: 500; }
.psx-linktarget { display: block; font-size: 11px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; max-width: 320px; }
.psx-barcell { width: 90px; }
.psx-bar { display: block; width: 100%; height: 6px; background: var(--line);
  border-radius: 999px; overflow: hidden; }
.psx-fill { display: block; height: 100%; background: var(--seal); opacity: .8;
  border-radius: 999px; }
.psx-conv { font-weight: 700; font-variant-numeric: tabular-nums; }
.psx-conv.is-good { color: var(--psx-good); }
.psx-conv.is-zero { color: var(--ink-soft); }

/* The only cell on the search panel that names something to go and fix: a
   search the site could not answer. Amber, not red — it is a gap in coverage,
   not a failure, and a red table teaches an operator to stop reading colour. */
.psx-warn { font-size: 12px; color: #B14A05; white-space: nowrap; }

/* Long lists scroll inside their card. A fifty-row term table otherwise sets
   the height of the whole page and pushes everything after it out of reach;
   capped, each panel stays a panel. The header sticks so the columns stay
   readable while scrolling. */
.psx-scroll { max-height: 320px; overflow-y: auto; overscroll-behavior: contain; }
/* Exactly ten rows, then scroll. Derived rather than guessed at: a psx-tbl row
   is 6px + line-height + 6px on a var(--t-sm) body, and the sticky header adds
   its own row — so a change to the table's padding moves this with it instead
   of leaving a fixed box that shows nine rows or eleven. */
.psx-scroll-10 { max-height: calc(10 * (var(--t-sm) * 1.45 + 12px) + 26px); }
.psx-scroll .psx-tbl th { position: sticky; top: 0; z-index: 1;
  background: var(--surface); }
.psx-scroll::-webkit-scrollbar { width: 8px; }
.psx-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.psx-scroll { scrollbar-width: thin; }

/* Trend sparkline. */
.psx-spark { display: flex; align-items: flex-end; gap: 3px; height: 96px; }
.psx-scol { position: relative; flex: 1; min-width: 3px; height: 100%;
  display: flex; align-items: flex-end; }
.psx-sbar { display: block; width: 100%; min-height: 2px; border-radius: 2px 2px 0 0;
  background: var(--seal); opacity: .7; }
.psx-scol:hover .psx-sbar { opacity: 1; }
/* Raw hits behind the engaged bar: present, so a spike is still visible, but
   plainly not the number being reported. Absolutely positioned so it shares the
   column's baseline with the solid bar rather than sitting beside it. */
.psx-sghost { position: absolute; inset-inline: 0; bottom: 0; display: block;
  min-height: 2px; border-radius: 2px 2px 0 0;
  background: var(--seal); opacity: .16; }
.psx-spark-note { font-size: var(--t-xs); margin: 6px 0 0; }

/* The engaged count leads the KPI strip; drive-by sits next to it, deliberately
   quiet, so the pair reads as "real people / everything else" at a glance. */
.psx-kpi-lead b { font-size: 1.35em; }
.psx-scope-note { font-size: var(--t-xs); margin: 6px 0 var(--s3); }
.psx-sdot { position: absolute; top: -3px; inset-inline-start: 50%;
  transform: translateX(-50%); width: 5px; height: 5px; border-radius: 50%;
  background: var(--psx-good); }
.psx-spark-x { display: flex; justify-content: space-between; margin-top: 6px;
  font-size: 10.5px; color: var(--ink-soft); }

/* ── hour-by-hour drill-down ───────────────────────────────────────────────
   Each day column is a button. It has to keep looking exactly like the bar it
   replaced — a chart that sprouts button chrome reads as a form — so the reset
   is deliberate and the only affordance is the cursor, a hover lift and a
   filled state once open. */
.psx-scol-btn { appearance: none; background: none; border: 0; padding: 0;
  cursor: pointer; font: inherit; color: inherit; }
.psx-scol-btn:hover .psx-sbar { opacity: 1; }
.psx-scol-btn.is-open .psx-sbar { opacity: 1; background: var(--brand, var(--seal)); }
.psx-scol-btn:focus-visible { outline: 2px solid var(--seal); outline-offset: 2px;
  border-radius: 2px; }
.psx-hours-hint { margin: 6px 0 0; }

.psx-hours { margin-top: var(--s3); padding-top: var(--s3);
  border-top: 1px solid var(--line); }
.psx-hours-h { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s2); margin-bottom: var(--s2); }
.psx-hours-title { margin: 0; font-size: var(--t-sm); }
.psx-hours-close { appearance: none; background: none; border: 0; cursor: pointer;
  font-size: var(--t-sm); line-height: 1; padding: 4px 6px; border-radius: 4px;
  color: var(--ink-soft); }
.psx-hours-close:hover { color: var(--ink); background: var(--surface-2, transparent); }
.psx-hours-bars { display: flex; align-items: flex-end; gap: 2px; height: 72px; }
.psx-hcol { flex: 1; min-width: 2px; height: 100%; display: flex; align-items: flex-end; }
.psx-hbar { display: block; width: 100%; min-height: 2px; border-radius: 2px 2px 0 0;
  background: var(--seal); opacity: .7; }
.psx-hcol:hover .psx-hbar { opacity: 1; }
/* An hour with nobody in it is a fact, so it keeps a visible baseline rather
   than vanishing and leaving a gap that reads as a rendering fault. */
.psx-hbar.is-empty { opacity: .18; }
/* Four labels across 24 columns; evenly spread rather than under their bar,
   which at this width would overlap. */
.psx-hours-x { display: flex; justify-content: space-between; margin-top: 6px;
  font-size: 10.5px; color: var(--ink-soft); }
.psx-hours-note { margin: 6px 0 0; }

@media (max-width: 760px) {
  .psx-funnel, .psx-kpis { grid-template-columns: repeat(2, 1fr); }
  .psx-grid { grid-template-columns: 1fr; }
  .psx-card.psx-wide { grid-column: auto; }
  .psx-path { max-width: 46vw; }
}

/* "Before you bid" — the decision_info fields that were extracted and stored
   since the schema existed and rendered nowhere. Values are one-liners
   ("מחיר 70%, איכות 30%"), so a tight two-column list reads better than a
   paragraph per field. Logical properties throughout: this block is RTL on IL,
   which is where most of its content lives. */
.t-bid-dl { display: grid; gap: var(--s2) var(--s3); margin: 0; }
.t-bid-dl > div { display: grid; grid-template-columns: minmax(9rem, auto) 1fr;
  gap: var(--s2) var(--s3); align-items: baseline; }
.t-bid-dl dt { font-size: var(--t-xs); font-weight: 700; color: var(--muted);
  text-align: start; }
.t-bid-dl dd { margin: 0; font-size: var(--t-sm); color: var(--ink); }
@media (max-width: 560px) {
  .t-bid-dl > div { grid-template-columns: 1fr; gap: 2px; }
}

/* ========================================================================
   T-ILSEARCH -- public search (/search) and public tender pages (/t/ID).
   Every selector is namespaced .ps-* / .pt-* and these pages carry their own
   shell, so nothing here can reach an existing screen -- which is what keeps
   the flag-off byte-identity gate green. Michraziya tokens only: search-results
   anatomy, no borrowed identity.

   SPECIFICITY NOTE: the pill's inner control is an <input> and a
   <button type=submit>, and two global rules outrank a bare class --
   `input:focus` (which drew a RECTANGULAR 2px outline inside the 999px pill,
   the misalignment this block fixes) and `body.il-pub button[type=submit]`
   (which forced an 8px radius and the T-ILBTN orange underline onto the round
   submit). So the control rules below are scoped `body.ps-body ...` to win
   honestly, rather than reaching for !important.
   ======================================================================== */
.ps-body { background: var(--paper); color: var(--ink); margin: 0; font-family: var(--font-body); }

/* A quiet wash behind the hero, so the pill sits on something rather than
   floating on flat paper. */
.ps-body::before {
  content: ""; position: fixed; inset: 0 0 auto; height: 420px; z-index: -1;
  background:
    radial-gradient(120% 90% at 50% -20%, color-mix(in srgb, var(--seal) 9%, transparent), transparent 70%),
    linear-gradient(var(--surface), var(--paper));
}

.ps-topbar { border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 85%, transparent);
  backdrop-filter: saturate(1.4) blur(8px); position: sticky; top: 0; z-index: 5; }
.ps-topbar-inner { max-width: 1080px; margin: 0 auto; padding: 10px 22px;
  display: flex; align-items: center; gap: 18px; }
.ps-auth { margin-inline-start: auto; display: flex; align-items: center; gap: 14px; }
.ps-login { color: var(--ink-soft); font-size: 14px; text-decoration: none;
  padding: 6px 4px; border-radius: 8px; transition: color .12s ease; }
.ps-login:hover { color: var(--ink); text-decoration: none; }
body.ps-body .ps-signup { font-size: 14px; font-weight: 500; padding: 7px 16px;
  border-radius: var(--r-control); background: var(--btn); color: #fff; text-decoration: none;
  border: 0; box-shadow: inset 0 -2.5px 0 var(--btn-line);
  transition: background .12s ease, transform .12s ease; }
body.ps-body .ps-signup:hover { background: var(--btn-hover); }
body.ps-body .ps-signup:active { transform: translateY(1px); }

/* Our own wordmark, with the accent full stop from the approved mock. */
.ps-wordmark { font-family: var(--font-display); color: var(--seal); text-decoration: none; }
.ps-wordmark-lg { font-size: clamp(40px, 7.5vw, 62px); margin: 0 0 8px; display: block;
  letter-spacing: -.015em; }
.ps-wordmark-sm { font-size: 21px; flex: none; }
.ps-dot { color: var(--accent); }

.ps-main { padding: 24px 22px 60px; }
/* TenderScan's page container, to the pixel: .ts-shell is
   `max-width: 1080px; margin-inline: auto; padding-inline: 22px`, and it wraps
   every page of that site — the market report included.
   IL had the number already, on .ps-topbar-inner, but only there: <main> had no
   cap at all, so on a 1280 screen the authority grid ran to 1221px while the
   header above it stopped at 1080 and the footer below it at 720. Content wider
   than its own chrome is what reads as "full width" and unfinished. */
.ps-wide { max-width: 1080px; margin-inline: auto; }
/* The prose pages on this shell — terms, privacy, contact. They are read, not
   scanned, so they take a measure rather than the 1080px grid container: at
   full width a policy line runs past 140 characters and the eye loses the
   return sweep. 760px lands around 75 Hebrew characters at this size. */
.ps-doc { max-width: 760px; margin-inline: auto; }
/* These pages arrived from base.html, where .blog-article supplied its own
   card. On this shell it sits directly on the page ground, so it needs the
   surface and the border it used to inherit — and both come from tokens, which
   is what makes the dark theme apply to them for free. */
.ps-doc .blog-article { background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s6) var(--s5); }
.ps-doc .crumbs { margin-bottom: var(--s4); }
@media (max-width: 640px) {
  .ps-doc .blog-article { padding: var(--s5) var(--s4); }
}
/* The empty state is two bands rather than one long column. The first is the
   search and nothing else, sized so it fills the screen a visitor lands on;
   the second starts below it, behind a rule. Grid-centring the whole <main>
   (what this did before) meant every block added underneath dragged the search
   box upward — the page's only real control losing ground to its own
   footnotes. */
.ps-main-empty { display: block; padding-top: 0; }
/* Sized so the browse section's rule only PEEKS at the bottom of a laptop
   screen: enough to say "there is more here", not enough to pull the eye off
   the box. Measured at 1280x900 and 1280x720 — the band ends at ~81% of the
   viewport in both, because the padding and the min-height are both in vh. */
.ps-hero-wrap { display: grid; place-items: center; min-height: 74vh;
  padding-top: 7vh; }
.ps-hero { width: min(680px, 100%); text-align: center; }
.ps-tagline { color: var(--ink-soft); margin: 0 0 30px; font-size: 16.5px; }

/* ---- the query field ----------------------------------------------------
   Squared off, on the product's own radii — a search pill reads as somebody
   else's search box. The frame takes --r-card and the submit takes
   --r-control, the same radius every other button in the product uses, so the
   field belongs to this theme rather than to a search engine. The focus ring
   is a box-shadow on the FRAME (box-shadow follows border-radius; an outline
   on the inner input does not). */
.ps-form { display: flex; align-items: center; gap: 6px; width: 100%;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: var(--r-card);
  padding: 5px 5px 5px 6px;
  box-shadow: 0 1px 2px rgba(28, 43, 51, .04), 0 6px 18px -10px rgba(28, 43, 51, .18);
  transition: box-shadow .16s ease, border-color .16s ease; }
.ps-form:hover { border-color: var(--line-hover);
  box-shadow: 0 1px 2px rgba(28, 43, 51, .05), 0 10px 26px -12px rgba(28, 43, 51, .24); }
.ps-form:focus-within { border-color: var(--seal);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--seal) 13%, transparent),
              0 10px 30px -12px rgba(28, 43, 51, .28); }

/* The magnifier is decorative — the input has its own aria-label. */
.ps-form-icon { flex: none; display: grid; place-items: center; inline-size: 22px;
  color: var(--ink-soft); margin-inline-start: 10px; transition: color .16s ease; }
.ps-form:focus-within .ps-form-icon { color: var(--seal); }
.ps-form-icon svg { display: block; }

body.ps-body .ps-input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  font: inherit; font-size: 16.5px; padding: 11px 10px; color: var(--ink);
  border-radius: 6px; box-shadow: none; width: auto; }
body.ps-body .ps-input:hover, body.ps-body .ps-input:focus { border: 0; outline: 0; box-shadow: none; }
body.ps-body .ps-input::placeholder { color: var(--ink-soft); opacity: .75; }
/* Chrome draws its own clear affordance in a search field; ours is the frame. */
body.ps-body .ps-input::-webkit-search-decoration,
body.ps-body .ps-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

/* align-self: stretch, not a hand-tuned height — the button then fills the
   frame's content box exactly, so the two stay flush if the font or padding
   ever changes. */
body.ps-body .ps-form .ps-submit { flex: none; align-self: stretch;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-control); cursor: pointer;
  background: var(--btn); color: #fff; font: inherit; font-weight: 500; font-size: 14.5px;
  padding: 0 26px; line-height: 1.2; box-shadow: inset 0 -2.5px 0 var(--btn-line);
  transition: background .12s ease, transform .12s ease; }
body.ps-body .ps-form .ps-submit:hover { background: var(--btn-hover); }
body.ps-body .ps-form .ps-submit:active { transform: translateY(1px); }
body.ps-body .ps-form .ps-submit:focus-visible { outline: 2px solid var(--seal); outline-offset: 3px; }

/* 35px tall like the login button beside it, so the bar is the same 55px on
   a results page as on the front door and the nav does not drop 5px when
   the results land. */
.ps-form-compact { max-width: 560px; padding: 0 3px 0 4px;
  box-shadow: 0 1px 2px rgba(28, 43, 51, .04); }
.ps-form-compact .ps-form-icon { inline-size: 18px; margin-inline-start: 8px; }
body.ps-body .ps-form-compact .ps-input { font-size: 14.5px; padding: 5px 8px; }
body.ps-body .ps-form.ps-form-compact .ps-submit { padding: 0 18px; font-size: 13.5px;
  border-radius: 6px; }

/* ---- example queries ----------------------------------------------------
   Suggestion pills, not buttons: no hard border, a faint seal wash, and they
   lift a hair on hover. Quiet enough to ignore, inviting enough to tap. */
.ps-examples { margin: 22px 0 0; display: flex; flex-wrap: wrap; gap: 8px;
  justify-content: center; align-items: center; }
.ps-examples-label { color: var(--ink-soft); font-size: 12.5px; letter-spacing: .01em;
  margin-inline-end: 2px; }
.ps-example { font-size: 13.5px; padding: 7px 14px; border-radius: 999px;
  border: 1px solid transparent;
  background: color-mix(in srgb, var(--seal) 6%, var(--surface));
  color: var(--ink); text-decoration: none; line-height: 1.3;
  box-shadow: 0 1px 2px rgba(28, 43, 51, .04);
  transition: background .14s ease, color .14s ease, border-color .14s ease,
              transform .14s ease, box-shadow .14s ease; }
.ps-example:hover { background: var(--seal-wash); color: var(--seal);
  border-color: color-mix(in srgb, var(--seal) 22%, transparent);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -6px rgba(28, 43, 51, .3); }
.ps-example:active { transform: translateY(0); }
/* Sits directly under the search box now, so it takes the box's own rhythm
   rather than the generous gap it needed at the foot of the hero. */
.ps-counts { margin: 14px 0 0; color: var(--ink-soft); font-size: 13px; }

.ps-shell { max-width: 720px; margin: 0 auto; }

/* Interpreted entities: how the query was read, one tap to correct. */
.ps-chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 4px 0 14px; }
.ps-chip { display: inline-flex; align-items: center; gap: 7px; font-size: 13px;
  padding: 5px 12px; border-radius: 999px; text-decoration: none; font-weight: 500;
  background: color-mix(in srgb, var(--seal) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--seal) 26%, transparent); color: var(--seal);
  transition: background .14s ease, border-color .14s ease; }
.ps-chip:hover { background: var(--seal-wash);
  border-color: color-mix(in srgb, var(--seal) 42%, transparent); }
.ps-chip-x { opacity: .55; font-size: 11px; }
.ps-chip:hover .ps-chip-x { opacity: 1; }
/* WHERE is one colour, WHAT is another - the same split as TenderScan. A
   region and a place both read as "where" to the reader (one filters on the
   extracted region, the other on the publisher's name, which is the data's
   business, not theirs), so both take the accent; categories, the kind and
   the stage keep the default. */
.ps-chip-region, .ps-chip-place, .ps-chip-buyer, .ps-chip-publisher {
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent-ink, color-mix(in srgb, var(--accent) 70%, var(--ink))); }
.ps-chip-region:hover, .ps-chip-place:hover, .ps-chip-buyer:hover, .ps-chip-publisher:hover {
  background: color-mix(in srgb, var(--accent) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 48%, transparent); }

/* align-items: center, or every control stretches to the tallest thing in
   the row - the segmented control measured 51px against 35px pills. */
.ps-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; padding: 0 0 12px;
  border-bottom: 1px solid var(--line); margin-bottom: 14px; }

/* The count and the sort share one line above the results: the sort describes
   the set the count just named. In RTL the count keeps the start (right) and
   the control sits at the end (left), against the edge the cards stop at.
   A flex row, exactly as TenderScan does it — the first version floated the
   form, which takes it out of flow: it shared no baseline with the count and
   the margins below collapsed differently, so it sat crooked. */
.ps-meta-row { display: flex; align-items: baseline;
  justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.ps-meta { color: var(--ink-soft); font-size: 13px; margin: 0 0 16px; }
.ps-meta-row .ps-meta { margin-bottom: 0; }
/* Type and sort are one group: both describe the set the count just named, so
   they share a line and wrap together rather than sitting at opposite ends of
   the row and breaking onto separate lines as the window narrows. */
.ps-meta-controls { display: flex; align-items: center; flex-wrap: wrap;
  gap: 4px 18px; }
/* The dashboard's standing-register section. Set apart from the match queue by
   a rule and a heading rather than by colour: it is not a lesser class of
   opportunity, it is a different kind of one, and the cards inside are the
   same cards. */
.match-registers { margin-block-start: var(--s6); padding-block-start: var(--s5);
  border-block-start: 1px solid var(--line); }
.mreg-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
  margin-block-end: var(--s4); }
.mreg-head h2 { font-size: var(--t-lg); margin: 0; }
.mreg-head p { margin: 0; font-size: var(--t-sm); }
.mreg-all { margin-inline-start: auto; font-size: var(--t-sm); color: var(--seal);
  text-decoration: none; white-space: nowrap; }
.mreg-all:hover { text-decoration: underline; }

/* The notice-type facet. Same weight as the sort control beside it — both
   describe the set the count just named, and neither is the thing the page is
   for. Quiet enough that a search with no registers loses nothing by not
   having it, which is the point of it being contextual. */
.ps-facet { display: flex; align-items: center; gap: 8px; flex: none;
  margin-block-end: 16px; }
/* Names the axis. Three bare words — הכל / מכרזים / מאגרים — do not say what
   is being switched between; one short label does, and costs a row nothing. */
.ps-facet-l { font-size: 12.5px; color: var(--ink-soft); }
.ps-facet-n { font-variant-numeric: tabular-nums; opacity: .7;
  margin-inline-start: 4px; }
.ps-sort { display: flex; align-items: center; gap: 6px; flex: none;
  margin-block-end: 16px; }
.ps-sort-l { font-size: 12.5px; color: var(--ink-soft); }
/* Quiet: a preference about a list, not the thing the page is for. */
.ps-sort-s { font: inherit; font-size: 12.5px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 8px; padding: 4px 8px; cursor: pointer; }
.ps-sort-s:hover { border-color: var(--line-hover); }
.ps-sort-s:focus-visible { outline: 2px solid var(--seal); outline-offset: 2px; }
.ps-sort-go { font: inherit; font-size: 12.5px; margin-inline-start: 6px;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink); cursor: pointer; }
@media (max-width: 560px) {
  /* Stacked, and the control keeps the start edge so it lines up with the
     cards rather than hanging off the far side of a narrow screen. */
  .ps-meta-row { display: block; }
  .ps-meta-row .ps-meta { margin-bottom: 4px; }
}
.ps-timing { opacity: .7; }
.ps-note { color: var(--seal); }
.ps-results { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }

/* The decision-strip card. */
.ps-card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 15px 17px; transition: border-color .14s ease, box-shadow .14s ease,
  transform .14s ease; }
/* This is the lift Bidvane started with and then dropped: on a page of twenty
   cards you pass over on the way down, a card that jumps and throws a deep
   shadow reads as an event. The border and a shallow shadow say "interactive"
   without the row moving under the cursor. */
.ps-card:hover { border-color: var(--line-hover);
  box-shadow: 0 2px 8px -4px rgba(28, 43, 51, .18); }

/* ── The whole card is the link ──────────────────────────────────────────────
   A result is one object and one decision, so the target is the object, not
   the eight words of its title. A stretched pseudo-element on the real anchor
   rather than a click handler on the <li>: the link stays a link, so
   middle-click, "copy link address", open-in-new-tab and crawlers all keep
   working, and no JavaScript is involved. */
.ps-card { position: relative; cursor: pointer; }
.ps-card-title a::after { content: ""; position: absolute; inset: 0; }
/* Anything else clickable has to sit ABOVE that overlay or it stops being
   reachable. These two go to the same notice, so the overlay swallowing them
   would still take the reader to the right place — but their hover underline
   would never fire, and a link that does not answer the cursor reads as
   broken. */
.ps-card .ps-fact-link, .ps-card .ps-thresholds-more { position: relative; z-index: 1; }
.ps-card.is-closed { opacity: .72; }
.ps-card-source { font-size: 12.5px; color: var(--ink-soft); display: flex;
  flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 3px; }
.ps-card-pub { font-weight: 500; color: var(--ink); }
.ps-sep { opacity: .4; }
.ps-badge-enriched { font-size: 11.5px; padding: 2px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--seal) 11%, var(--surface)); color: var(--seal);
  border: 1px solid color-mix(in srgb, var(--seal) 22%, transparent); }
/* Notice type on a public result. Same dashed edge as the register's chip
   elsewhere, so "you join this rather than bid on it" looks the same wherever
   it is said. Sits in the muted source line, not competing with the title. */
.ps-badge-kind { font-size: 11.5px; padding: 1px 8px; border-radius: 999px;
  border: 1px dashed color-mix(in srgb, var(--seal) 40%, var(--line));
  background: color-mix(in srgb, var(--seal) 6%, transparent);
  color: var(--seal); font-weight: 600; }
.ps-card-title { margin: 2px 0 6px; font-size: 17.5px; line-height: 1.35;
  font-weight: 500; font-family: var(--font-body); }
.ps-card-title a { color: var(--seal); text-decoration: none; }
.ps-card-title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.ps-card-title a:visited { color: color-mix(in srgb, var(--seal) 72%, #6b4b8a); }
.ps-card-snip { margin: 0 0 11px; font-size: 14px; line-height: 1.6; color: var(--ink-soft); }

.ps-facts { display: flex; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 10px; }
.ps-fact { flex: 1 1 0; min-width: 108px; padding-inline: 12px;
  border-inline-start: 1px solid var(--line); }
.ps-fact:first-child { padding-inline-start: 0; border-inline-start: 0; }
.ps-fact-label { display: block; font-size: 11px; color: var(--ink-soft); margin-bottom: 2px;
  letter-spacing: .015em; }
.ps-fact-value { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.ps-fact.is-urgent .ps-fact-value { color: var(--accent-ink); }
.ps-fact.is-muted .ps-fact-value { color: var(--ink-soft); font-weight: 500; }
.ps-fact-link { color: var(--seal); text-decoration: none; }
.ps-fact-link:hover { text-decoration: underline; text-underline-offset: 3px; }

.ps-card-thresholds { margin: 10px 0 0; font-size: 12.5px; color: var(--ink-soft);
  line-height: 1.6; display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; }
.ps-thresholds-label { font-weight: 700; color: var(--ink); }
.ps-thresholds-more { color: var(--seal); text-decoration: none; }
.ps-thresholds-more:hover { text-decoration: underline; text-underline-offset: 3px; }

.ps-zero { padding: 44px 0; text-align: center; }
.ps-zero h2 { font-family: var(--font-display); color: var(--ink); margin: 0 0 8px;
  font-size: 21px; font-weight: 400; }
.ps-zero p { color: var(--ink-soft); margin: 0; }

/* The page row, as Bidvane draws it. Ten outlined pills in a line was a row of
   buttons competing with the results above them; these are quiet until you
   reach for one, and a rule separates the row from the last card so it stops
   looking like a twenty-first. */
.ps-pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 2px; margin-top: 32px; padding-top: 16px; border-top: 1px solid var(--line); }
/* Every page carries a transparent border, so the one that lights up changes
   colour without changing size and the row never shifts by a pixel. */
.ps-page { min-width: 34px; text-align: center; padding: 7px 9px; border-radius: 8px;
  border: 1px solid transparent; background: transparent; color: var(--ink-soft);
  text-decoration: none; font-size: 13px; font-variant-numeric: tabular-nums;
  transition: background .12s ease, color .12s ease, border-color .12s ease; }
.ps-page:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); color: var(--ink); }
/* The current page is marked, not shouted. A solid seal-blue fill made "you
   are here" the loudest thing on the page; the button treatment belongs to
   things you press to make something happen, and this is not one of them. */
.ps-page.is-current { background: var(--surface); color: var(--ink); font-weight: 600;
  border-color: var(--line-hover); }
.ps-page.is-current:hover { background: var(--surface); }
/* The two that are words, not numbers: pushed away from the digits so they
   read as directions rather than as page "0" and page "11". */
.ps-page-prev { margin-inline-end: 12px; }
.ps-page-next { margin-inline-start: 12px; }
.ps-page-prev, .ps-page-next { color: var(--seal); font-weight: 500; }
/* The ellipsis is a gap in the sequence, not a page you can click — it gets
   the row's spacing and none of its affordance. */
.ps-page-gap { font-size: 13px; color: var(--line-hover); padding-inline: 4px; user-select: none; }

.ps-advanced { margin: 32px 0 0; font-size: 13.5px; color: var(--ink-soft); }
.ps-advanced summary { cursor: pointer; color: var(--seal); }

/* Sponsored units: native and result-shaped. The label is what makes it
   honest -- bold, small, above the title, never omitted. */
/* Spacing on BOTH sides, because a sponsored unit sits between things the
   reader is actually reading — the meta row and the results above the fold,
   the alert form and the footer links below it. It had margin: 0, so it butted
   straight against them at both appearances and read as part of the results
   rather than as a break from them. Measured on prod: 0px above and 0px below,
   on a 53px box. 22px is the page's own rhythm — a touch more than the 14px
   between the filter rows, since this is a change of subject rather than the
   next control. */
.ps-ad { background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 15px 17px; margin: 22px 0; }
/* An unfilled unit collapses. :empty cannot do it — the box always holds the
   label and the <ins>, so the rule this replaces could never once have fired —
   and neither can a height test in CSS. AdSense marks a slot it could not fill,
   which is the one moment we can be certain there is nothing to show; :has()
   re-evaluates, so a unit that fills later still appears, label and all. */
.ps-ad:has(ins[data-ad-status="unfilled"]) { display: none; }
.ps-ad-label { font-size: 11.5px; font-weight: 700; color: var(--ink); display: block; margin-bottom: 3px; }

@media (prefers-reduced-motion: reduce) {
  .ps-example, .ps-card, body.ps-body .ps-form .ps-submit, body.ps-body .ps-signup,
  .ps-form { transition: none; }
  .ps-example:hover, .ps-card:hover { transform: none; }
}

@media (max-width: 640px) {
  .ps-topbar-inner { flex-wrap: wrap; gap: 10px; }
  .ps-form-compact { order: 3; flex-basis: 100%; max-width: none; }
  body.ps-body .ps-input { font-size: 16px; }
  body.ps-body .ps-form .ps-submit { padding: 0 18px; }
  .ps-fact { flex-basis: 50%; border-inline-start: 0; padding-inline: 0; margin-bottom: 6px; }
}

/* ---- typeahead ----------------------------------------------------------
   The list hangs off the field and shares its curvature, so the two read as one
   object rather than a panel that happens to be nearby. Hidden by default and
   only ever revealed by JS, so a no-JS visitor sees the plain form. */
.ps-form { position: relative; }
.ps-suggest { position: absolute; inset-inline: 0; top: calc(100% + 8px);
  margin: 0; padding: 6px; list-style: none; z-index: 20;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: 0 18px 40px -18px rgba(28, 43, 51, .45), 0 2px 6px rgba(28, 43, 51, .05);
  max-height: 340px; overflow-y: auto; }
.ps-suggest[hidden] { display: none; }
.ps-suggest-item { display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 9px 14px; border-radius: 6px; font-size: 15px; color: var(--ink);
  transition: background .1s ease; }
.ps-suggest-item:hover, .ps-suggest-item.is-active { background: var(--seal-wash); }
.ps-suggest-item.is-active { color: var(--seal); }
.ps-suggest-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
/* The kind label is the honest part: it says WHY the row is being offered —
   a category, an authority, a region — so picking one is never a guess. */
.ps-suggest-kind { flex: none; font-size: 11.5px; color: var(--ink-soft);
  background: color-mix(in srgb, var(--seal) 7%, var(--surface));
  border: 1px solid var(--line); border-radius: 4px; padding: 2px 9px; }
.ps-suggest-item.is-active .ps-suggest-kind {
  border-color: color-mix(in srgb, var(--seal) 28%, transparent); color: var(--seal); }
/* The Tab affordance, on the row it applies to. Tab-completing is invisible
   unless something says so, and the logged-in box has said so all along with
   the same key cap — the two surfaces should teach one gesture rather than each
   keeping it a secret in its own way. */
.ps-suggest-tab { flex: none; font-family: var(--font-body); font-size: 10.5px;
  font-weight: 600; letter-spacing: .04em; color: var(--ink-soft);
  background: color-mix(in srgb, var(--ink) 6%, var(--surface));
  border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px;
  padding: 1px 6px; }
.ps-suggest-item.is-active .ps-suggest-tab { color: var(--seal);
  border-color: color-mix(in srgb, var(--seal) 28%, transparent); }
/* An operator row carries a symbol, and a symbol in a proportional face beside
   Hebrew is easy to miss. Only the operator half is monospaced — the field name
   it is attached to stays in the body face, so the row still reads as a
   sentence. */
.ps-suggest-item[data-op] .ps-suggest-label { font-family: var(--font-mono,
  ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); font-size: 14px; }
.ps-form-compact .ps-suggest-item { font-size: 14px; padding: 7px 12px; }

/* ---- the advanced-search hint (empty state) -----------------------------
   It lives where someone is deciding HOW to search, rather than at the foot of
   results they are already reading. Closed by default: a hint, not a feature
   tour. */
.ps-advanced-hint { margin: 18px auto 0; max-width: 640px; text-align: center; }
/* No pill. The dashed capsule was sized for a six-word abstraction and the line
   now carries a query — inside a 306px pill that reads as a cramped label
   rather than a sentence, and the border competes with the search box directly
   above it for the same "type here" affordance. Plain text, the way TenderScan
   shows it: the query chip and the coloured call to action are affordance
   enough, and the line can wrap to two without the frame having to stretch. */
.ps-advanced-hint summary { display: inline-flex; flex-wrap: wrap;
  align-items: baseline; justify-content: center; gap: 4px 8px;
  cursor: pointer; list-style: none; font-size: 12.5px; line-height: 1.5;
  color: var(--ink-soft); padding: 2px 4px; border-radius: 8px;
  transition: color .14s ease; }
.ps-advanced-hint summary::-webkit-details-marker { display: none; }
.ps-advanced-hint summary:hover { color: var(--ink); }
.ps-advanced-hint summary:focus-visible { outline: 2px solid var(--seal);
  outline-offset: 2px; }
/* The query, drawn as code — the one part of the line that is meant to be
   copied rather than read. Monospace and the seal colour say "this is the
   thing", which is the whole job of putting an example here. */
/* Same treatment as .search-help code, and for the same reason: this teaser is
   a Hebrew BQL query, and ui-monospace/SFMono/Menlo carry no Hebrew glyphs, so
   the browser fell back per character to a default serif. It read as a
   different, older typeface sitting inside the sentence. The examples panel was
   moved to the UI face for this exact reason; this one line was missed, which
   is why the teaser and the examples it advertises did not match.
   11.5 -> 13px comes with it: 11.5 was sized for a monospace face. */
.ps-hint-q { font-family: var(--font-body); font-size: 13px; font-weight: 500;
  color: var(--seal);
  background: color-mix(in srgb, var(--seal) 9%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--seal) 16%, transparent);
  padding: 1px 6px; border-radius: 5px; white-space: nowrap;
  /* The query mixes a Hebrew field name with Latin operators; plaintext lets
     each run lay out in its own direction, as the examples panel does. */
  unicode-bidi: plaintext; }
.ps-hint-cta { color: var(--seal); font-weight: 600; white-space: nowrap; }
.ps-advanced-hint summary:hover .ps-hint-cta { text-decoration: underline; }
.ps-advanced-hint[open] summary { color: var(--ink); }
/* The panel carries .search-help too, so its insides are styled by the app's
   own help-popover rules — one panel, two surfaces. Only the framing is
   re-stated here: it OVERLAYS what follows rather than displacing it (opening a
   hint must not shove the page under the reader), and it spans the hint's width
   instead of the popover's fixed 440px, so `width: auto` is load-bearing. */
.ps-advanced-hint { position: relative; }
.ps-advanced-panel { position: absolute; inset-inline: 0; width: auto;
  /* bottom: auto undoes the app popover's narrow-screen rule, which docks it to
     the bottom of the viewport. Left in, top AND bottom would both be set and
     the panel would be squashed to a 30px sliver. */
  top: calc(100% + 10px); bottom: auto;
  z-index: 15; text-align: start; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: 0 18px 40px -18px rgba(28, 43, 51, .45), 0 2px 6px rgba(28, 43, 51, .05); }
/* Once there is room, spill past the 520px hint that opens it: two columns plus
   four example lines are 390px tall at the hint's width and run under the fold.
   The negative inset spreads symmetrically in both writing directions, where a
   left/translate pair would need undoing under RTL — but only above the width
   where it fits, or it would push the page into horizontal scroll. */
@media (min-width: 760px) {
  .ps-advanced-panel { inset-inline: -70px; }
}

/* Each example is a paste target wrapping the app's <code> chip. The anchor is
   only there to carry the link and the paste — the chip does the drawing, so
   the anchor adds no box of its own. */
/* The compact layout for the PUBLIC hint panel only. The app's help panel
   keeps the two-column grid: it opens in a modal with room, while this one
   hangs under the search box on the first screen, where sixteen rows of help
   push the page the reader came for below the fold. Same content, flowing
   rows: a label, then the chips or the operators, wrapping as they need to. */
.ps-advanced-panel.is-compact .sh-row { display: flex; flex-wrap: wrap;
  align-items: baseline; gap: 4px 6px; margin: 0 0 6px; font-size: 12.5px;
  color: var(--ink-soft); line-height: 1.7; }
.ps-advanced-panel.is-compact .sh-lab { font-weight: 600; color: var(--ink);
  margin-inline-end: 2px; }
/* An operator and its meaning travel together — they must never wrap apart,
   or the panel reads as a list of symbols followed by a list of words. */
.ps-advanced-panel.is-compact .sh-op { display: inline-flex; align-items: baseline;
  gap: 4px; white-space: nowrap; }
.ps-advanced-panel.is-compact .sh-op + .sh-op { margin-inline-start: 2px; }
.ps-advanced-panel.is-compact .sh-row-ex { gap: 5px; }
.ps-advanced-panel.is-compact .sh-tip { margin: 2px 0 0; }

.ps-advanced-panel .sh-ex .ps-adv-ex { display: inline-block; text-decoration: none;
  padding: 0; border-radius: 5px; transition: none; }
.ps-advanced-panel .sh-ex .ps-adv-ex:focus-visible { outline: 2px solid var(--seal);
  outline-offset: 2px; }
.ps-advanced-panel .sh-ex .ps-adv-ex.is-pasted code {
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  border-color: var(--accent); }

/* ---- filter bar ---------------------------------------------------------
   Status is a segmented control: two options, both visible, one tap. Real
   radios underneath so it submits with JS off. */
.ps-seg { display: inline-flex; align-items: center; padding: 2px; gap: 2px; border-radius: 999px;
  background: color-mix(in srgb, var(--seal) 7%, var(--surface));
  border: 1px solid var(--line); }
/* 31px tall, the same as the menu pills beside it (6px + text + 6px + the
   border): 2px of track and 4px of option. It was 37px, and read as a
   bigger control than the menus it sits with. */
.ps-seg-opt { position: relative; display: inline-flex; align-items: center;
  cursor: pointer; font-size: 13px; color: var(--ink-soft); padding: 4px 13px;
  border-radius: 999px; transition: background .14s ease, color .14s ease; }
.ps-seg-opt input { position: absolute; opacity: 0; pointer-events: none;
  width: 1px; height: 1px; margin: 0; }
.ps-seg-opt:hover { color: var(--ink); }
.ps-seg-opt.is-on { background: var(--surface); color: var(--seal); font-weight: 500;
  box-shadow: 0 1px 3px rgba(28, 43, 51, .12); }
.ps-seg-opt:focus-within { outline: 2px solid color-mix(in srgb, var(--seal) 45%, transparent);
  outline-offset: 1px; }
.ps-seg-go { margin-inline-start: 8px; }

/* Selects: our own chevron, so the control matches the pills instead of
   inheriting the OS dropdown look. */
.ps-filter { position: relative; display: inline-flex; align-items: center; }
body.ps-body .ps-filter select { appearance: none; -webkit-appearance: none;
  font: inherit; font-size: 13px; color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: 999px;
  padding-block: 6px; padding-inline: 15px 34px;
  background: var(--surface); width: auto; cursor: pointer;
  transition: border-color .14s ease, color .14s ease, background .14s ease; }
body.ps-body .ps-filter select:hover { color: var(--ink);
  border-color: color-mix(in srgb, var(--seal) 35%, transparent); }
body.ps-body .ps-filter select:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--seal) 45%, transparent);
  outline-offset: 1px; border-color: var(--seal); }
/* A set filter is state, so it reads as selected rather than as a default. */
body.ps-body .ps-filter.is-set select { color: var(--seal); font-weight: 500;
  background: color-mix(in srgb, var(--seal) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--seal) 30%, transparent); }
.ps-filter::after { content: ""; position: absolute; inset-inline-end: 14px;
  width: 8px; height: 8px; pointer-events: none;
  border-inline-end: 1.6px solid currentColor; border-block-end: 1.6px solid currentColor;
  color: var(--ink-soft); transform: translateY(-2px) rotate(45deg); }
.ps-filter.is-set::after { color: var(--seal); }

/* The two menus (תחום, אזור): a pill like the old select, a panel of options
   with a count each. Scoped to the free site's shell like the rest of .ps-. */
/* margin: 0 - the app's generic `details` rule gives every details block a
   16px bottom margin, and a centred row centres the MARGIN box: the pill
   sat 8px above the segmented control beside it. */
body.ps-body .ps-facet { position: relative; margin: 0; }
/* display: flex, not inline-flex: an inline-level summary sits in a line box
   with the strut's descender space under it, so the <details> ran 16px taller
   than its pill and the row centred the box, not the pill - the segmented
   control beside it landed 8px lower. Block-level, the details IS the pill. */
body.ps-body .ps-facet > summary { list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 9px;
  font: inherit; font-size: 13px; color: var(--ink-soft);
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 6px 15px 6px 14px; transition: border-color .14s ease, color .14s ease; }
body.ps-body .ps-facet > summary::-webkit-details-marker { display: none; }
/* Physical right+bottom borders, not inline-end: rotated 45deg those make a
   chevron that points DOWN in either direction. Logical borders flip in RTL
   and drew one pointing left - the old selects had the same quirk. */
body.ps-body .ps-facet > summary::after { content: ""; width: 7px; height: 7px; flex: none;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform .14s ease; }
body.ps-body .ps-facet[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
body.ps-body .ps-facet > summary:hover, body.ps-body .ps-facet[open] > summary {
  border-color: color-mix(in srgb, var(--seal) 35%, transparent); color: var(--ink); }
body.ps-body .ps-facet.is-set > summary { color: var(--seal); font-weight: 500;
  background: color-mix(in srgb, var(--seal) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--seal) 30%, transparent); }
body.ps-body .ps-facet-menu { position: absolute; z-index: 30; top: calc(100% + 6px);
  inset-inline-start: 0; min-width: 240px; max-height: 360px; overflow: auto;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px -12px rgba(28, 43, 51, .28); padding: 6px;
  scrollbar-width: thin; }
body.ps-body .ps-facet-opt { display: flex; align-items: center; gap: 10px; padding: 7px 10px;
  border-radius: 8px; font-size: 13px; color: var(--ink); text-decoration: none;
  cursor: pointer; white-space: nowrap; }
body.ps-body .ps-facet-opt:hover { background: var(--wash); text-decoration: none; }
body.ps-body .ps-facet-opt.is-on { color: var(--seal); font-weight: 600; }
body.ps-body .ps-facet-opt.is-zero { color: var(--ink-soft); opacity: .6; }
body.ps-body .ps-facet-l { flex: 1 1 auto; }
body.ps-body .ps-facet-n { margin-inline-start: 14px; font-size: 12px; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }
body.ps-body .ps-facet-opt.is-on .ps-facet-n { color: var(--seal); }
/* Keyboard: the option under focus reads like the option under the pointer. */
body.ps-body a.ps-facet-opt:focus-visible { outline: none; background: var(--wash);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--seal) 45%, transparent); }
body.ps-body .ps-chips { align-items: center; }
body.ps-body .ps-chips-label { font-size: 12px; color: var(--ink-soft); margin-inline-end: 2px; }
body.ps-body .ps-chips-clear { font-size: 12px; color: var(--ink-soft);
  margin-inline-start: auto; text-decoration: none; }
body.ps-body .ps-chips-clear:hover { color: var(--ink); text-decoration: underline; }
/* On a phone the panel takes the row's width rather than overflowing it. */
@media (max-width: 560px) {
  body.ps-body .ps-facet { position: static; }
  body.ps-body .ps-filters { position: relative; }
  body.ps-body .ps-facet-menu { inset-inline: 0; min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ps-suggest-item, .ps-seg-opt, .ps-advanced-hint summary,
  body.ps-body .ps-filter select { transition: none; }
}

/* ---- footer: the legal minimum, kept quiet --------------------------------
   A search page is not a marketing surface, so this is one small centred row
   rather than the app's full footer. Reuses the app's own strings. */
/* The bottom padding is not decoration: without it the copyright line sits
   flush against the viewport edge, which reads as a page that got cut off
   rather than one that ended. */
.ps-footer { max-width: 720px; margin: 44px auto 0; padding: 18px 22px 40px;
  border-top: 1px solid var(--line); text-align: center; }
.ps-main-empty .ps-footer { margin-top: 34px; }
.ps-footer-links { display: flex; flex-wrap: wrap; gap: 18px; justify-content: center; }
.ps-footer-links a { font-size: 13px; color: var(--ink-soft); text-decoration: none; }
.ps-footer-links a:hover { color: var(--seal); text-decoration: underline;
  text-underline-offset: 3px; }
.ps-footer-rights { margin: 10px 0 0; font-size: 12px; color: var(--ink-soft); opacity: .85; }

/* ---- inline ghost completion -------------------------------------------
   Mirrors the logged-in advanced search: the typed text is transparent (it
   only reserves the width) and the rest of the field name is greyed in right
   after it, so the completion sits exactly where the next character will land.
   The wrapper exists so the overlay can match the input's box precisely. */
.ps-input-wrap { position: relative; flex: 1; min-width: 0; display: flex; }
.ps-ghost { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  display: flex; align-items: center; padding: 11px 10px;
  font: inherit; font-size: 16.5px; white-space: pre; overflow: hidden; }
.ps-ghost-typed { color: transparent; }
.ps-ghost-suffix { color: var(--ink-soft); opacity: .55; }
.ps-ghost-key { display: none; margin-inline-start: 8px; font-family: inherit;
  font-size: 10px; line-height: 1; color: var(--ink-soft); background: var(--paper);
  border: 1px solid var(--line); border-radius: 5px; padding: 3px 6px; }
.ps-ghost.has-suffix .ps-ghost-key { display: inline-flex; align-items: center; }
.ps-form-compact .ps-ghost { padding: 7px 8px; font-size: 14.5px; }
@media (max-width: 560px) { .ps-ghost-key { display: none !important; } }

/* ---- the submit, trimmed ------------------------------------------------
   It was a slab: 26px of padding either side of a word, filling a third of the
   pill. Now it carries the magnifier and keeps the word only where there is
   room for it, so the field itself is what the eye lands on. */
body.ps-body .ps-form .ps-submit { padding: 0 18px; font-size: 14px; gap: 7px;
  grid-auto-flow: column; align-items: center; }
/* No magnifier in the button. The word is the label; a glyph beside it says
   the same thing twice, and TenderScan's button — the one this now matches —
   carries none either.
   The phone rule went with it: it hid the WORD because the icon was carrying
   the meaning, so keeping it would have left an empty dark rectangle. The
   button keeps its word at every width and just loses some padding. */
body.ps-body .ps-form.ps-form-compact .ps-submit { padding: 0 14px; }
@media (max-width: 560px) {
  body.ps-body .ps-form .ps-submit { padding: 0 14px; }
}

/* The way into the product from a page that is deliberately only a search box. */
.ps-footer-product { font-weight: 500; color: var(--seal) !important; }
.ps-footer-product:hover { color: var(--btn-hover) !important; }

/* ---- T-ILSEARCH: the public tender page (/t/ID) --------------------------
   Rebuilt in the house language: the .bh2 card idiom (hairline border, soft
   lift), .bp2-head section headers, tokens for spacing and type, .tnum for
   every figure. Two columns like the app's own detail pages — the reading
   column carries the argument, the aside carries the actions — collapsing to
   one on narrow screens with the facts still high up.                        */
.pt-shell { max-width: 1000px; margin: 0 auto; }
.pt-crumbs { font-size: var(--t-xs); color: var(--ink-soft); margin: 0 0 14px;
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.pt-crumbs a { color: var(--ink-soft); text-decoration: none; }
.pt-crumbs a:hover { color: var(--seal); text-decoration: underline; text-underline-offset: 3px; }

/* ---- hero: status first, because that is the question people arrive with -- */
.pt-head { margin: 0 0 22px; }
.pt-status-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 11px; }
.pt-status { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  font-weight: 600; padding: 4px 12px; border-radius: 999px; letter-spacing: .01em; }
.pt-status::before { content: ""; inline-size: 6px; block-size: 6px; border-radius: 50%;
  background: currentColor; }
.pt-status.is-open { color: var(--live); background: color-mix(in srgb, var(--live) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--live) 24%, transparent); }
.pt-status.is-closed { color: var(--ink-soft); background: var(--paper);
  border: 1px solid var(--line); }
/* "No submission date published" — neither open nor closed, because we do not
   know. Built on --check, the token already carrying this product's amber, so
   it follows the theme like everything else and reads as one statement with the
   .pt-stale warning below it rather than competing with it. */
.pt-status.is-unknown { color: var(--check);
  background: color-mix(in srgb, var(--check) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--check) 30%, transparent); }
.pt-countdown { font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
  padding: 4px 10px; border-radius: 999px; background: var(--paper); border: 1px solid var(--line); }
.pt-countdown.is-urgent { color: var(--accent-ink);
  background: var(--accent-wash); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
.pt-tag { font-size: 12.5px; color: var(--ink-soft); padding: 4px 11px; border-radius: 999px;
  background: var(--paper); border: 1px solid var(--line); }
.pt-tag.is-analysed { color: var(--seal);
  background: color-mix(in srgb, var(--seal) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--seal) 24%, transparent); }

.pt-title { font-family: var(--font-display); font-weight: 400; color: var(--ink);
  font-size: clamp(24px, 3.6vw, 33px); line-height: 1.25; margin: 0 0 9px; max-width: 34ch; }
.pt-sub { font-size: var(--t-xs); color: var(--ink-soft);
  display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.pt-sub-pub { font-weight: 600; color: var(--ink); }

/* ---- the two columns ---------------------------------------------------- */
/* Three children, not two: the reading column is split so that on a phone the
   ACTIONS (official link, documents) can follow the facts immediately, instead
   of sitting below the entire analysis. On desktop both halves return to the
   reading column and the aside spans them. */
.pt-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  column-gap: 26px; row-gap: 0; align-items: start; }
.pt-lead, .pt-body { min-width: 0; grid-column: 1; }
.pt-aside { grid-column: 2; grid-row: 1 / span 2; display: grid; gap: 14px;
  position: sticky; top: 76px; }

/* The tile strip that used to open the reading column is gone: its rows are in
   the at-a-glance panel with the rest of the facts. Only the shared bits are
   kept here — the note under a value, and the two states a deadline has. */
.pt-fact-note { display: block; font-size: 11.5px; font-weight: 500; color: var(--ink-soft);
  margin-top: 2px; }

.pt-unanalysed { background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--ink-soft); border-radius: var(--r-card);
  padding: 13px 16px; margin: 0 0 18px; }
.pt-unanalysed h2 { font-family: var(--font-body); font-weight: 700; font-size: 13.5px;
  color: var(--ink); margin: 0 0 4px; }
.pt-unanalysed p { margin: 0; font-size: var(--t-xs); color: var(--ink-soft); line-height: 1.6; }

/* The stale-notice caution. Deliberately the same shape as .pt-unanalysed and
   NOT a red alert: we do not know the process closed, only that a year-old
   publication carrying no date usually has. The amber start-border is the one
   thing that separates it from an ordinary note. */
.pt-stale { background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid #C98A2E; border-radius: var(--r-card);
  padding: 13px 16px; margin: 0 0 18px; display: block; }
.pt-stale strong { display: block; font-size: 13.5px; color: var(--ink);
  margin: 0 0 4px; }
.pt-stale span { display: block; font-size: var(--t-xs); color: var(--ink-soft);
  line-height: 1.6; }

/* ---- sections ----------------------------------------------------------- */
.pt-block { margin: 0 0 26px; }
.pt-block-head { display: flex; align-items: center; gap: 9px; margin: 0 0 12px;
  padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.pt-block-head h2 { font-family: var(--font-body); font-size: 15px; font-weight: 700;
  color: var(--ink); margin: 0; letter-spacing: -.01em; }
.pt-count { font-size: 11.5px; font-weight: 700; color: var(--seal);
  background: color-mix(in srgb, var(--seal) 10%, var(--surface));
  border-radius: 999px; padding: 1px 8px; }
.pt-summary { margin: 0; font-size: var(--t-sm); line-height: 1.75; color: var(--ink); max-width: 68ch; }

/* Threshold conditions read as a checklist — one gate per row. */
.pt-conds { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.pt-conds li { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: 11px 14px 11px 12px; font-size: 14.5px; line-height: 1.6;
  display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline;
  transition: border-color .14s ease; }
.pt-conds li:hover { border-color: color-mix(in srgb, var(--seal) 26%, transparent); }
/* align-self: center put the dot beside the MIDDLE line of a wrapped
   condition. A checklist bullet marks where the item starts, so it is pinned
   to the first line — the offset is half a line box, which lands it on the
   optical centre of a one-line row too. */
.pt-conds li::before { content: ""; flex: none; align-self: flex-start;
  margin-block-start: .6em;
  inline-size: 6px; block-size: 6px; border-radius: 50%;
  background: color-mix(in srgb, var(--seal) 55%, transparent); }
/* `flex: 1 1 auto` is why long conditions rendered UNDERNEATH their bullet.
   Flex breaks lines on an item's HYPOTHETICAL size, and with basis auto that
   is the text's max-content width — one long sentence is wider than the row,
   so the wrap happened before any shrinking could save it and the text got a
   flex line of its own. min-width: 0 does not help: it licenses shrinking,
   which the algorithm has already decided not to attempt.
   A percentage basis is smaller than the row by construction, so the text
   never triggers the break — while `wrap` still does its actual job, which is
   letting a long value chip drop to its own line. */
.pt-cond-text { flex: 1 1 60%; min-width: 0; }
.pt-cond-value { flex: none; color: var(--seal); font-weight: 700;
  background: color-mix(in srgb, var(--seal) 8%, var(--surface));
  border-radius: 7px; padding: 2px 9px; font-size: 13.5px; }

.pt-cta { display: inline-block; margin: 13px 0 0; font-size: var(--t-xs);
  color: var(--seal); text-decoration: none; font-weight: 500; }
.pt-cta:hover { text-decoration: underline; text-underline-offset: 3px; }

.pt-decision { margin: 0; display: grid; gap: 0; border: 1px solid var(--line);
  border-radius: var(--r-card); overflow: hidden; background: var(--surface); }
.pt-decision > div { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 14px;
  padding: 12px 15px; border-block-end: 1px solid var(--line); }
.pt-decision > div:last-child { border-block-end: 0; }
.pt-decision dt { font-size: 12px; color: var(--ink-soft); font-weight: 600; padding-top: 1px; }
.pt-decision dd { margin: 0; font-size: 14.5px; line-height: 1.65; color: var(--ink); }
/* No .pt-kp-title any more: the points are a block of their own with the same
   <h2> head as every other, rather than a small grey subheading buried inside
   the decision block. */
.pt-kp { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
.pt-kp li { position: relative; padding-inline-start: 20px; font-size: 14.5px;
  line-height: 1.65; color: var(--ink); }
.pt-kp li::before { content: ""; position: absolute; inset-inline-start: 4px; top: .62em;
  inline-size: 7px; block-size: 7px; border-radius: 2px; transform: rotate(45deg);
  background: color-mix(in srgb, var(--accent) 70%, transparent); }

/* ---- aside cards -------------------------------------------------------- */
.pt-card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 15px 16px; box-shadow: 0 1px 2px rgba(28, 43, 51, .04); }
/* Same size and colour as .pt-block-head h2 ("נקודות מפתח"). At 12px in
   ink-soft with wide tracking this read as a field label above a list, not as
   the heading of a panel that carries every fact on the page. */
.pt-card-title { font-family: var(--font-body); font-size: 15px; font-weight: 700;
  color: var(--ink); letter-spacing: -.01em; margin: 0 0 12px;
  display: flex; align-items: center; gap: 8px; }
body.ps-body .pt-source { display: block; text-align: center; font-size: 14px; font-weight: 500;
  padding: 10px 16px; border-radius: 999px; background: var(--btn); color: #fff;
  text-decoration: none; box-shadow: inset 0 -2.5px 0 var(--btn-line);
  transition: background .12s ease, transform .12s ease; }
body.ps-body .pt-source:hover { background: var(--btn-hover); }
body.ps-body .pt-source:active { transform: translateY(1px); }
.pt-source-note { margin: 9px 0 0; font-size: 11.5px; line-height: 1.55; color: var(--ink-soft); }

/* Label and value on ONE line, the value bold at the end of it, a dashed rule
   between rows — TenderScan's key-facts shape, which reads down a narrow rail
   far better than the stacked label-over-value pairs did. Stacked, eight facts
   ran to sixteen lines and the eye had to decide each time whether it was
   looking at a name or a number; paired, the values form a column you can
   scan. fit-content(52%) lets a long label take the room it needs without ever
   crowding the value out. */
.pt-facts-list { margin: 14px 0 0; display: flex; flex-direction: column; gap: 7px; }
.pt-facts-list > div { display: grid; grid-template-columns: fit-content(52%) 1fr;
  align-items: start; column-gap: 12px; font-size: 13px;
  border-bottom: 1px dashed var(--line); padding-bottom: 7px; }
.pt-facts-list > div:last-child { border-bottom: 0; padding-bottom: 0; }
.pt-facts-list dt { color: var(--ink-soft); letter-spacing: .015em; }
.pt-facts-list dd { margin: 0; color: var(--ink); font-weight: 700; text-align: end;
  min-width: 0; overflow-wrap: anywhere; line-height: 1.4; }
/* The deadline is the one value with a state. Urgent takes the accent; a
   closed notice goes quiet rather than shouting a date that no longer
   matters. */
.pt-facts-list dd.is-urgent { color: var(--accent-ink); }
.pt-facts-list dd.is-muted { color: var(--ink-soft); font-weight: 500; }

.pt-docs { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.pt-docs a { display: block; color: var(--seal); font-size: 13.5px; text-decoration: none;
  padding: 7px 9px; border-radius: 8px; line-height: 1.4;
  transition: background .12s ease; }
.pt-docs a:hover { background: var(--seal-wash); }
/* The rest of a long attachment list, opened on request. One notice carries
   46 and the largest 143. <details> keeps them in the DOM, so a crawler and
   a reader pressing ctrl-F still find every document on a page whose value
   is partly that it lists them. Same rules as the uk branch. */
.pt-docs-more > summary { list-style: none; cursor: pointer; padding: 7px 0 2px;
  font-size: 13px; }
.pt-docs-more > summary::-webkit-details-marker { display: none; }
.pt-docs-more > summary::marker { content: ""; }
.pt-docs-cta { color: var(--seal); font-weight: 600; text-decoration: underline;
  text-underline-offset: 3px; }
.pt-docs-more > summary:hover .pt-docs-cta { color: var(--ink); }
.pt-docs-more > summary .pt-docs-open { display: none; }
.pt-docs-more[open] > summary .pt-docs-shut { display: none; }
.pt-docs-more[open] > summary .pt-docs-open { display: inline; }

.pt-foot { margin: 30px 0 0; font-size: var(--t-xs); }
.pt-foot a { color: var(--seal); text-decoration: none; }
.pt-foot a:hover { text-decoration: underline; text-underline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .pt-conds li, .pt-docs a, body.ps-body .pt-source { transition: none; }
  body.ps-body .pt-source:active { transform: none; }
}

@media (max-width: 900px) {
  /* One column, in the order a phone reader needs: the numbers, then what to
     do about them, then the analysis. */
  .pt-grid { grid-template-columns: minmax(0, 1fr); row-gap: 20px; }
  .pt-lead, .pt-body, .pt-aside { grid-column: 1; grid-row: auto; }
  .pt-lead { order: 1; }
  .pt-aside { order: 2; position: static; }
  .pt-body { order: 3; }
}
@media (max-width: 640px) {
  .pt-decision > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
}


/* ---- T-ILSEARCH: the admin ads block. Plain settings form, house style. ---- */
.ads-form { display: grid; gap: 14px; max-width: 560px; }
.ads-field { display: grid; gap: 5px; }
.ads-field > span { font-size: 13px; font-weight: 600; }
.ads-field input[type="text"], .ads-field textarea { font: inherit; font-size: 14px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: #fff; }
.ads-field textarea { resize: vertical; min-height: 66px; }
.ads-field small { font-size: 12px; line-height: 1.5; }
.ads-slots { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px;
  display: flex; flex-wrap: wrap; gap: 14px; margin: 0; }
.ads-slots legend { font-size: 13px; font-weight: 600; padding-inline: 4px; }
.ads-slot { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; }

/* ── שפת החיפוש (/query) ─────────────────────────────────────────────────────
   The full explanation the hint panel under the search box cannot hold. Reads
   like documentation rather than a product page: one reading column, every
   query on the page clickable, and the examples set in the same code style the
   box itself uses so a reader can see what they are about to paste. */
.qh-page { max-width: 760px; margin: 0 auto; padding-block: 8px 40px; }
.qh-page h1 { font-size: 28px; font-weight: 700; margin: 0 0 10px; }
.qh-page h2 { font-size: 17px; font-weight: 700; margin: 28px 0 10px; }
.qh-lead { font-size: 15px; color: var(--ink); margin: 0 0 10px; line-height: 1.7; }
.qh-page p { line-height: 1.75; color: var(--ink-soft); margin: 0 0 10px; }
.qh-page code { background: var(--wash); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 6px; font-size: 13px;
  /* A query is left-to-right even in a right-to-left page: "מועד > 2026-09-20"
     with the operator flipped is a different query, and the one printed would
     be wrong. */
  direction: ltr; unicode-bidi: isolate; display: inline-block; }
.qh-ex { list-style: none; margin: 0 0 10px; padding: 0; display: flex;
  flex-direction: column; gap: 6px; }
.qh-ex a, .qh-worked a, .qh-eg { text-decoration: none; }
.qh-ex a:hover code, .qh-worked a:hover code, .qh-eg:hover code {
  border-color: var(--seal); background: #fff; }
.qh-fields, .qh-ops, .qh-worked { margin: 0; display: flex;
  flex-direction: column; gap: 10px; }
.qh-fields dt, .qh-ops dt, .qh-worked dt { margin-bottom: 3px; font-weight: 600;
  color: var(--ink); }
.qh-fields dd, .qh-ops dd, .qh-worked dd { margin: 0; color: var(--ink-soft);
  line-height: 1.65; }
.qh-opname { font-weight: 400; color: var(--ink-soft); font-size: 13px;
  margin-inline-start: 6px; }
.qh-note { color: var(--ink-soft); font-size: 12.5px; }
.qh-eg { margin-inline-start: 6px; }
.qh-gotchas { margin: 0; padding-inline-start: 18px; color: var(--ink-soft);
  line-height: 1.75; display: flex; flex-direction: column; gap: 6px; }
/* The way back into the panel that sent them here. */
.search-help .sh-more { margin-inline-start: 6px; color: var(--seal);
  text-decoration: none; font-weight: 600; white-space: nowrap; }
.search-help .sh-more:hover { text-decoration: underline; text-underline-offset: 3px; }

/* The quiet route out of a search results page, into the authority pages.
   Text, centred, at the size of the small print around it: this is an
   invitation at the end of a page, not a call to action competing with the
   results above it. Mirrors .ts-foot-xlink on the UK search site. */
.ps-foot-xlink { margin: var(--s5, 24px) 0 0; font-size: 12.5px;
  color: var(--ink-soft); text-align: center; }
.ps-foot-xlink a { color: var(--seal); text-decoration: none; }
.ps-foot-xlink a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── רשויות: הפרופיל והאינדקס (IL) ───────────────────────────────────────────
   The authority profile panel and the directory. Deliberately not a copy of
   the UK buyer page: there is no award history in Israel, so there are no
   money panels to style — what is here is what the notices can support. */
.ilb-facts { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.ilb-facts dt { font-size: var(--t-xs, 13px); color: var(--ink-soft); margin-bottom: 2px; }
.ilb-facts dd { margin: 0; font-size: 14px; color: var(--ink); line-height: 1.5; }
/* The sample or the cohort median: present, checkable, and never the loudest
   thing in the row. */
.ilb-peer { color: var(--ink-soft); font-size: 12.5px; }

/* The type filter. Buttons, because they act on the page rather than navigate;
   [hidden] is forced below so a display rule cannot outrank it. */
.ilb-filter { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.ilb-chip { font: inherit; font-size: 12.5px; cursor: pointer;
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); }
.ilb-chip span { color: var(--ink-soft); margin-inline-start: 5px;
  font-variant-numeric: tabular-nums; }
.ilb-chip:hover { border-color: var(--line-hover); }
.ilb-chip.is-on { background: var(--ink); border-color: var(--ink); color: #fff; }
.ilb-chip.is-on span { color: rgba(255, 255, 255, .72); }

.ilb-cards { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: 10px; }
.ilb-card[hidden] { display: none !important; }
.ilb-card a { display: block; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: 12px; text-decoration: none; background: var(--surface); }
.ilb-card a:hover { border-color: var(--seal); }
.ilb-card-top { display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; }
.ilb-card-name { font-weight: 600; color: var(--ink); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ilb-card-kind { font-size: 11.5px; color: var(--ink-soft); white-space: nowrap; }
.ilb-card-meta { display: block; margin-top: 4px; font-size: 12.5px;
  color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.ilb-card-meta b { color: var(--ink); }
.ilb-card-buys { display: block; margin-top: 3px; font-size: 12px;
  color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.ilb-dot { color: var(--line-hover); margin: 0 5px; }
.ilb-quiet { color: var(--ink-soft); }
.ilb-empty { margin: 12px 0 0; color: var(--ink-soft); font-size: 13px; }

/* The same invitation as the foot of a results page, in the hero. Quiet: the
   search box is what the page is for, and this sits under the caption that
   already names the number. */
.ps-hero-xlink { margin: 6px 0 0; font-size: 12.5px; color: var(--ink-soft); }
/* The 6px above is the gap BETWEEN the two cross-links, which belong together
   as a pair. The first of them needs room from the advanced-search tip, which
   is a bordered control rather than a line of text — at 6px the tip and the
   link read as one stack. Set on the adjacent sibling so the pair stays tight
   and only the join opens up. */
.ps-advanced-hint + .ps-hero-xlink { margin-top: 22px; }
.ps-hero-xlink a { color: var(--seal); text-decoration: none; }
.ps-hero-xlink a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Sign-in reads as a control, not as body text: it is one of two things in
   the header and the only one that does something to your session. Bordered
   rather than filled — a solid button here would outshout the search box. */
.ps-topbar .ps-login { border: 1px solid var(--line-hover);
  border-radius: 8px; padding: 6px 14px; font-weight: 600; font-size: 13px;
  color: var(--ink); text-decoration: none; white-space: nowrap; }
.ps-topbar .ps-login:hover { border-color: var(--ink-soft); background: var(--wash); }

/* The one link out of the free search and into the paid service, in the
   header where a search engine puts "sign in". Text, not a button: the search
   box is what this page is for, and the product link competing with it would
   make the front door look like an advert for itself. */
.ps-product { font-size: 13px; font-weight: 600; color: var(--seal);
  text-decoration: none; white-space: nowrap; }
.ps-product:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── הסכמה לעוגיות פרסום ─────────────────────────────────────────────────────
   One question at the foot of the page, in the site's own type. Both answers
   are buttons of the same shape: a "no" styled as a link beside a filled "yes"
   is a dark pattern with extra steps. */
.ps-consent { position: sticky; bottom: 0; z-index: 30; display: flex;
  flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 16px;
  padding: 12px 18px; background: var(--surface);
  border-top: 1px solid var(--line); }
.ps-consent p { margin: 0; font-size: 13px; color: var(--ink-soft);
  line-height: 1.55; max-width: 62ch; }
.ps-consent a { color: var(--seal); }
.ps-consent-btns { display: flex; gap: 8px; }
.ps-consent button { font: inherit; font-size: 13px; font-weight: 600;
  padding: 7px 16px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line-hover); background: var(--surface);
  color: var(--ink); }
.ps-consent button:hover { border-color: var(--ink-soft); }
/* Named with the element too, so the rule above cannot outrank the text
   colour — the UK version shipped black-on-black for exactly that reason. */
.ps-consent button.ps-consent-yes { background: var(--ink); border-color: var(--ink);
  color: #fff; }
.ps-consent button.ps-consent-yes:hover { background: #14212a; color: #fff; }

/* The hub's find row: free text and the type chips do the same job — narrowing
   246 names — so they sit together. The button is plain on purpose: a filled
   accent button next to a text field reads as the page's main action, and the
   page's main action is reading the list. */
/* A single filter field, not a hero search box. It was `display: flex` with
   no cap, so the input took the full 1080px of the directory — a text field
   the width of the screen invites a sentence, gives the eye no anchor, and
   leaves its own button stranded at the far end. Capped at a comfortable
   measure; below that width it still fills what it has. The chips underneath
   stay full width on purpose — they are a row of targets, not a field. */
.ilb-find { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px;
  max-width: 460px; }
.ilb-find input { flex: 1 1 320px; min-height: 40px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
  font: inherit; font-size: 14px; }
.ilb-find input:focus { outline: 2px solid var(--seal); outline-offset: 1px;
  border-color: var(--seal); }
/* body.il-pub button[type="submit"] paints every submit in this shell dark,
   and it scores (0,2,2) — a bare class loses to it, which is why this button
   came out filled. Matching the weight and coming later is what makes a plain
   one plain. */
.ilb-find-go { display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 16px; cursor: pointer; font: inherit;
  font-size: 14px; font-weight: 600; border-radius: 8px; }
body.il-pub button.ilb-find-go { background: var(--surface);
  color: var(--ink); border: 1px solid var(--ink-soft); box-shadow: none; }
body.il-pub button.ilb-find-go:hover { border-color: var(--ink);
  background: var(--wash); color: var(--ink); }

/* The search button on the front door, as TenderScan draws it: a quiet ink
   fill, white text, no border and NO inset accent line.
   The app's own --btn is seal blue with a construction-orange base line, which
   is right on a signup button inside the product and wrong here — a search box
   is not a call to action, and blue-with-orange made the front door look like
   one. The accent survives where it does a job rather than decorating one: as
   the focus ring, which is the moment a keyboard user needs to be shouted at. */
body.ps-body .ps-form .ps-submit { background: var(--ink); color: #fff;
  border: 0; box-shadow: none; font-weight: 500; }
body.ps-body .ps-form .ps-submit:hover { background: #14212a; }
body.ps-body .ps-form .ps-submit:active { transform: translateY(1px); }
body.ps-body .ps-form .ps-submit:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 3px; }

/* The one fact in the glance panel that leads somewhere. Coloured on purpose:
   every other value beside it is a dead-end string, so a link drawn like them
   would never be found. */
.pt-facts-list .pt-fact-buyer { color: var(--seal); text-decoration: none;
  font-weight: 600; }
.pt-facts-list .pt-fact-buyer:hover { text-decoration: underline; text-underline-offset: 3px; }

/* "נדחה מ-12/03/2026", set beside the closing date rather than instead of it.
   Deliberately quiet: the live date is the fact a bidder acts on, and this is
   the reason it is not the date they may already have written down. Loud enough
   to be read, never loud enough to be mistaken for the deadline itself. */
.pt-facts-list .pt-postponed { display: block; margin-top: 2px;
  font-size: var(--t-xs); font-weight: 500; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }
/* The chain, shown only from the second move. One move is already said above;
   three is a pattern, and the gap between the first date and the current one is
   the part worth seeing at a glance. */
.pt-postpone-chain ol { margin: 0; padding-inline-start: 1.1em;
  display: flex; flex-direction: column; gap: 2px; }
.pt-postpone-chain li { font-size: var(--t-xs); color: var(--ink); line-height: 1.5; }
/* The superseded date, dimmed so the line reads as "this date, not that one"
   at a glance rather than as two dates of equal standing. */
.pt-postpone-chain .pt-postpone-was { color: var(--ink-soft); }
.pt-postpone-chain a { color: var(--seal); }

/* The official record, as a line under the facts rather than a slab above
   them. On a phone the button was the biggest thing in the aside — louder than
   the deadline, and offered before the reader had decided this notice was even
   the one. It is the last step, so it sits last. */
.pt-source-line { margin: 12px 0 0; font-size: 13px; line-height: 1.5; }
.pt-source-line a { color: var(--seal); font-weight: 600;
  text-decoration: none; }
.pt-source-line a:hover { text-decoration: underline; text-underline-offset: 3px; }
.pt-source-line span { display: block; margin-top: 2px; font-size: 12px;
  color: var(--ink-soft); }


/* ── Public market page (/tender-market) ─────────────────────────────────────
   Drawn the way TenderScan draws /uk-tender-market — period nav, headline
   tiles, one chart, leaderboards side by side — so the two markets read as one
   product. Own .mkt-* namespace: it must never restyle .ps-*, .bh2-* or the
   app's components. RTL throughout, so anything directional uses logical
   properties rather than left/right. */

.mkt-periods { display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: 18px 0 16px; }
.mkt-periods-k { font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-soft, #667); margin-inline-end: 6px; }
.mkt-period { font-size: 13.5px; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--line, #dfe3ea); color: var(--ink-soft, #667);
  text-decoration: none; background: var(--paper, #fff); }
.mkt-period:hover { border-color: var(--seal); color: var(--seal); }
.mkt-period.is-on { background: var(--seal); border-color: var(--seal);
  color: #fff; font-weight: 600; }

.mkt-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px; margin-bottom: 14px; }
.mkt-tile { background: var(--paper, #fff); border: 1px solid var(--line, #dfe3ea);
  border-radius: 12px; padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; }
.mkt-tile b { font-size: 25px; line-height: 1.15; font-weight: 700; }
.mkt-tile-money { border-color: var(--seal); }
.mkt-tile-money b { color: var(--seal); }
.mkt-tile span { font-size: 13px; color: var(--ink-soft, #667); }
.mkt-tile small { display: block; font-size: 11.5px; opacity: .85; }

.mkt-caveat { font-size: 13px; line-height: 1.75; color: var(--ink-soft, #667);
  background: var(--wash, #f7f9fc); border: 1px solid var(--line, #dfe3ea);
  border-radius: 12px; padding: 13px 16px; margin: 0 0 22px; }
.mkt-caveat strong { color: var(--ink, #16202c); }

.mkt-card { background: var(--paper, #fff); border: 1px solid var(--line, #dfe3ea);
  border-radius: 12px; padding: 18px 18px 14px; margin-bottom: 18px; }
.mkt-card-quiet { background: transparent; }
.mkt-card-h { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 12px; }
.mkt-card-h h2 { font-size: 16px; margin: 0; }
.mkt-card-sub { font-size: 13px; color: var(--ink-soft, #667); margin: -4px 0 14px;
  max-width: 70ch; }

/* Two leaderboards abreast on desktop, stacked on a phone. */
.mkt-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 780px) { .mkt-cols { grid-template-columns: 1fr; gap: 0; } }

.mkt-leaders { list-style: none; margin: 0; padding: 0; }
.mkt-leader { display: grid; grid-template-columns: 22px 1fr auto; align-items: baseline;
  gap: 10px; padding: 8px 2px; border-bottom: 1px solid var(--line-soft, #eef1f5); }
.mkt-leader:last-child { border-bottom: 0; }
.mkt-leader-n { font-size: 12px; color: var(--ink-soft, #667); }
.mkt-leader-name { font-size: 14px; overflow-wrap: anywhere; }
.mkt-leader-name a { color: var(--ink, #16202c); text-decoration: none; }
.mkt-leader-name a:hover { text-decoration: underline; text-underline-offset: 3px; }
.mkt-leader-v { font-size: 12.5px; color: var(--ink-soft, #667); white-space: nowrap; }

/* Resolution switch, a segmented control: three options, one choice. Sits in
   the card header opposite the title, the way TenderScan's does. */
.mkt-res { display: inline-flex; flex: none; border: 1px solid var(--line, #dfe3ea);
  border-radius: 8px; overflow: hidden; }
.mkt-res-b { font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
  padding: 4px 11px; border: 0; background: var(--paper, #fff);
  color: var(--ink-soft, #667); }
.mkt-res-b + .mkt-res-b { border-inline-start: 1px solid var(--line, #dfe3ea); }
.mkt-res-b:hover { color: var(--ink, #16202c); }
.mkt-res-b.is-on { color: #fff; background: var(--seal); }

/* The chart. Bars reach 85% of the box because the top 15% belongs to the
   amount sitting above each one — the label is part of the chart, not an
   afterthought hovering over it. The inactive resolutions are [hidden], which
   the global rule at the top of this file forces to display:none; without it
   the display:flex here would outrank the attribute and show all three at once. */
/* Time runs left to right, even here. The page is RTL, so a plain flex row put
   the first point — the OLDEST — on the right and ran the years backwards.
   Text has a direction; an axis does not, and every chart the reader has seen
   before puts the past on the left. So the CHART is ltr and each COLUMN is
   handed rtl back, which keeps the Hebrew labels and every inset-inline inside
   them behaving exactly as they did. */
.mkt-chart { display: flex; align-items: stretch; gap: 7px; height: 178px;
  direction: ltr;
  padding-top: 10px; border-bottom: 1px solid var(--line, #dfe3ea); }
.mkt-col { flex: 1; min-width: 0; display: flex; flex-direction: column;
  direction: rtl;
  justify-content: flex-end; align-items: center; gap: 5px; height: 100%; }
.mkt-barwrap { flex: 1; min-height: 0; position: relative; width: 100%;
  align-self: stretch; }
/* Centred with auto margins rather than the usual left:50%/translateX(-50%):
   this page is RTL, where an inline-start offset anchors the OTHER edge and the
   translate then pushes the bar half its width off centre. Auto margins between
   two zero insets centre in both directions. */
.mkt-bar { position: absolute; bottom: 0; inset-inline: 0; margin-inline: auto;
  width: 64%; max-width: 40px; min-height: 2px;
  border-radius: 4px 4px 0 0; background: var(--seal); opacity: .8;
  transition: opacity .15s; }
.mkt-col:hover .mkt-bar { opacity: 1; }
.mkt-bval { position: absolute; inset-inline: 0; margin-inline: auto;
  width: max-content; margin-bottom: 3px; white-space: nowrap; font-size: 9.5px;
  font-weight: 700; color: var(--ink, #16202c); font-variant-numeric: tabular-nums; }
.mkt-bval-sm { font-size: 7px; font-weight: 600; margin-bottom: 2px;
  letter-spacing: -.03em; }
/* The label row is always emitted, blank or not, so every column reserves the
   same height and the bars stay on one shared scale. */
.mkt-mlabel { font-size: 10px; color: var(--ink-soft, #667); line-height: 1.15;
  text-align: center; min-height: 12px; }
.mkt-myr { margin-inline-start: 3px; opacity: .6; }
.mkt-chart-hint { font-size: 12px; color: var(--ink-soft, #667); margin: 12px 0 0;
  line-height: 1.6; }

.mkt-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.mkt-table th { text-align: start; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-soft, #667); font-weight: 600;
  padding: 0 8px 8px; border-bottom: 1px solid var(--line, #dfe3ea); }
.mkt-table td { padding: 8px; border-bottom: 1px solid var(--line-soft, #eef1f5); }
.mkt-table tr:last-child td { border-bottom: 0; }
.mkt-table td.tnum, .mkt-table th.tnum { text-align: end; white-space: nowrap; }

.mkt-more { margin: 12px 0 0; font-size: 13.5px; }
.mkt-more-quiet { color: var(--ink-soft, #667); }
.mkt-cta { text-align: center; padding: 26px 18px; margin-top: 4px;
  border: 1px solid var(--line, #dfe3ea); border-radius: 12px;
  background: var(--wash, #f7f9fc); }
.mkt-cta h2 { font-size: 18px; margin: 0 0 6px; }
.mkt-cta p { color: var(--ink-soft, #667); margin: 0 0 14px; }
.mkt-source { font-size: 12px; color: var(--ink-soft, #667); text-align: center;
  margin: 22px 0 0; }

@media (max-width: 640px) {
  .mkt-tile b { font-size: 21px; }
  /* The month view of the whole record is ~50 bars, which at phone width is
     sub-pixel, so let it scroll rather than collapse into a smear. Year and
     quarter fit without scrolling — which is the point of opening on them. */
  .mkt-chart { height: 152px; gap: 4px; overflow-x: auto; }
  .mkt-col { min-width: 24px; }
  /* The switch drops under the heading rather than squeezing it. */
  .mkt-card-h { flex-wrap: wrap; row-gap: 8px; }
}

/* The way in, from the search page and the authority directory. */
.bh2-market-xlink { margin-block: 4px 18px; }


/* The header search box, starting where the cards start.

   Measured on prod at 1280: the results column runs 273→993 and the box ran
   504→1064 — its edge 71px past the cards', which is what reads as crooked.

   The cause is structural. The column is 720 centred and the top bar is 1080
   centred: two different widths, both centred on the page, so nothing lines up
   by itself. `margin-inline: auto` centres the box between the wordmark and
   the nav — 69px and 235px — so it lands off-centre by the difference and got
   the gap only down to 26px.

   What works is reserving the right rail. Both boxes are centred on the same
   page, so the distance from the bar's content edge to the column's edge is
   half the difference between them; as a PERCENTAGE flex-basis that resolves
   against the bar's own content width, so it stays correct at every viewport
   instead of baking in 1280. Measured with it applied: the box's inline-start
   edge and the cards' are the same pixel, and the nav still fits.

   RTL, so "start" is the right — the box begins where a card begins and the
   eye follows one line down the page.

   Scoped with :has(.ps-form:not([hidden])) so it ONLY touches the headers that
   carry a VISIBLE search box — the front door and a results page. The notice,
   authority, directory and market pages have no header form: their wordmark
   and nav must NOT get the rail treatment, or the nav stretches full width and
   its items pile up beside the wordmark on the right instead of sitting at the
   left. Those pages fall through to the base
   `.ps-auth { margin-inline-start: auto }`, which puts the nav at the end (the
   left, in RTL) where it belongs.

   :not([hidden]) is load-bearing, not tidiness. The empty state now RENDERS
   the compact form and hides it, so the async path has something to unhide —
   and a bare :has(.ps-form) would have started matching the front door, handed
   its nav `flex: 1 1 auto`, and piled the nav items against the wordmark on
   exactly the page this comment says must not get the treatment. The selector
   has to ask what is on screen, not what is in the markup. */
/* The nav grows to take the rail's leftover, so its items are pushed to its
   inline end (justify-content: flex-end) - the left, in RTL - or they sit
   64px further right on a results page than on the front door, where the
   nav does not grow. Same x on both states, as the switch and the two links
   were promised to be. */
@media (min-width: 900px) {
  .ps-topbar-inner:has(.ps-form:not([hidden])) > .ps-wordmark {
    flex: 0 0 calc((100% - 720px) / 2 - 18px);   /* 720 = .ps-shell, 18 = the row gap */
  }
  .ps-topbar-inner:has(.ps-form:not([hidden])) > .ps-auth { flex: 1 1 auto; display: flex; align-items: center; justify-content: flex-end; }
  .ps-topbar .ps-form { flex: 0 0 auto; max-width: 560px; }
}

/* ══ Dark mode, on the free search only ═════════════════════════════════════
   Scoped to body.ps-body — the free site's shell — so the signed-in app and
   the /product landing keep their one palette. The attribute is written by a
   head script before first paint, so there is no flash of the light theme.

   Everything below is a token swap. The ground is the brand's own ink
   (#1C2B33) taken darker rather than a neutral grey, so the site reads as the
   same site with the lights off. Ratios measured, not eyeballed: the worst
   text pair is 5.97:1 and every one clears AA.
*/
html[data-ps-theme="dark"] { color-scheme: dark; }
/* body.il-pub joins body.ps-body here so ONE preference covers both public
   surfaces: the free search site and the paid site's own public pages
   (/product, /login, /signup, the legal pages). The reader sets it once,
   on the search front door. The signed-in app is deliberately not in this
   list — it has its own attribute, palette and switch. */
html[data-ps-theme="dark"] body.ps-body,
html[data-ps-theme="dark"] body.il-pub {
  --paper: #111A20;
  --surface: #18232B;
  --ink: #E7EDF1;
  --ink-soft: #9DAFBA;
  --line: #2A3A45;
  --line-hover: #3C505D;
  --wash: #1E2A33;

  /* Both brand colours have to come UP to stay legible on a dark ground. The
     seal at #16557A on #18232B is 1.5:1 — invisible. */
  --seal: #7CB7DE;
  --seal-wash: #1B2E3B;
  --accent: #F5822F;
  --accent-ink: #F19A55;
  --accent-wash: #33241A;

  --ok: #4FC489;   --ok-wash: #14301F;
  --bad: #EC7F72;  --bad-wash: #33201C;
  --check: #DCAE45; --check-wash: #33290F;
  --live: #4FC489;

  /* The accent as a GROUND behind text, answered here as well as in the app's
     dark block — a token defined in light and left unanswered in dark keeps
     its light value, which on this surface would be a deep-orange fill nobody
     chose. Same arrangement as the app: the fill lifts, the writing on it
     becomes ink. */
  --accent-fill: #F5822F;
  --accent-fill-hover: #F19A55;
  --on-accent: #111A20;

  /* The button keeps a fill dark enough for white text (5.49:1); --seal is a
     text colour here and would fail behind one. */
  --btn: #1F6F9E;
  --btn-hover: #2A85B8;

  --shadow: 0 1px 3px rgb(0 0 0 / .5);
  --shadow-card: 0 1px 2px rgb(0 0 0 / .4), 0 2px 8px rgb(0 0 0 / .35);
}

/* The literals that a token swap cannot reach. Each one is a colour written
   into a free-site rule before there was a second theme to write it for. */
html[data-ps-theme="dark"] body.ps-body .bp2-panel {
  border-color: var(--line);
  box-shadow: none;
}
html[data-ps-theme="dark"] body.ps-body .bp2-row,
html[data-ps-theme="dark"] body.ps-body .bp2-links li,
html[data-ps-theme="dark"] body.ps-body .bp2-orglist li,
html[data-ps-theme="dark"] body.ps-body .bp2-tease,
html[data-ps-theme="dark"] body.ps-body .bp2-panel-soft .bp2-tease,
html[data-ps-theme="dark"] body.ps-body .psx-tbl td { border-top-color: var(--line); }
/* A visited link mixed toward a dark purple, which on a dark ground pulled it
   back into the background it had to stand out from. */
html[data-ps-theme="dark"] body.ps-body .ps-card-title a:visited {
  color: color-mix(in srgb, var(--seal) 78%, #C9A6E0);
}
/* Shadows are cast BY a light. On a dark ground the same ink-tinted shadows
   read as smudges, so the cards keep their borders and drop them. */
html[data-ps-theme="dark"] body.ps-body .ps-form,
html[data-ps-theme="dark"] body.ps-body .ps-form-compact,
html[data-ps-theme="dark"] body.ps-body .ps-example,
html[data-ps-theme="dark"] body.ps-body .ps-card:hover,
html[data-ps-theme="dark"] body.ps-body .ps-seg-opt.is-on { box-shadow: none; }
html[data-ps-theme="dark"] body.ps-body .ps-form:hover,
html[data-ps-theme="dark"] body.ps-body .ps-example:hover { box-shadow: none; }
/* These two float ABOVE the page, so they keep a shadow — a real one for a
   dark ground, not the ink-tinted one. */
html[data-ps-theme="dark"] body.ps-body .ps-suggest,
html[data-ps-theme="dark"] body.ps-body .ps-advanced-panel {
  box-shadow: 0 18px 40px -18px rgb(0 0 0 / .7), 0 2px 6px rgb(0 0 0 / .4);
}

/* Controls painted as the INVERSE of the page: an --ink fill carrying white
   text. In dark --ink is the LIGHT end of the scale, so the fill inverts with
   the theme while the hardcoded white text does not — measured on the search
   button at 1.18:1, white on near-white. The text takes the paper colour and
   the hover goes lighter instead of darker, which is the same gesture read in
   the other direction. */
html[data-ps-theme="dark"] body.ps-body .ps-form .ps-submit,
html[data-ps-theme="dark"] body.ps-body .ilb-chip.is-on,
html[data-ps-theme="dark"] body.ps-body .ps-consent button.ps-consent-yes {
  color: var(--paper);
}
html[data-ps-theme="dark"] body.ps-body .ilb-chip.is-on span { color: rgb(17 26 32 / .66); }
html[data-ps-theme="dark"] body.ps-body .ps-form .ps-submit:hover,
html[data-ps-theme="dark"] body.ps-body .ps-consent button.ps-consent-yes:hover {
  background: #FFFFFF; color: var(--paper);
}

/* The find button on the authority index. Deliberately white with dark text
   in light mode — a plain control, not a call to action — but written as a
   literal #fff, so in dark it kept the white while --ink went light: 1.18:1,
   and visibly a white slab on a dark page. Same intent, drawn for the ground
   it is actually on. */
/* A separator at --line-hover is a hairline's colour, which on dark reads as
   nothing at all where it is a glyph rather than a border. */
html[data-ps-theme="dark"] body.ps-body .ilb-dot { color: var(--ink-soft); }
/* The other inverse-fill family: white text on a --seal fill. --seal has to
   come up to stay legible AS TEXT on a dark ground, which makes it far too
   light to sit behind white. */
html[data-ps-theme="dark"] body.ps-body .mkt-period.is-on,
html[data-ps-theme="dark"] body.ps-body .mkt-res-b.is-on { color: var(--paper); }

/* ── the switch ──────────────────────────────────────────────────────────────
   An icon button, not a third nav link: the top bar carries התחברות and the
   one link to the full service, and a display preference is a control rather
   than a destination. */
.ps-theme {
  display: inline-flex; align-items: center; justify-content: center;
  inline-size: 34px; block-size: 34px; padding: 0;
  border: 1px solid transparent; border-radius: var(--r-control);
  background: transparent; color: var(--ink-soft); cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.ps-theme:hover { color: var(--ink); border-color: var(--line-hover); background: var(--wash); }
.ps-theme svg { display: block; }
/* The switch inside the app chrome's logged-out nav (/product and friends).
   That nav runs on a 6px gap, which sets the button hard against the login
   link; this lifts the separation to the 14px the search header uses, so the
   two headers read as the same control in the same place. */
.nav-auth .ps-theme { margin-inline-end: 8px; }
/* One icon at a time, and it shows what a click WILL DO — a moon while the
   page is light. A button that pictures the state you are already in reads as
   a status light rather than a switch. */
.ps-theme .ps-theme-sun { display: none; }
html[data-ps-theme="dark"] .ps-theme .ps-theme-sun { display: block; }
html[data-ps-theme="dark"] .ps-theme .ps-theme-moon { display: none; }

/* ── Search results placeholder ────────────────────────────────────────────
   Shown the instant a search is submitted, so the reader is looking at the
   results page while the query runs instead of at the page they just left.
   Reuses the .skel shimmer above, including its reduced-motion opt-out. */
/* No inset of its own. This wrapper used to pad 8px at the top, from when the
   skeleton was its own little layout rather than a stand-in for the answer's;
   now that it mirrors the real structure that padding shifted every row 8px
   down and back up again on arrival. */
.ps-skel { padding: 0; }
.ps-skel-head { margin: 0 0 18px; }
.ps-skel-card {
  list-style: none; padding: 16px 0; border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 10px;
}
.ps-skel-status {
  color: var(--ink-soft); font-size: 0.92rem; margin: 0 0 14px;
}

/* A chip the CLIENT drew while the search runs, from what was submitted. The
   server replaces it the moment the response lands, and its reading may differ
   — it can interpret a query in ways the browser cannot. So this one is
   quieter: enough to hold the row and say what was asked for, not so settled
   that a reader takes it as the final reading. No remove control, because
   there is nothing to remove from a search still in flight. */
.ps-chip.is-pending { opacity: .55; }

/* The placeholder has to reserve what the answer will occupy, or it is not a
   placeholder — it is a smaller layout that the real one shoves aside.

   Measured on a results page: the meta row is 58px, and result cards run
   323-554px with a median of 531. The skeleton was reserving 71px a card, so
   five rows came up about 2,300px short and everything below the fold slid as
   the answer arrived.

   The median rather than the maximum: overshooting leaves a gap under the last
   card that then closes, which is the same jump in the other direction. Cards
   vary because their content does, so this cannot be exact — it can only stop
   being wrong by a factor of seven. */
/* 58px where the count and the sort control stack, 46px where they sit on one
   line. Measured either side; reserving the tall one everywhere left the first
   card 12px low on a desktop. */
.ps-skel-metarow { min-block-size: 46px; }
@media (max-width: 1023px) { .ps-skel-metarow { min-block-size: 58px; } }
.ps-skel-card { min-block-size: 531px; }
/* Cards are shorter on a narrow screen — measured at 375px, the median is 499
   against 531 on the desktop — so the desktop reserve overshoots by about
   600px across a ten-row list, leaving a gap that closes when the answer
   lands. That is the same jump as being too short, only mirrored. */
@media (max-width: 560px) { .ps-skel-card { min-block-size: 499px; } }
.ps-skel-ad { min-block-size: 53px; }

/* The bars, sized off the real card's blocks (measured at 375px: source 50,
   title 95, snippet 67, facts 3x44, thresholds 72). Widths vary so the block
   reads as text rather than as a stack of identical rectangles — the one thing
   that makes a skeleton look like a loading state instead of a broken layout.
   Heights come to roughly the card's own, which is why min-block-size is now a
   floor rather than the whole story. */
/* The bar set has to FIT the card, not force it taller. A real card is about
   256px at 1280px wide and about 500px at 375px, because everything in it
   wraps — so a single set of bars either leaves a hole on a phone or pushes a
   desktop card to nearly double its height. The wide layout gets the lean set;
   the narrow one adds the lines that wrapping really does produce. */
.ps-skel-card .skel-src    { block-size: 20px; inline-size: 46%; }
.ps-skel-card .skel-title  { block-size: 34px; inline-size: 92%; }
.ps-skel-card .skel-title2 { display: none; }
.ps-skel-card .skel-snip   { block-size: 18px; inline-size: 100%; }
.ps-skel-card .skel-snip2  { display: none; }
.ps-skel-card .skel-fact   { block-size: 30px; inline-size: 100%; }
.ps-skel-card .skel-thr    { block-size: 18px; inline-size: 80%; }
.ps-skel-card .skel-thr2   { display: none; }

@media (max-width: 1023px) {
  /* Titles run to two lines and the facts stack, so the card grows. */
  .ps-skel-card .skel-title  { block-size: 44px; }
  .ps-skel-card .skel-title2 { display: block; block-size: 44px; inline-size: 64%; }
  .ps-skel-card .skel-snip   { block-size: 20px; }
  .ps-skel-card .skel-snip2  { display: block; block-size: 20px; inline-size: 72%; }
  .ps-skel-card .skel-fact   { block-size: 44px; }
  .ps-skel-card .skel-thr2   { display: block; block-size: 20px; inline-size: 52%; }
}


/* ══ Dark mode: the literals a token swap cannot reach ══════════════════════
   Scoped to html[data-theme="dark"] body.app, so the light theme is unchanged.
   Every ratio quoted was measured on the rendered page. */

/* The score seal's tier label was #333333 — dark grey on a dark card, 1.26:1.
   It is a quiet label, so it takes the quiet ink rather than the loud one. */
html[data-theme="dark"] body.app .seal .seal-tier { color: var(--ink-soft); }

/* A planning caption in "soft warm gold" (#9a7a2b) lands at 3.95:1 on the dark
   card. --check is the token for exactly this kind of warm advisory colour and
   is already lifted for dark. */
html[data-theme="dark"] body.app .stage-tag { color: var(--check); }

/* The active sort segment is white on --accent. The accent has to come UP for a
   dark ground, and white on the brighter orange is 2.59:1 — worse than it was.
   Dark ink on the orange instead: the segment stays unmistakably the accent,
   and the label becomes readable (8.7:1).

   NOTE: white on the LIGHT theme's #E8650D is 3.3:1, which also misses AA for
   text this size. That is pre-existing and outside this change — flagged, not
   silently restyled. */


/* Confidence chips were three hardcoded pastel fills — light islands punched
   into a dark panel. The condition tokens already carry a dark-ready pair. */
html[data-theme="dark"] body.app .conf-high   { background: var(--ok-wash);    color: var(--ok); }
html[data-theme="dark"] body.app .conf-medium { background: var(--check-wash); color: var(--check); }
html[data-theme="dark"] body.app .conf-low    { background: var(--bad-wash);   color: var(--bad); }

/* A separator dot drawn in --line: right in light, invisible in dark. It is
   punctuation between facts, so it wants to stay quieter than the text while
   still being seen. */
html[data-theme="dark"] body.app .fitcard-context .dot { color: var(--line-hover); }

/* The primary button is white on --accent. The accent has to come UP for a dark
   ground, and white on the brighter orange measures 2.59:1 — so the loudest
   control on every page was the least readable one. Dark ink on the same
   orange instead (8.7:1): the button stays unmistakably the CTA, and it now
   matches what .sort-opt.is-active does two rules up.

   The hover state needs it too — --accent-ink is LIGHTER than --accent in dark
   (#F19A55), so white there would be worse still. */


/* The account avatar, once its menu is open or active, fills with --seal and
   writes white on it. In dark --seal is a light blue TEXT colour, so white on
   it is 2.17:1. */
html[data-theme="dark"] body.app .nav-account > summary.active .nav-avatar,
html[data-theme="dark"] body.app .nav-account[open] > summary .nav-avatar { color: #111A20; }

/* The Bidvane wordmark's "TENDERS" bar is drawn in --accent, so it followed
   the accent UP for the dark ground and its white lettering fell to 2.59:1.
   A logo is a fixed asset, not a themed component: pinning the bar to the
   brand orange renders the lockup exactly as designed on either ground, and
   restores the 3.3:1 it has in light.

   (WCAG exempts logotypes from the contrast minimum, which is why 3.3:1 is
   the brand's own decision to make and not one for this change.) */
html[data-theme="dark"] body.app .bv-bar { background: #E8650D; }

/* The BQL help popup floats OVER the page, so on a dark ground it needs the
   shadow to read as depth rather than as the ink-tinted smudge a light-theme
   shadow becomes. Same reasoning as --shadow-card in the token block. */
html[data-theme="dark"] body.app .search-help {
  box-shadow: 0 14px 40px rgb(0 0 0 / .55);
}

/* ── Dark: the market surfaces ─────────────────────────────────────────────
   Market, Buyers, Suppliers and Frameworks. These were invisible to the first
   sweep because the local database had no awards, so every one of these pages
   was an empty state; seeding real market data is what exposed them. */

/* The sector palette is six ink/background PAIRS, so re-colouring the tokens
   fixes every sector pill and dot on every surface at once. Each background is
   its own hue taken dark and each ink lifted onto it, so a sector still reads
   by colour rather than collapsing into one grey. */
html[data-theme="dark"] body.app {
  --sec-works-ink: #F19A55;   --sec-works-bg: #33241A;
  --sec-digital-ink: #7CB7DE; --sec-digital-bg: #16293A;
  --sec-health-ink: #4FC489;  --sec-health-bg: #102E27;
  --sec-facil-ink: #B79BE0;   --sec-facil-bg: #241D33;
  --sec-supply-ink: #DCAE45;  --sec-supply-bg: #33290F;
  --sec-prof-ink: #A9BAC4;    --sec-prof-bg: #232D33;
}

/* Two more fills that write white on --accent, the same shape as .btn-primary:
   the accent is lifted for a dark ground and white on it is 2.59:1. */


/* A fit badge whose green was written as literals rather than tokens, so it
   could not follow the theme; --ok/--ok-wash are the dark-ready pair. */
html[data-theme="dark"] body.app .fw-fit--high {
  background: var(--ok-wash); color: var(--ok);
}
html[data-theme="dark"] body.app .fw-fit--low {
  background: var(--wash); color: var(--ink-soft);
}

/* The grain selector (month / quarter / year) on "Activity over time".
   Light reads as "the chosen chip is raised": a faint inset track with a
   lighter chip sitting on it. Dark keeps the relationship and inverts the
   values — a well darker than the panel, a chip lighter than both — because
   at --surface the chip was exactly the panel's own colour and the 4%-black
   track was invisible on it. The seal label on --line measures 5.5:1. */
html[data-theme="dark"] body.app .mk-grain {
  background: var(--paper);
  border: 1px solid var(--line);
}
html[data-theme="dark"] body.app .mk-grain-btn.is-on {
  background: var(--line);
  color: var(--ink);
  /* No shadow: a shadow is cast BY a light, and the ink-tinted original reads
     as a smudge on a dark ground rather than as lift. The chip is raised here
     by being lighter than the well it sits in. */
  box-shadow: none;
}


/* Long award histories (Israel's runs from 2005) draw ~190 monthly columns.
   The default 6px gap is sized for a two-year window; at this count the gaps
   alone are wider than the chart, and `flex: 1` then leaves every column zero
   pixels wide — a chart with no visible bars at all. A 1px gap gives the
   columns the width back.

   Only January carries a label here (see _market_body.html), and that year tick
   is far wider than its own column, so it is lifted out of the flow and centred
   on it — otherwise the twelve labelled columns would stretch to fit their text
   and no longer be comparable with their neighbours. */
.bp-chart-dense { gap: 1px; }
.bp-chart-dense .bp-col { position: relative; padding-bottom: 1.2em; }
.bp-chart-dense .bp-bar { border-radius: 1px 1px 0 0; }
.bp-chart-dense .bp-mlabel-year {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  margin-top: 0;
}


/* The category chips in the directory tables sat flush against each other —
   tolerable when each held a two-digit CPV number, unreadable once Israel put
   whole words in them ("בריאות ורפואה" "הסעדה" "בנייה" read as one run-on
   string). Logical margin so it works the same in both text directions. */
.chip-cpv + .chip-cpv { margin-inline-start: 4px; }


/* ── Buyers / suppliers directory rows ───────────────────────────────────────
   Ported from the UK's directory (T-MARKET) so both markets read the same:
   monogram, one dominant category with a share bar, money with a coverage cue,
   whole-row hover. Scoped to #dir-results.dir2 so the shared table classes on
   every other page are untouched.

   Written with LOGICAL properties (inline-start/end, margin-inline) rather than
   left/right, because this table is the same markup in an LTR and an RTL page —
   a hard-coded `left` puts the hover rail and the coverage bar on the wrong edge
   in Hebrew. */

/* The six sector families, as ink/background PAIRS. The dark overrides for these
   already existed; the light values did not, which meant every var() reading
   them resolved to nothing and the pills rendered transparent. */
:root {
  --sec-works-ink: #B14A05;   --sec-works-bg: #FCEFE4;
  --sec-digital-ink: #155E8A; --sec-digital-bg: #E7F0F6;
  --sec-health-ink: #0F7A63;  --sec-health-bg: #E4F3EF;
  --sec-facil-ink: #6B4AA8;   --sec-facil-bg: #F0EBF9;
  --sec-supply-ink: #8A6410;  --sec-supply-bg: #F8F0DC;
  --sec-prof-ink: #455A64;    --sec-prof-bg: #ECEFF1;
}
.sec-works { color: var(--sec-works-ink); background: var(--sec-works-bg); }
.sec-digital { color: var(--sec-digital-ink); background: var(--sec-digital-bg); }
.sec-health { color: var(--sec-health-ink); background: var(--sec-health-bg); }
.sec-facil { color: var(--sec-facil-ink); background: var(--sec-facil-bg); }
.sec-supply { color: var(--sec-supply-ink); background: var(--sec-supply-bg); }
.sec-prof { color: var(--sec-prof-ink); background: var(--sec-prof-bg); }
.sec-other { color: var(--ink-soft); background: var(--paper); }

/* Column grid. Fixed layout so a long authority name ellipsizes inside its cell
   instead of blowing the column out, and a readable minimum below which the
   wrapper scrolls rather than the page. */
.bp-dirwrap { overflow-x: auto; }
table.bp-dir { table-layout: fixed; min-width: 720px; }
table.bp-dir th:nth-child(1), table.bp-dir td:nth-child(1) { width: 27%; }
table.bp-dir th:nth-child(2), table.bp-dir td:nth-child(2) { width: 23%; }
table.bp-dir th:nth-child(3), table.bp-dir td:nth-child(3) { width: 10%; }
table.bp-dir th:nth-child(4), table.bp-dir td:nth-child(4) { width: 17%; }
table.bp-dir th:nth-child(5), table.bp-dir td:nth-child(5) { width: 10%; }
table.bp-dir th:nth-child(6), table.bp-dir td:nth-child(6) { width: 13%; }
table.bp-dir td.bp-metric, table.bp-dir td.bp-date, table.bp-dir td:nth-child(4) {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The wrapper's overflow makes it the sticky containing block, so the shared
   `table.data thead th { top: 64px }` (written to clear the fixed nav) would
   push this header down onto the first row. Inside the wrapper it is 0. */
table.data.bp-dir thead th { top: 0; }

/* identity cell */
.bp-idcell { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.bp-mono { flex: none; width: 34px; height: 34px; border-radius: 9px; display: grid;
  place-items: center; font-weight: 800; font-size: 11px; letter-spacing: .02em; }
.bp-idtext { min-width: 0; }
.bp-bname { font-weight: 600; color: var(--ink); text-decoration: none; display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bp-btype { font-size: var(--t-xs); color: var(--ink-soft); text-transform: capitalize; }

/* dominant category + its share of the entity's awards */
.bp-cat { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
/* display:block is load-bearing, not tidying. overflow and text-overflow do
   NOTHING on an inline box, so for years this rule only delivered its
   white-space:nowrap — and a label wider than its column did not clip, it
   spilled over the cell beside it. Measured on the expiry table:
   "פסולת, מיחזור וסביבה" wanted 122px in a 102px cell and overflowed all 20.

   It looked correct because the buyer page puts this inside a .bp-cat flex
   container, where the item is blockified anyway and the ellipsis does work.
   In a plain <td> it never did. Blockified here, it fills the cell's content
   box and clips against that — which is the width the reader can actually
   see, and better than any character count could guess for Hebrew. */
.bp-cat-name { display: block; font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bp-cat-share { display: flex; align-items: center; gap: 8px; }
.bp-cat-bar { flex: 1; max-width: 96px; height: 5px; background: var(--seal-wash);
  border-radius: 999px; overflow: hidden; }
.bp-cat-bar i { display: block; height: 100%; background: var(--seal); border-radius: 999px; }
.bp-cat-pct { flex: none; font-size: 11.5px; font-weight: 700; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }

/* money + how much of it is actually published */
.bp-money { font-weight: 700; color: var(--ink); }
.bp-metric { font-weight: 600; color: var(--ink); }
.bp-date { color: var(--ink-soft); }
.bp-cov { display: flex; align-items: center; gap: 6px; justify-content: flex-end;
  font-size: 11px; color: var(--ink-soft); margin-top: 3px; }
.bp-covbar { width: 40px; height: 5px; border-radius: 999px; background: var(--seal-wash);
  overflow: hidden; flex: none; }
.bp-covbar i { display: block; height: 100%; background: var(--seal); border-radius: 999px; }

/* ── the .dir2 card treatment ───────────────────────────────────────────── */
.dir2 .results-summary { font-size: 13px; color: var(--ink-soft); margin: 0 0 14px; }
.dir2 .results-summary b { color: var(--ink); }
.dir2 .table-wrap, .dir2 .bp-dirwrap {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 1px 2px rgba(28, 43, 51, .03); }
.dir2 .bp-table thead th {
  background: var(--surface); text-transform: uppercase; font-size: 10.5px;
  letter-spacing: .05em; font-weight: 700; color: var(--ink-soft); padding: 13px 12px;
  border-bottom: 1px solid var(--line); }
/* A sortable header's label is a link that carries its own padding so the whole
   cell is clickable. This block re-pads the th, and the two stacked: header text
   sat 12+16px in while the cells below sat 12px in, so every sortable column was
   16px out of line with its own values. Give the padding to the link only. */
.dir2 .bp-table thead th.sortable { padding: 0; }
.dir2 .bp-table thead th.sortable a { color: var(--ink-soft); padding: 13px 12px; }
.dir2 .bp-table thead th.sort-active a { color: var(--seal); }
.dir2 .bp-table td { padding: 11px 12px; }
.dir2 .bp-table tbody tr + tr td { border-top: 1px solid var(--line); }
.dir2 .bp-mono { background: var(--seal-wash); color: var(--seal); }
.dir2 .bp-bname:hover { color: var(--seal); text-decoration: none; }

/* whole-row click target, with the accent rail on the row's LEADING edge in
   whichever direction the page runs */
.dir2 .bp-table tbody tr.row-link { cursor: pointer; }
.dir2 .bp-table tbody tr.row-link:hover td { background: var(--seal-wash); }
.dir2 .bp-table tbody tr.row-link:hover td:first-child {
  box-shadow: inset 3px 0 0 var(--accent); }
[dir="rtl"] .dir2 .bp-table tbody tr.row-link:hover td:first-child {
  box-shadow: inset -3px 0 0 var(--accent); }
.dir2 .bp-table tbody tr.row-link:focus-within td { background: var(--seal-wash); }


/* ── Award-list filter bar (buyer + supplier profiles) ───────────────────────
   One pane for every control over the list — category, counterparty, sort and
   the priced-only tick — so they read as one set of filters rather than three
   loose widgets. Ported from the UK; the popovers already use logical
   properties, which is what lets the same markup sit in an RTL page. */
.awf { display: flex; flex-wrap: wrap; align-items: center; position: relative;
  justify-content: flex-start; gap: var(--s2); margin: 0 0 var(--s3);
  padding: var(--s2) var(--s3); border: 1px solid var(--line);
  border-radius: var(--r-card); background: var(--paper); }

.awf-sort { display: inline-flex; align-items: center; gap: var(--s2);
  font-size: var(--t-xs); color: var(--ink-soft); }
.awf-sort select { font: inherit; font-size: var(--t-xs); color: var(--ink);
  padding: 5px var(--s2); border: 1px solid var(--line);
  border-radius: var(--r-control); background: var(--surface); }
.awf-sort select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* A reset belongs beside the controls it clears, at the far end — and stays
   hidden until something is actually narrowing the list. */
.awf-clear { margin-inline-start: auto; font: inherit; font-size: var(--t-xs);
  cursor: pointer; padding: 4px 10px; border: 0; border-radius: 999px;
  background: none; color: var(--ink-soft); text-decoration: underline; }
.awf-clear:hover { color: var(--accent-ink); }
.awf-clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* "Priced only" is a pill toggle, not a stray checkbox. */
.aw-toggle { font: inherit; font-size: var(--t-xs); cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px;
  border: 1px solid var(--line); border-radius: 999px; background: transparent;
  color: var(--ink-soft); white-space: nowrap; }
.aw-toggle:hover { border-color: var(--accent); }
.aw-toggle .aw-toggle-tick { opacity: 0; transition: opacity .12s ease; color: var(--accent-ink); }
.aw-toggle.is-on { background: var(--accent-wash); border-color: var(--accent);
  color: var(--accent-ink); font-weight: 600; }
.aw-toggle.is-on .aw-toggle-tick { opacity: 1; }
.aw-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The two choosers share one popover shell. */
.awcat { position: relative; }
.awcat-toggle { font: inherit; font-size: var(--t-xs); cursor: pointer;
  display: inline-flex; align-items: center; gap: var(--s2); max-width: 100%;
  padding: 5px 10px; border: 1px solid var(--line);
  border-radius: var(--r-control); background: var(--surface); color: var(--ink); }
.awcat-toggle:hover { border-color: var(--ink-soft); }
.awcat-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.awcat-toggle-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 16em; }
.awcat-chevron { flex: none; color: var(--ink-soft); transition: transform .15s ease; }
.awcat-toggle[aria-expanded="true"] { border-color: var(--accent); }
.awcat-toggle[aria-expanded="true"] .awcat-chevron { transform: rotate(180deg); }

.awcat-dot { flex: none; width: 9px; height: 9px; border-radius: 999px;
  background: var(--ink-soft); }
.awcat-dot.sec-works { background: var(--sec-works-ink); }
.awcat-dot.sec-digital { background: var(--sec-digital-ink); }
.awcat-dot.sec-health { background: var(--sec-health-ink); }
.awcat-dot.sec-facil { background: var(--sec-facil-ink); }
.awcat-dot.sec-supply { background: var(--sec-supply-ink); }
.awcat-dot.sec-prof { background: var(--sec-prof-ink); }
.awcat-dot.sec-other { background: var(--ink-soft); }

.awcat-panel { position: absolute; z-index: 30; inset-inline-start: 0;
  top: calc(100% + 4px); width: min(340px, 86vw); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-control);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .14); overflow: hidden; }
.awcat-head { padding: var(--s2); border-bottom: 1px solid var(--line); }
.awcat-search { width: 100%; padding: 7px var(--s3); font-size: var(--t-sm);
  border: 1px solid var(--line); border-radius: var(--r-control); background: var(--paper); }
.awcat-search:focus { outline: 2px solid var(--accent); outline-offset: 1px;
  border-color: var(--accent); }
.awcat-list { max-height: 280px; overflow-y: auto; padding: 4px; }
.awcat-opt { display: flex; align-items: center; gap: var(--s2); width: 100%;
  padding: 7px var(--s2); border: 0; border-radius: 6px; background: none;
  cursor: pointer; font: inherit; font-size: var(--t-sm); color: var(--ink);
  text-align: start; }
.awcat-opt:hover { background: var(--paper); }
.awcat-opt.is-active { background: var(--accent-wash); color: var(--accent-ink);
  font-weight: 600; }
.awcat-opt-label { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.awcat-opt-count { flex: none; color: var(--ink-soft); font-size: var(--t-xs); }
.awcat-opt.is-active .awcat-opt-count { color: var(--accent-ink); }
.awcat-empty { padding: var(--s3); margin: 0; color: var(--ink-soft);
  font-size: var(--t-sm); text-align: center; }

/* Counterparty names run long, so that panel is a touch wider. */
.awsup .awcat-panel { width: min(400px, 90vw); }

/* On a narrow screen the panel is wider than the room beside its toggle and
   would push the page sideways. Anchor it to the bar instead of the toggle. */
@media (max-width: 560px) {
  .awsup { position: static; }
  .awsup .awcat-panel { width: auto; inset-inline: 0; }
  .awf-clear { margin-inline-start: 0; }
}


/* ── Activity chart: timeline treatment + grain toggle ───────────────────────
   A TIME AXIS RUNS LEFT TO RIGHT, in Hebrew as much as in English. The chart is
   a flex row, so in an RTL page it laid the oldest bar on the right and read
   backwards against every other timeline a reader has ever seen. `direction:
   ltr` on the track fixes the order; the labels inside are short numerals and
   month abbreviations, which read correctly either way. */
.bp-chart-tl { align-items: stretch; height: 178px; gap: 7px; }
/* The 7px gap is sized for a few dozen bars. A full monthly history is ~190 of
   them, and 191 gaps are wider than the chart — flex then leaves every column
   ZERO pixels and the whole series is invisible rather than merely cramped.
   The gap tightens with the count, and past 100 each bar also claims a 3px
   floor and the track scrolls, because below about that width a bar stops being
   a bar. `flex: 1 0 3px` means they still stretch to fill a wide chart. */
.bp-chart-tl.is-tight { gap: 3px; }
.bp-chart-tl.is-dense { gap: 1px; }
/* Both crowded views take the same floor and the same escape: a bar never goes
   under 3px, and the track scrolls rather than squeezing them out of sight.
   `flex: 1 0 3px` is a floor, not a width — they still stretch to fill a wide
   chart, so this changes nothing on a desktop. */
.bp-chart-tl.is-tight, .bp-chart-tl.is-dense {
  overflow-x: auto; overscroll-behavior-x: contain; }
.bp-chart-tl.is-tight .bp-col, .bp-chart-tl.is-dense .bp-col { flex: 1 0 3px; }
.bp-chart-tl.is-tight .bp-barwrap .bp-bar,
.bp-chart-tl.is-dense .bp-barwrap .bp-bar { width: 100%; }
.bp-chart-tl .bp-col { justify-content: flex-end; gap: 5px; }
.bp-chart-tl .bp-barwrap { flex: 1; min-height: 0; position: relative; width: 100%;
  align-self: stretch; }
.bp-chart-tl .bp-barwrap .bp-bar { position: absolute; bottom: 0; left: 50%;
  transform: translateX(-50%); width: 64%; max-width: 40px; }
/* The amount, printed above its bar. */
.bp-chart-tl .bp-bval { position: absolute; left: 50%; transform: translateX(-50%);
  margin-bottom: 3px; white-space: nowrap; font-size: 9.5px; font-weight: 700;
  color: var(--ink); font-variant-numeric: tabular-nums; }
/* Many grouped bars (24 quarters, say): shrink and tighten so they don't collide. */
.bp-chart-tl .bp-bval-sm { font-size: 7px; font-weight: 600; margin-bottom: 2px;
  letter-spacing: -.03em; }
/* min-height keeps a blank label slot the same height as a filled one, so every
   bar shares one vertical scale. */
.bp-chart-tl .bp-mlabel { flex: none; font-size: 9.5px; line-height: 1.2;
  text-align: center; color: var(--ink-soft); min-height: 1.2em; }
.bp-chart-tl .bp-myr { margin-inline-start: 2px; opacity: .6; }

/* Month / quarter / year — a segmented control in the panel heading. */
.mk-grain { margin-inline-start: auto; display: inline-flex; gap: 2px; padding: 2px;
  border-radius: 8px; background: var(--seal-wash); }
.mk-grain-btn { appearance: none; border: 0; cursor: pointer; padding: 3px 9px;
  border-radius: 6px; font: inherit; font-size: 11.5px; font-weight: 600;
  line-height: 1.4; color: var(--ink-soft); background: transparent;
  letter-spacing: .01em; }
.mk-grain-btn:hover { color: var(--ink); }
/* --surface, not a literal white: the selected pill has to follow the theme or
   it burns a white chip into a dark panel. */
.mk-grain-btn.is-on { background: var(--surface); color: var(--seal);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08); }
.mk-grain-btn:focus-visible { outline: 2px solid var(--seal); outline-offset: 1px; }

/* ---------- Admin: foldable list + block header ---------- */
/* The scrape-health table is one row per source — 481 of them on IL — so it
   ships collapsed and the summary carries the number that matters (how many
   are failing) without opening it. */
.admin-fold { border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface); margin-bottom: var(--s5); }
.admin-fold > summary { cursor: pointer; padding: var(--s3) var(--s4); display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; font-weight: 600; border-radius: var(--r-card); }
.admin-fold > summary::-webkit-details-marker { display: none; }
.admin-fold > summary::marker { content: ""; }
.admin-fold > summary::after { content: "BE"; margin-inline-start: auto; color: var(--ink-soft); transition: transform .15s ease; }
.admin-fold[open] > summary::after { transform: rotate(180deg); }
.admin-fold > summary:hover { background: var(--paper); }
.admin-fold[open] > summary { border-start-start-radius: var(--r-card); border-start-end-radius: var(--r-card); border-end-start-radius: 0; border-end-end-radius: 0; border-bottom: 1px solid var(--line); }
.admin-fold .fold-note { color: var(--ink-soft); font-weight: 400; font-size: var(--t-sm); }
.admin-fold > .table-wrap { margin: 0; }

/* Title on one side, its action on the other, with room between them —
   replaces an inline flex that left the button crushed against the heading. */
.admin-block-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; margin: var(--s6) 0 var(--s2); }
.admin-block-head > .section-title { margin: 0; }
.admin-block-head form { margin: 0; }
.admin-block-head .btn { white-space: nowrap; }

/* ════════════════════════════════════════════════════════════════════════
   Dark for the paid site's PUBLIC pages — /product, /login, /signup and the
   legal pages in app chrome. Driven by the free site's preference, which the
   reader sets once on the search front door; there is no second switch here.

   The marketing page carries its own palette (`.lp { --lp-ink … }`) rather
   than the app's tokens, so widening the token block alone left it writing
   #1C2B33 ink on a #111A20 ground — 1.21:1, i.e. invisible. Everything below
   answers a value that was written for one theme when there was only one.
   ════════════════════════════════════════════════════════════════════════ */
html[data-ps-theme="dark"] body.il-pub .lp {
  --lp-ink: #E7EDF1;
  --lp-soft: #9DAFBA;
  --lp-line: #2A3A45;
  --lp-paper: #111A20;
  /* The seal is a TEXT colour on this page (kickers, marks). #16557A on the
     dark ground is 2.19:1; the same lift the app's dark block gives it. */
  --lp-seal: #7CB7DE;
  /* The oranges already carry on a dark ground (4.6:1 and 8.1:1) and they are
     the brand's signature here, so they are left alone. */
}

/* Sections that paint their own ground. Each was a light-theme composition:
   a near-white band, or a wash mixed from a light paper. */
html[data-ps-theme="dark"] body.il-pub .lp-section,
html[data-ps-theme="dark"] body.il-pub .lp-hero { background: var(--lp-paper); }
html[data-ps-theme="dark"] body.il-pub .lp-feature-alt,
html[data-ps-theme="dark"] body.il-pub .lp-sources,
html[data-ps-theme="dark"] body.il-pub .lp-stats { background: #16222B; }
html[data-ps-theme="dark"] body.il-pub .lp-mock,
html[data-ps-theme="dark"] body.il-pub .lp-window,
html[data-ps-theme="dark"] body.il-pub .lp-tile,
html[data-ps-theme="dark"] body.il-pub .lp-price-card,
html[data-ps-theme="dark"] body.il-pub .lp-faq-item {
  background: var(--surface); border-color: var(--line);
}
/* Shadows are drawn for a light ground; on a dark one they read as smudges. */
html[data-ps-theme="dark"] body.il-pub .lp-mock,
html[data-ps-theme="dark"] body.il-pub .lp-window,
html[data-ps-theme="dark"] body.il-pub .lp-tile { box-shadow: var(--shadow-card); }

/* The auth pages sit on the same public surface. .auth-card is composed
   separately below — this is the plain ground around it. */
html[data-ps-theme="dark"] body.il-pub .auth-wrap,
html[data-ps-theme="dark"] body.il-pub .auth-side {
  background: var(--surface); border-color: var(--line); box-shadow: none;
}

/* The surfaces that paint a literal white or near-white. Enumerated from the
   rendered page rather than guessed at, so the list is exactly what was left
   writing light-theme ink on a light-theme card inside a dark composition. */
html[data-ps-theme="dark"] body.il-pub .lp-stat,
html[data-ps-theme="dark"] body.il-pub .lp-step,
html[data-ps-theme="dark"] body.il-pub .lp-kcard,
html[data-ps-theme="dark"] body.il-pub .lp-q,
html[data-ps-theme="dark"] body.il-pub .lp-float,
html[data-ps-theme="dark"] body.il-pub .lp-window-url,
html[data-ps-theme="dark"] body.il-pub .lp-btn-ghost {
  background: var(--surface); border-color: var(--line); color: var(--ink);
}
/* The headers and numerals that sit a shade off their card. */
html[data-ps-theme="dark"] body.il-pub .lp-window-bar,
html[data-ps-theme="dark"] body.il-pub .lps-head,
html[data-ps-theme="dark"] body.il-pub .lps-num,
html[data-ps-theme="dark"] body.il-pub .lpt-head {
  background: var(--wash); border-color: var(--line); color: var(--ink);
}
/* The kanban column counter reads as ink on its own chip. */
html[data-ps-theme="dark"] body.il-pub .lp-col-h em { background: var(--wash); color: var(--ink); }
/* .lp-float lifts off the hero mock; the light drop-shadow becomes a smudge. */
html[data-ps-theme="dark"] body.il-pub .lp-float { box-shadow: var(--shadow-card); }
/* seal-tier is a fixed #333 written before there was a dark ground under it. */
html[data-ps-theme="dark"] body.il-pub .seal .seal-tier { color: var(--ink-soft); }
/* The score badges take --ok / --check as a GROUND. Both lift in the dark
   palette because they are text colours everywhere else, and white numerals on
   the lifted fill fall to ~2.1:1. Same answer the app's dark block gives
   --accent-fill: the fill stays lifted, the writing on it becomes ink. */
html[data-ps-theme="dark"] body.il-pub .lp-seal-mini.good,
html[data-ps-theme="dark"] body.il-pub .lp-seal-mini.mid { color: #111A20; }

/* Gradients, which a background-COLOUR sweep does not see. The comparison
   table's "with מכרזיה" column paints linear-gradient(#fff,#FFF7F0) — a white
   card. Against the dark ground its own light ink sat on white at 1.1:1, so
   the column that carries the pitch was the one unreadable panel on the page.
   The light design is "this column is warmer and lifted"; that intent is what
   is rebuilt here, not the literal white. */
html[data-ps-theme="dark"] body.il-pub .lp-compare-col.new {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 7%, var(--surface)),
    var(--surface));
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line));
  box-shadow: 0 18px 40px -24px rgb(232 101 13 / .45);
}
/* The "without" column takes --lp-paper, which in dark IS the page ground, so
   the two columns became one undivided block. Recessed instead. */
html[data-ps-theme="dark"] body.il-pub .lp-compare-col.old {
  background: var(--wash); border-color: var(--line);
}

/* ── The auth pages, dark ────────────────────────────────────────────────
   /login and /signup are a single card on an empty field, so in dark the flat
   fill read as a grey box rather than a designed surface. Same composition as
   the light page — a lifted card on a quiet ground — expressed the way a dark
   interface expresses it: a shallow gradient, a lit top edge, and a seal-tinted
   glow instead of a drop shadow that a dark ground cannot show. */
html[data-ps-theme="dark"] body.il-pub .auth-card {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--seal) 6%, var(--surface)),
    var(--surface));
  border: 1px solid var(--line);
  border-top-color: color-mix(in srgb, var(--seal) 34%, var(--line));
  box-shadow: 0 24px 60px -30px rgb(124 183 222 / .30),
              0 1px 0 rgb(255 255 255 / .04) inset;
}
html[data-ps-theme="dark"] body.il-pub .auth-card h1 { color: var(--ink); }
/* The rule either side of "או" is a hairline on white; it needs the dark line. */
html[data-ps-theme="dark"] body.il-pub .auth-sep::before,
html[data-ps-theme="dark"] body.il-pub .auth-sep::after { background: var(--line); }
/* Google's button stays white on purpose — their brand guidance specifies it,
   and it reads as a deliberate third-party control rather than an oversight. */

/* The auth forms' primary action. It was btn-block — as wide as the email
   field above it — which reads as another input rather than the thing you
   press. A normal button, centred under the field it submits. The width floor
   keeps "התחברות" (two short words) from shrinking to a chip. */
.auth-submit { display: block; margin-inline: auto; min-width: 190px; }

/* Contract-expiry years on /tender-market/intents. A list, not a chart: seven
   rows where the only quantity is a count, so a bar per row says it and a
   plotting library would be ceremony. Tokens only, so it follows the theme
   like everything else on this shell. */
.mi-years { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.mi-year { display: grid; grid-template-columns: 4ch 1fr 4ch; align-items: center;
  gap: var(--s3); font-size: var(--t-sm); }
.mi-year-k { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.mi-year-bar { height: 14px; border-radius: 4px; background: var(--wash);
  position: relative; overflow: hidden; }
.mi-year-bar::before { content: ""; position: absolute; inset: 0; width: var(--w);
  background: color-mix(in srgb, var(--seal) 45%, transparent); }
.mi-year-n { text-align: end; font-weight: 700; font-variant-numeric: tabular-nums; }
/* The forward teaser on the market page reads as a note, not a fifth table. */
.mkt-forward .mkt-more { font-size: var(--t-sm); }
/* The intents tab reuses bp-tiles / mk-leaders / mk-cols wholesale; these are
   the only two it adds — a lede above the tiles and the note under each list. */
.mi-lede { margin: 0 0 var(--s4); max-width: 76ch; }
.mi-sub { font-size: var(--t-sm); margin-top: var(--s3); }
.mi-scope { margin-top: var(--s5); }
/* The intents list reuses .t-table wholesale; these are its own two bits. */


.mi-table td a { font-weight: 500; }
/* The intents filter row: the site's segmented controls, laid out like the
   period picker on /market rather than as a bespoke bar. */
.mi-filters { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s2) var(--s4); margin: var(--s3) 0 var(--s4); }
.mi-row-sub { font-size: var(--t-sm); margin-top: 2px; }
/* The intents table's own two columns: the contract period reads as a range,
   and the source button sits at the row end like every other table's does. */
.mi-period { white-space: nowrap; }
.mi-src { text-align: end; white-space: nowrap; }
/* The expiry radar. It borrows the intents tab's furniture wholesale — tiles,
   leader lists, bar rows, table — and adds only what a 13-month curve and a
   date-plus-countdown cell need that a 5-year curve and a plain date did not. */
.xp-horizon { margin-top: var(--s4); }
/* Seven characters, because the key is "2026-12" and not "2026". Without this
   the month labels wrap and every bar in the column sits at a different height. */
.xp-months .mi-year { grid-template-columns: 7ch 1fr 5ch; }
/* Date over countdown, not date then countdown: side by side they read as one
   run-on string and the eye cannot find the date. */
.xp-end small { display: block; font-weight: 400; }
/* The way out of the buyer-page panel and into the market-wide view. */
.bp-expiring-more { font-size: var(--t-sm); margin: var(--s3) 0 0; }
/* ── the market tables, in the directory's own clothes ─────────────────────
   .xp-dir is the two market lists wearing .bp-dir (as /buyers does). What they
   add is a row that OPENS: a contract carries more than a table can show at a
   readable width, so the columns hold what you scan by and the rest waits
   underneath. */
.xp-dir tbody tr.xrow { cursor: pointer; }
.xp-dir tbody tr.xrow:hover > td,
.xp-dir tbody tr.xrow:focus-visible > td { background: var(--wash); }
.xp-dir tbody tr.xrow.is-open > td { background: var(--wash); }
/* The open row and its detail read as one block: no rule between them. */
.xp-dir tbody tr.xrow.is-open > td { border-bottom-color: transparent; }
/* One line, always. Uniform row height is what makes a long list scannable;
   the whole title is a click away. */
.xp-dir .xp-title { display: block; max-width: 34ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.xp-dir .xp-end small { display: block; font-weight: 400; }

.xrow-detail > td { padding: 0 var(--s4) var(--s4); background: var(--wash); }
.xrow-body { display: flex; flex-direction: column; gap: var(--s3);
  align-items: start; padding: var(--s3) 0 0; border-top: 1px dashed var(--line); }
.xrow-title { margin: 0; font-weight: 600; max-width: 90ch; }
/* Auto-fit rather than a fixed column count: the same block reads correctly
   with four facts or with seven, and on a phone it becomes one column. */
.xrow-facts { display: grid; gap: var(--s2) var(--s5); margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); width: 100%; }
.xrow-facts dt { font-size: var(--t-xs); color: var(--ink-soft);
  text-transform: none; letter-spacing: .02em; }
.xrow-facts dd { margin: 0; }
.xrow-hint { display: block; margin-top: 2px; }
/* Twenty categories do not fit on a row as segments, so this one is a select —
   sized and coloured to sit beside the segmented controls rather than look
   like a form dropped into the panel. */
.xp-cat-select { font: inherit; font-size: var(--t-sm); padding: 4px var(--s2);
  border: 1px solid var(--line); border-radius: var(--r2);
  background: var(--surface); color: var(--ink); max-width: 22ch; }
/* The control bar carries three groups now (horizon, scope, category) and has
   to wrap on a narrow screen without the labels drifting from their segments. */
.xp-controls { row-gap: var(--s3); }
.xp-controls .mk-period-lbl { margin-inline-start: var(--s2); }
.xp-controls .mk-period-lbl:first-child { margin-inline-start: 0; }
/* Free-text search in the control bar. It grows into whatever room is left on
   the row and drops to full width when the row wraps, so it never squeezes the
   segmented controls into two lines to make space for itself. */
.mkt-q { display: flex; align-items: center; gap: 6px; flex: 1 1 240px;
  min-width: 200px; margin: 0; }
.mkt-q-box { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0;
  padding: 6px var(--s3); border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-soft);
  transition: border-color .12s ease, box-shadow .12s ease; }
.mkt-q-box svg { flex: none; }
.mkt-q-box:focus-within { border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent); }
.mkt-q-box input { flex: 1; min-width: 0; border: 0; background: none; outline: none;
  font: inherit; font-size: var(--t-sm); color: var(--ink); }
/* The browser's own clear "x" would sit beside ours and do something subtly
   different (clears the field without re-running the search). */
.mkt-q-box input::-webkit-search-cancel-button { display: none; }
.mkt-q-clear { display: inline-flex; align-items: center; color: var(--ink-soft); }
.mkt-q-clear:hover { color: var(--accent-ink); }
/* The list heading and its search share a row. The search moved down here from
   the control bar: the controls above select which contracts exist, this one
   finds a row among them. */
/* The list heading and its search share a row, with air under them: the box
   sat flush against the table's top border and read as part of the header
   rule rather than as a control of its own. */
.mi-list-head { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--s3) var(--s4);
  margin-bottom: var(--s4); }
.mi-list-head h2 { margin: 0; }
.mi-list-head .mkt-q { flex: 0 1 320px; }
/* Admin: the priority picker in the scrape-health table, and the tier
   checkboxes on the manual scrape button. */
.src-prio { font: inherit; font-size: var(--t-sm); padding: 2px 4px;
  border: 1px solid var(--line); border-radius: 4px; background: var(--surface);
  color: var(--ink); }
.admin-prio { border: 0; margin: 0 0 var(--s3); padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--s4); }
.admin-prio legend { padding: 0; margin-bottom: 4px; }
.admin-prio-opt { display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--t-sm); }

/* ── Logged-out topbar on phones ─────────────────────────────────────────
   Kept at the very end on purpose: the max-width:720px block above sets
   .topbar-inner's padding with the SHORTHAND, which beats a padding-inline
   longhand written earlier however specific it is. This was the difference
   between fitting at 360px and not. */
/* Below ~480px the logged-out topbar did not fit: brand (105) + "תפריט" (81) +
   the login/signup pair (165) plus the gaps came to 387 in a 346px content
   box, and nothing could give — .nav is a nowrap flex row and every child is
   sized by its own padding. The page scrolled sideways by the difference.

   Nothing is hidden to fix it; the cluster just stops being generous with
   space it does not have. Scoped to the public auth pair, which only exists
   when logged out — the signed-in bar has always fitted. */
@media (max-width: 480px) {
  .topbar-inner { gap: var(--s3); }
  /* A flex item defaults to min-width:auto and so refuses to shrink below its
     content. Without this the rules below only move the overflow around. */
  .topbar-inner .nav { min-width: 0; }
  .brand { flex: none; }
  .nav-auth { margin-inline-start: var(--s2); gap: var(--s2); }
  .nav .nav-auth .nav-pub-login { padding: 7px 10px; }
  /* Through .nav-auth as well: a later .btn.btn-primary rule matches this
     anchor with the same specificity and would otherwise keep its own
     padding, which is what left the cluster one pixel over the edge. */
  .nav .nav-auth .nav-signup { padding: 8px 12px; font-size: var(--t-sm); }
}

/* Narrower still. "התחברות" cannot be dropped here — it is the only route to
   the login page; the "תפריט" menu carries the marketing pages only. So the
   bar keeps all four items and simply gets smaller, which at 320px is the
   difference between fitting and a sideways-scrolling page. */
@media (max-width: 400px) {
  .topbar-inner { gap: var(--s2); padding-inline: var(--s3); }
  .brand { font-size: 19px; }
  .nav-auth { margin-inline-start: 4px; gap: 6px; }
  .nav .nav-auth .nav-pub-login,
  .nav .nav-auth .nav-signup { padding: 7px 9px; font-size: 13px; }
}

/* The marketing mock cards set the page's minimum width on small phones: the
   match-card row is a nowrap flex line (score + title + verdict pill) whose
   parts add up to more than a 320px screen once the shell padding is taken
   off. It was the last thing forcing the whole page to scroll sideways.

   The row is allowed to wrap — the pill drops under the title, which reads
   perfectly well on a phone — and the shell gives back some of its gutter.
   Nothing is hidden and the desktop composition is untouched. */
@media (max-width: 420px) {
  .lp-shell { padding: 0 14px; }
  .lp-mock-row { flex-wrap: wrap; gap: 8px 10px; padding: 10px; }
  .lp-mock-main { flex: 1 1 60%; }
  .lp-seal-mini { width: 32px; height: 32px; }
}

/* 320px (iPhone SE and friends). Four items — brand, תפריט, התחברות, הרשמו —
   still do not fit at the sizes above, and none of them can go: the menu holds
   the marketing pages and the pair is the only route to signing in. So the bar
   is allowed to take a second line here rather than push the page sideways. */
@media (max-width: 340px) {
  .topbar-inner { flex-wrap: wrap; row-gap: 8px; }
  /* Through :has() as well — the rule that gives the nav `flex: 1` is written
     as .topbar-inner:has(.nav-pub-links) .nav, which outranks a plain
     descendant selector however late it appears. Without matching it the nav
     stayed on the first line and OVERLAPPED the wordmark, which is worse than
     the scroll this replaced. */
  .topbar-inner .nav,
  .topbar-inner:has(.nav-pub-links) .nav { flex: 1 0 100%; justify-content: flex-end; }
  .nav-auth { margin-inline-start: 0; }
}

/* ══ The story chapters ════════════════════════════════════════════════════
   The marketing middle used to be thirteen parallel blocks, each announcing
   another capability. Six numbered chapters instead, and the shape is the one
   the UK page uses because that shape is doing a job: a small number chip says
   "this is a sequence, not a list", copy and evidence sit side by side so the
   claim and its proof are read together, and the sides alternate so six
   chapters do not settle into a rhythm the eye stops seeing.

   Every colour is --lp-*: the landing declares its own token set (.lp) and the
   app tokens are undefined inside it. Every visual is BUILT rather than
   screenshotted — it has to stay legible at 320px and follow the dark theme,
   and a screenshot does neither. */
.lp-story { padding-block: var(--s7); }
.st-ch { display: grid; grid-template-columns: 1.05fr 1fr;
  gap: var(--s6) 72px; align-items: center;
  padding-block: clamp(40px, 5.5vw, 76px); }
.st-ch + .st-ch { border-top: 1px solid color-mix(in srgb, var(--lp-line) 55%, transparent); }
/* Alternating sides. The visual moves, not the copy — the text edge stays put
   so the reading line never shifts. */
.st-ch.is-rev .st-vis { order: -1; }
.st-copy { min-width: 0; }
.st-vis { min-width: 0; }

.st-k { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--t-xs); letter-spacing: .06em; color: var(--lp-soft);
  margin-bottom: var(--s3); }
.st-kx { display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: 6px; font-weight: 700; font-family: "Sora", sans-serif;
  background: color-mix(in srgb, var(--lp-seal) 12%, transparent);
  color: var(--lp-seal); }
/* The one chapter nobody else can ship says so, the way the UK page marks its
   own edge — a pill, not a louder heading. */
.st-edge-pill { display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--t-xs); font-weight: 700; letter-spacing: 0;
  color: var(--lp-seal); background: color-mix(in srgb, var(--lp-seal) 12%, transparent);
  border-radius: 999px; padding: 2px 9px; }
.st-edge-pill svg { color: var(--lp-accent); }

.st-h { margin: 0 0 10px; font-family: "Sora", sans-serif; font-weight: 700;
  font-size: clamp(22px, 3vw, 30px); line-height: 1.22; text-wrap: balance;
  color: var(--lp-ink); }
.st-p { margin: 0; font-size: 16px; line-height: 1.65; color: var(--lp-soft); }
.st-p b { color: var(--lp-ink); }
.st-ev { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5);
  margin-top: var(--s4); padding-top: var(--s4);
  border-top: 1px dashed var(--lp-line); font-size: var(--t-sm); color: var(--lp-soft); }
.st-ev b { font-family: "Sora", sans-serif; font-size: 20px; color: var(--lp-ink);
  margin-inline-end: 6px; }
.st-facts { list-style: none; margin: var(--s4) 0 0; padding: 0; display: grid; gap: 8px; }
.st-facts li { display: flex; align-items: flex-start; gap: 8px;
  font-size: var(--t-sm); line-height: 1.55; color: var(--lp-soft); }
.st-facts svg { flex: none; margin-top: 3px; color: #1E8E5A; }
.st-note { margin: var(--s3) 0 0; font-size: 12.5px; line-height: 1.55;
  color: var(--lp-soft); opacity: .85; }

/* ── the built visuals ───────────────────────────────────────────────────── */
.st-card { background: #fff; border: 1px solid var(--lp-line); border-radius: 14px;
  padding: var(--s4); box-shadow: 0 1px 2px rgba(28,43,51,.04); }
.st-card-h { display: flex; align-items: center; gap: 7px; font-weight: 700;
  font-size: var(--t-sm); color: var(--lp-ink); margin-bottom: var(--s3); }
.st-card-h svg { color: var(--lp-seal); }
.st-card-f { margin-top: var(--s3); padding-top: var(--s3);
  border-top: 1px solid var(--lp-line); font-size: 12px; color: var(--lp-soft);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.st-card-f b { color: var(--lp-ink); }

/* 01 — the fragmentation, drawn. Every chip is a place a tender can hide. */
.st-scatter { display: flex; flex-wrap: wrap; gap: 8px; }
.st-chip { display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 999px; font-size: 12.5px;
  border: 1px solid var(--lp-line); color: var(--lp-soft); background: var(--lp-paper); }
.st-chip svg { color: var(--lp-seal); }
.st-chip.is-more { border-style: dashed; }

/* 02 — the ranked list */
.st-mock { display: grid; gap: 10px; }
.st-row { display: flex; align-items: center; gap: 10px; }
.st-row.is-dim { opacity: .45; }
.st-seal { flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; font-family: "Sora", sans-serif;
  font-size: 13px; font-weight: 700; color: #fff; background: #1E8E5A;
  font-variant-numeric: tabular-nums; }
.st-seal.mid { background: #B7791F; }
.st-seal.low { background: var(--lp-soft); }
.st-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.st-row-main b { font-size: 14px; color: var(--lp-ink); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.st-row-main small { font-size: 12px; color: var(--lp-soft); }
.st-pill { flex: none; display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; padding: 4px 9px; border-radius: 999px; }
.st-pill.ok { background: #E8F5EE; color: #1E8E5A; }
.st-pill.warn { background: #FDF3E3; color: #B7791F; }

/* 03 — the thresholds, decided */
.st-checks { display: grid; gap: 9px; }
.st-check { display: flex; align-items: center; gap: 9px; font-size: 13.5px;
  color: var(--lp-ink); }
.st-check span { flex: 1; min-width: 0; }
.st-check em { font-style: normal; font-size: 11px; font-weight: 700;
  padding: 3px 8px; border-radius: 999px; }
.st-check.ok svg, .st-check.ok em { color: #1E8E5A; }
.st-check.ok em { background: #E8F5EE; }
.st-check.warn svg, .st-check.warn em { color: #B7791F; }
.st-check.warn em { background: #FDF3E3; }
.st-check.bad svg, .st-check.bad em { color: #C0392B; }
.st-check.bad em { background: #FBEAE8; }
.st-check-foot { margin-top: 2px; padding-top: var(--s3);
  border-top: 1px solid var(--lp-line); font-size: 12px; color: var(--lp-soft);
  display: flex; align-items: center; gap: 6px; }
.st-check-foot svg { color: #B7791F; }

/* 04 — who buys, scaled against the leader */
.st-bars { display: grid; gap: 7px; }
.st-bar { position: relative; display: flex; align-items: center;
  justify-content: space-between; gap: 10px; padding: 7px 10px;
  border-radius: 8px; font-size: 12.5px; color: var(--lp-ink); overflow: hidden;
  background: color-mix(in srgb, var(--lp-seal) 7%, transparent); }
.st-bar::before { content: ""; position: absolute; inset: 0; width: var(--w);
  background: color-mix(in srgb, var(--lp-seal) 16%, transparent); }
.st-bar > * { position: relative; }
.st-bar-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-bar-v { flex: none; font-weight: 700; }

/* 07 — competition: share of wins against share of money.
   Two bars per category on ONE scale (both are percentages of the same whole),
   stacked rather than side by side, because the vertical gap between them is
   the entire point — 4% of the awards, 57% of the money. Drawing a single
   "concentration" number would hide exactly what a bidder needs to see.
   The name sits in its own column so the bars share a left edge and stay
   comparable across rows. */
.st-comp { display: grid; gap: 9px; }
.st-cmp { display: grid; grid-template-columns: minmax(0, 8.5em) 1fr;
  align-items: center; gap: 10px; font-size: 12px; }
.st-cmp-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--lp-ink); }
.st-cmp-pair { display: grid; gap: 3px; min-width: 0; }
.st-cmp-row { display: flex; align-items: center; gap: 7px;
  color: var(--lp-soft); white-space: nowrap; }
.st-cmp-bar { flex: none; height: 7px; width: var(--w); min-width: 3px;
  border-radius: 999px; }
.st-cmp-bar.is-count {
  background: color-mix(in srgb, var(--lp-seal) 26%, transparent); }
.st-cmp-bar.is-value { background: var(--lp-accent); }
.st-cmp-row b { color: var(--lp-ink); font-weight: 700; }

/* 05 — the countdown.
   One grid for the whole card, with each row `display: contents`, so the four
   bars line up in a column that is sized to the longest label. The rows used
   to be grids of their own with a fixed 9ch label track; "עוד 11 חודשים" is
   thirteen characters and nowrap, so it ran straight over the bar beside it.
   The bar keeps a floor and the subject is allowed to ellipsis, because
   max-content on both edges squeezed the middle to nothing on a phone. */
.st-count { display: grid; row-gap: 9px; column-gap: 0;
  grid-template-columns: max-content minmax(44px, 1fr) minmax(0, max-content); }
/* The card's own heading and footnote are grid items now that the rows are
   `display: contents` — left to auto-place they take the first and last cells
   and shift every row one column along, which is what put the label under the
   bar. */
.st-count > .st-card-h, .st-count > .st-card-f { grid-column: 1 / -1; }
.st-cd { display: contents; }
.st-cd > * { align-self: center; font-size: 12px; color: var(--lp-soft); }
.st-cd-w { white-space: nowrap; padding-inline-end: 10px; }
.st-cd-bar { height: 8px; border-radius: 999px; position: relative; overflow: hidden;
  background: color-mix(in srgb, var(--lp-seal) 10%, transparent); }
.st-cd-bar::before { content: ""; position: absolute; inset: 0; width: var(--w);
  background: color-mix(in srgb, var(--lp-accent) 55%, transparent); }
.st-cd-s { padding-inline-start: 10px; color: var(--lp-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 06 — the board. It used to be four columns of empty rectangles, which is
   what "a board, suggested" looks like when nobody puts anything on it: a card
   that failed to load. Two real columns with real rows instead. */
.st-board { display: grid; gap: 10px; grid-template-columns: 1fr 1fr; }
.st-board > .st-card-h, .st-board > .st-card-f { grid-column: 1 / -1; }
.st-bcol { display: grid; gap: 8px; align-content: start; min-width: 0; }
.st-bh { display: flex; align-items: center; gap: 6px; font-size: 11px;
  font-weight: 700; color: var(--lp-soft); }
.st-bh i { font-style: normal; font-size: 10px; font-weight: 700;
  min-width: 16px; text-align: center; border-radius: 999px; padding: 1px 5px;
  background: color-mix(in srgb, var(--lp-seal) 12%, transparent); color: var(--lp-seal); }
.st-bcard { display: grid; gap: 6px; padding: 8px 9px; border-radius: 8px;
  background: var(--lp-paper); border: 1px solid var(--lp-line);
  border-inline-start: 3px solid color-mix(in srgb, var(--lp-accent) 60%, var(--lp-line)); }
.st-bcard.is-done { border-inline-start-color: #1E8E5A; }
.st-bcard b { font-size: 12.5px; line-height: 1.35; color: var(--lp-ink); }
.st-bmeta { display: flex; align-items: center; gap: 7px; }
.st-who { flex: none; font-style: normal; font-size: 10px; font-weight: 700;
  width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--lp-seal) 14%, transparent); color: var(--lp-seal); }
.st-due { display: inline-flex; align-items: center; gap: 4px; font-size: 11px;
  color: var(--lp-soft); }
.st-due svg { flex: none; }
.st-due.urgent { color: #B7791F; font-weight: 600; }
.st-due.ok { color: #1E8E5A; }

/* ── Chapter arrival + the rail ─────────────────────────────────────────────
   The hidden state is gated on BOTH `.st-rv-on` (set by story.js) and
   prefers-reduced-motion, so the failure of either leaves every chapter
   visible. Nothing here may be the only thing standing between a reader and
   the content. */
@media (prefers-reduced-motion: no-preference) {
  .st-rv-on [data-rv] { opacity: 0; transform: translateY(16px); }
  .st-rv-on [data-rv].is-in { opacity: 1; transform: none;
    transition: opacity .5s cubic-bezier(.22,.61,.36,1),
                transform .5s cubic-bezier(.22,.61,.36,1);
    transition-delay: calc(var(--rvi, 0) * 90ms); }
}

/* The rail is built by story.js and lives on the reading edge — which in
   Hebrew is the left, and `inset-inline-end` is that in both directions. */
.st-rail { position: fixed; inset-inline-end: 20px; top: 50%;
  transform: translateY(-50%); z-index: 40;
  display: flex; flex-direction: column; gap: 12px; }
.st-raildot { position: relative; width: 9px; height: 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--lp-seal) 28%, transparent);
  transition: background .2s ease, height .2s ease; }
.st-raildot:hover { background: color-mix(in srgb, var(--lp-seal) 55%, transparent); }
.st-raildot.is-on { background: var(--lp-accent); height: 24px; }
.st-railtip { position: absolute; inset-inline-end: 18px; top: 50%;
  transform: translateY(-50%); white-space: nowrap;
  font-size: var(--t-xs); color: var(--lp-soft);
  background: var(--lp-paper); border: 1px solid var(--lp-line);
  border-radius: 6px; padding: 2px 8px;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.st-raildot:hover .st-railtip, .st-raildot:focus-visible .st-railtip { opacity: 1; }
@media (max-width: 959px) { .st-rail { display: none; } }

/* 03 — the query. Field / operator / value get three weights, which is the
   whole reason the advanced mode is legible: you can see the shape of the
   query before you read it. */
.st-qry { display: grid; gap: 8px; }
.st-qline { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 9px 10px; border-radius: 8px; background: var(--lp-paper);
  border: 1px solid var(--lp-line); font-size: 12.5px; line-height: 1.5; }
.st-qline span { white-space: nowrap; }
.q-f { font-weight: 700; color: var(--lp-seal); }
.q-o { color: var(--lp-soft); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.q-v { color: var(--lp-ink); background: color-mix(in srgb, var(--lp-accent) 12%, transparent);
  border-radius: 4px; padding: 1px 6px; }
.q-b { font-size: 11px; font-weight: 700; letter-spacing: .04em; color: var(--lp-soft);
  border: 1px solid var(--lp-line); border-radius: 4px; padding: 1px 5px; }

@media (max-width: 860px) {
  /* One column. The visual follows its copy rather than leading, so the
     alternation stops mattering and every chapter reads the same way down. */
  .st-ch, .st-ch.is-rev { grid-template-columns: 1fr; gap: var(--s4); }
  .st-ch.is-rev .st-vis { order: 0; }
  .st-ev b { font-size: 17px; }
  .st-row-main b { white-space: normal; }
  .st-board { grid-template-columns: 1fr; }
}

/* The chapter surfaces under the dark public theme. Everything else rides the
   --lp-* tokens, which body.il-pub already re-declares. */
html[data-ps-theme="dark"] body.il-pub .st-card {
  background: var(--surface); border-color: var(--line); box-shadow: none; }
html[data-ps-theme="dark"] body.il-pub .st-chip,
html[data-ps-theme="dark"] body.il-pub .st-col i {
  background: color-mix(in srgb, var(--surface) 60%, transparent);
  border-color: var(--line); }
html[data-ps-theme="dark"] body.il-pub .st-pill.ok,
html[data-ps-theme="dark"] body.il-pub .st-check.ok em {
  background: color-mix(in srgb, #1E8E5A 22%, transparent); color: #7FD3A6; }
html[data-ps-theme="dark"] body.il-pub .st-pill.warn,
html[data-ps-theme="dark"] body.il-pub .st-check.warn em {
  background: color-mix(in srgb, #B7791F 22%, transparent); color: #E9C27C; }
html[data-ps-theme="dark"] body.il-pub .st-check.bad em {
  background: color-mix(in srgb, #C0392B 22%, transparent); color: #F0A79E; }
html[data-ps-theme="dark"] body.il-pub .st-check.ok svg { color: #7FD3A6; }
html[data-ps-theme="dark"] body.il-pub .st-check.warn svg { color: #E9C27C; }
html[data-ps-theme="dark"] body.il-pub .st-check.bad svg { color: #F0A79E; }
html[data-ps-theme="dark"] body.il-pub .st-facts svg { color: #7FD3A6; }
/* The board's rows, the query lines and the countdown all paint --lp-paper on
   top of a card that is itself --surface in dark; nudge them apart so the
   inset still reads as inset. The two literal greens/ambers get the same
   treatment as the pills above — a flat #1E8E5A on a dark ground is a hole. */
html[data-ps-theme="dark"] body.il-pub .st-bcard,
html[data-ps-theme="dark"] body.il-pub .st-qline {
  background: color-mix(in srgb, var(--paper) 55%, transparent);
  border-color: var(--line); }
html[data-ps-theme="dark"] body.il-pub .st-bcard.is-done {
  border-inline-start-color: #7FD3A6; }
html[data-ps-theme="dark"] body.il-pub .st-due.ok { color: #7FD3A6; }
html[data-ps-theme="dark"] body.il-pub .st-due.urgent { color: #E9C27C; }

/* The area column needs a fairer share. It was getting 102px — 70px of content
   once padding is off — against 275px for the buyer, so a two-word category
   like "בריאות ורפואה" ellipsised while the buyer name had room to spare.
   Clipping a label that would fit in a fairer share is not a fix, it is the
   same loss with better manners.

   Set on the HEADER cell, and that is the whole trick: this table is
   table-layout:fixed, so column widths come from the first row and a
   min-width on a body <td> is ignored outright — which is why the first
   attempt at this measured as having changed nothing at all. */
/* Percentages, because .bp-dir already sizes these columns that way and this
   table is table-layout:fixed — a min-width on a body cell is ignored outright,
   which is why two earlier attempts at this measured as having changed
   nothing. `table.` on the front to match .bp-dir's specificity; source order
   then decides, and this file appends.
   The 6% comes from the CONTRACT column, not the buyer. Taking it from the
   buyer clipped 18 of 25 authority names — swapping one truncation for
   another. The contract title is already cut to one line on purpose, with the
   whole of it in the drawer below, so it is the one column here that can give
   space up without losing anything a reader cannot get back. The .bp-dir rule
   itself is left alone: the buyers and suppliers directories share it. */
table.xp-dir th:nth-child(2), table.xp-dir td:nth-child(2) { width: 17%; }
table.xp-dir th:nth-child(3), table.xp-dir td:nth-child(3) { width: 16%; }

/* ── Tracked-tender verdict: the match card's readiness folded into one line
   under the saved card's title; opens in place and never opens the row. ── */
.sc-verdict { margin: 6px 0 2px; }
.kb-meta + .sc-verdict { margin: 4px 0 2px; }
.scv-summary { margin: var(--s2) 0 0; font-size: var(--t-sm); line-height: 1.5; color: var(--ink); }
.scv-line { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; max-width: 100%;
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer; font: inherit;
  text-align: start; color: var(--ink); }
.scv-line .rd-badge { font-size: var(--t-sm); }
.scv-line .rd-tally { white-space: normal; }
.scv-line .chev { color: var(--ink-soft); transition: transform .18s ease; }
.sc-verdict.is-open .scv-line .chev { transform: rotate(180deg); }
.scv-line:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.scv-body { display: none; margin: 6px 0 2px; padding: var(--s2) var(--s3);
  background: var(--paper); border-radius: var(--r-control); border-inline-start: 2px solid var(--line); }
.sc-verdict.is-open .scv-body { display: block; }
.sc-verdict.rd-ready .scv-body { border-inline-start-color: var(--ok); }
.sc-verdict.rd-almost .scv-body { border-inline-start-color: var(--check); }
.sc-verdict.rd-blocked .scv-body { border-inline-start-color: var(--bad); }
.scv-body .rd-items, .scv-body .rd-prep { margin-top: var(--s2); }

/* "מהתיאור שלכם זיהינו" — the sectors the free-text description declares,
   shown under the field as it is typed. Informational chips: they already
   count in matching, so there is nothing to click. */
.sector-hints { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: -4px 0 var(--s3); font-size: var(--t-sm); }
.sector-hints[hidden] { display: none; }
.sh-chips { display: contents; }
.sh-chip { padding: 3px 9px; font-size: var(--t-xs); cursor: default; }
.sh-note { flex-basis: 100%; }

/* ── Visitor journeys (admin → free search) ────────────────────────────────
   One row per person, in the order they did things. Two nested <details>: the
   whole section is closed, and each row opens into its own story — so the
   panel costs nothing to scroll past and everything is one click away. No
   JavaScript: the section is injected with innerHTML, where a <script> never
   runs, and <details> needs none.

   Grid, not a table. A row's cells hold wildly different content — three
   Hebrew search terms in one, a single time in the next — and a table column
   sized for the widest term would leave the rest of the row empty. */
.jrn { padding: 0; }
.jrn > .jrn-sum { padding: 14px 16px; }
.jrn[open] > .jrn-sum { border-bottom: 1px solid var(--line); }
.jrn-sum { cursor: pointer; display: flex; align-items: baseline;
  flex-wrap: wrap; gap: 4px 10px; list-style: none; }
.jrn-sum::-webkit-details-marker { display: none; }
.jrn-sum::before { content: "▸"; color: var(--ink-soft); font-size: 11px;
  transition: transform .15s ease; }
.jrn[open] > .jrn-sum::before { transform: rotate(-90deg); }
.jrn-sum-t { font-size: var(--t-base); font-weight: 700; color: var(--ink); }
.jrn-sum-n { font-size: var(--t-sm); color: var(--seal); font-weight: 600; }
.jrn-sum-hint { margin-inline-start: auto; }

/* The funnel. Same numbers as the rows below it, on the same people. */
.jrn-funnel { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 16px 0; }
.jrn-fstep { flex: 1 1 92px; background: var(--seal-wash); border-radius: 8px;
  padding: 8px 10px; display: flex; flex-direction: column; gap: 1px; }
.jrn-fstep b { font-size: var(--t-lg); font-weight: 700; color: var(--ink);
  line-height: 1.1; }
.jrn-fstep span { font-size: 11px; color: var(--ink-soft); }
.jrn-fstep i { font-size: 11px; font-style: normal; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }
.jrn-fstep.is-bad b { color: var(--accent-ink); }
.jrn-fstep.is-good b { color: var(--ok); }

.jrn-basenote { margin: 0; padding: 12px 16px 0; }
.jrn-lead { margin: 12px 16px 0; padding: 10px 12px; border-radius: 8px;
  background: var(--wash); font-size: var(--t-sm);
  line-height: 1.55; color: var(--ink); }

/* The rows. Capped so a busy week cannot set the height of the whole tab. */
.jrn-rows { margin-top: 12px; max-height: 620px; overflow-y: auto;
  overscroll-behavior: contain; }
.jrn-row { border-top: 1px solid var(--line); }
.jrn-row > summary { cursor: pointer; list-style: none; padding: 9px 16px;
  display: grid; align-items: center; gap: 4px 10px;
  grid-template-columns: 52px minmax(90px, auto) minmax(120px, 1.4fr)
                         minmax(0, 78px) minmax(0, 1fr) 52px minmax(0, 104px); }
.jrn-row > summary::-webkit-details-marker { display: none; }
.jrn-row > summary:hover { background: var(--seal-wash); }
.jrn-row[open] > summary { background: var(--seal-wash); }

.jrn-when { display: flex; flex-direction: column; line-height: 1.2; }
.jrn-when b { font-size: var(--t-sm); font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.jrn-when i { font-size: 10px; font-style: normal; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }

.jrn-who { display: flex; flex-wrap: wrap; gap: 3px; }
.jrn-tag { font-size: 10px; padding: 1px 5px; border-radius: 4px;
  background: var(--line); color: var(--ink-soft); white-space: nowrap; }
.jrn-tag.is-good { background: var(--ok-wash); color: var(--ok); }
.jrn-tag.is-warm { background: var(--accent-wash); color: var(--accent-ink); }
/* The link back to this visitor's previous session of the same day. A LINK,
   not a label: the sequence is the point, and jumping to it beats scanning the
   table for a matching six-character tag. */
.jrn-tag.is-back { background: var(--seal-wash); color: var(--seal);
  font-weight: 600; text-decoration: none; }
.jrn-tag.is-back:hover { background: var(--seal); color: var(--surface); }
/* Which visit of the day this is, worn by the visitor tag so two rows with the
   same tag are visibly the same person twice rather than a duplicate. */
.jrn-seq { font-weight: 700; color: var(--seal); }
/* Landing on an anchored session should be obvious after the jump. */
.jrn-row:target { background: var(--seal-wash); }
.jrn-row:target > summary { background: var(--seal-wash); }

.jrn-asked { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
/* A search term is the one thing on this row the operator came to read, so it
   gets the only quoted, full-contrast treatment — and it wraps rather than
   truncating, because half a Hebrew phrase is not a shorter phrase. */
.jrn-term { font-size: var(--t-sm); color: var(--ink); font-weight: 600;
  background: var(--wash); border-radius: 4px;
  padding: 1px 6px; }
.jrn-term::before { content: "\201d"; opacity: .45; }
.jrn-term::after { content: "\201c"; opacity: .45; }

.jrn-got { font-size: 11px; color: var(--ink-soft); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.jrn-did { display: flex; flex-wrap: wrap; gap: 3px; min-width: 0; }
.jrn-pill { font-size: 10px; padding: 1px 6px; border-radius: 999px;
  background: var(--line); color: var(--ink-soft); white-space: nowrap; }
/* Only the destination that means "this visit worked" is coloured. Colouring
   every pill would make the row a rainbow and teach the eye to skip it. */
.jrn-c-source { background: var(--ok-wash); color: var(--ok); font-weight: 600; }
.jrn-c-funnel { background: var(--ok-wash); color: var(--ok); font-weight: 600; }
.jrn-dwell { font-size: 11px; color: var(--ink-soft); white-space: nowrap; }

.jrn-verdict { display: flex; justify-content: flex-end; }
.jrn-v { font-size: 10px; padding: 2px 7px; border-radius: 999px;
  white-space: nowrap; font-weight: 600; }
.jrn-v-bad { background: var(--accent-wash); color: var(--accent-ink); }
.jrn-v-warn { background: var(--accent-wash); color: var(--accent-ink); }
.jrn-v-soft { background: var(--line); color: var(--ink-soft); }
.jrn-v-good { background: var(--ok-wash); color: var(--ok); }

/* The opened story. A rail down the side carries the eye through the order,
   which is the only thing this view has that the summary row does not. */
.jrn-story { margin: 0; padding: 4px 30px 4px 16px; list-style: none;
  border-inline-start: 2px solid var(--line); margin-inline-start: 22px; }
.jrn-step { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  padding: 4px 0; font-size: var(--t-sm); line-height: 1.5; }
.jrn-t { font-size: 10px; color: var(--ink-soft); min-width: 34px; }
.jrn-act { font-size: 11px; color: var(--ink-soft); }
.jrn-label { font-size: 11px; color: var(--ink); }
.jrn-link { font-size: 11px; color: var(--seal); max-width: 340px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: inline-block; vertical-align: bottom; }
.jrn-foot { padding: 2px 16px 12px 16px; font-size: 11px; }
.jrn-note { padding: 10px 16px 14px; font-size: 11px; line-height: 1.6; }

/* Narrow: the grid collapses to two lines, keeping the row readable rather
   than squeezing seven columns into 380px. */
@media (max-width: 900px) {
  .jrn-row > summary { grid-template-columns: 56px 1fr auto; }
  .jrn-who, .jrn-did { grid-column: 2 / -1; }
  .jrn-asked { grid-column: 1 / -1; }
  .jrn-verdict { justify-content: flex-start; grid-column: 1 / -1; }
  .jrn-link { max-width: 200px; }
}

/* ── Sub-tabs inside the IL search panel ───────────────────────────────────
   CSS-ONLY, and that is load-bearing rather than clever: this panel arrives by
   fetch and is written with innerHTML, where a <script> NEVER executes. A JS
   tab bar would render and do nothing, which is exactly how every control on
   the UK frameworks page shipped dead. Radio inputs give focus, arrow-key
   movement and screen-reader semantics for free.

   The inputs must PRECEDE both the tab bar and the panes: ~ only reaches
   forward. */
.ilx-radio { position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  border: 0; }
.ilx-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line);
  margin-bottom: var(--s4); }
.ilx-tabs label { cursor: pointer; padding: 8px 14px; font-size: var(--t-sm);
  font-weight: 600; color: var(--ink-soft); border-bottom: 2px solid transparent;
  margin-bottom: -1px; display: inline-flex; align-items: center; gap: 6px; }
.ilx-tabs label:hover { color: var(--ink); }
.ilx-n { font-size: 11px; font-variant-numeric: tabular-nums;
  background: var(--line); color: var(--ink-soft); border-radius: 999px;
  padding: 0 6px; }
/* Focus must be visible: the input itself is off-screen, so the label wears it. */
.ilx-radio:focus-visible + .ilx-radio + .ilx-tabs label[for="ilx-t-overview"],
.ilx-radio:focus-visible ~ .ilx-tabs label[for="ilx-t-journeys"] {
  outline: 2px solid var(--seal); outline-offset: -2px; border-radius: 6px; }
#ilx-t-overview:checked ~ .ilx-tabs label[for="ilx-t-overview"],
#ilx-t-journeys:checked ~ .ilx-tabs label[for="ilx-t-journeys"] {
  color: var(--ink); border-bottom-color: var(--seal); }
#ilx-t-overview:checked ~ .ilx-tabs label[for="ilx-t-overview"] .ilx-n,
#ilx-t-journeys:checked ~ .ilx-tabs label[for="ilx-t-journeys"] .ilx-n {
  background: var(--seal-wash); color: var(--seal); }

.ilx-pane { display: none; }
#ilx-t-overview:checked ~ .ilx-pane-overview,
#ilx-t-journeys:checked ~ .ilx-pane-journeys { display: block; }

/* ── One day at a time ─────────────────────────────────────────────────────
   A day is the only grouping this data supports: the visitor hash is salted
   per day, so there is no identity spanning the week to group by. */
.ilx-days { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: var(--s4); }
.ilx-day { cursor: pointer; display: flex; flex-direction: column;
  align-items: center; gap: 1px; padding: 7px 12px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); min-width: 74px; }
.ilx-day:hover { border-color: var(--line-hover); }
.ilx-day b { font-size: 12px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.ilx-day i { font-size: 10px; font-style: normal; color: var(--ink-soft); }
.ilx-day span { font-size: 15px; font-weight: 700; color: var(--seal); }
/* A day with nobody on it should read as empty at a glance, not as a number
   you have to stop and parse. */
.ilx-day.is-quiet { opacity: .55; }
.ilx-day.is-quiet span { color: var(--ink-soft); }

.ilx-daypane { display: none; }
#ilx-d-0:checked ~ [data-day="0"], #ilx-d-1:checked ~ [data-day="1"],
#ilx-d-2:checked ~ [data-day="2"], #ilx-d-3:checked ~ [data-day="3"],
#ilx-d-4:checked ~ [data-day="4"], #ilx-d-5:checked ~ [data-day="5"],
#ilx-d-6:checked ~ [data-day="6"] { display: block; }
#ilx-d-0:checked ~ .ilx-days label[for="ilx-d-0"],
#ilx-d-1:checked ~ .ilx-days label[for="ilx-d-1"],
#ilx-d-2:checked ~ .ilx-days label[for="ilx-d-2"],
#ilx-d-3:checked ~ .ilx-days label[for="ilx-d-3"],
#ilx-d-4:checked ~ .ilx-days label[for="ilx-d-4"],
#ilx-d-5:checked ~ .ilx-days label[for="ilx-d-5"],
#ilx-d-6:checked ~ .ilx-days label[for="ilx-d-6"] {
  border-color: var(--seal); background: var(--seal-wash); opacity: 1; }

/* Where the visit began and ended, above the step-by-step trail. */
.jrn-landing { display: flex; flex-wrap: wrap; gap: 4px 16px;
  padding: 8px 16px 4px; font-size: 11px; color: var(--ink-soft); }
.jrn-landing em { font-style: normal; opacity: .75; margin-inline-end: 4px; }
.jrn-landing span span { color: var(--ink); }
.jrn-tag-id { font-size: 10px; font-style: normal; color: var(--ink-soft);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }


/* ── /jobs — the free municipal jobs board ─────────────────────────────────
   The list rides the tender search's chassis — .ps-form, .ps-chips,
   .ps-filters, .ps-card, .ps-pager — so the two products read as one family
   and behave the same under the hand. What lives here is only what the board
   adds: the two-part wordmark, the browse band under the hero, the card's
   closing-soon edge, and the job page. Tokens only, so both themes hold. */
.jb-wm-sub { color: var(--accent-ink); font-weight: 400; margin-inline-start: .06em; }
.ps-wordmark-lg .jb-wm-sub { font-size: .8em; }
/* the wordmark is a way home, not a text link: no underline on hover */
.jb-topbar .ps-wordmark:hover, .jb-topbar .ps-wordmark:hover .jb-wm-sub { text-decoration: none; }
.jb-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.jb-skip { position: absolute; inset-inline-start: -999px; top: 8px; padding: 8px 12px; background: var(--ink); color: var(--paper, #fff); border-radius: 8px; z-index: 5; }
.jb-skip:focus { inset-inline-start: 16px; }
.jb-muted { color: var(--ink-soft); font-weight: 400; }
.jb-n { font-size: .85em; opacity: .65; margin-inline-start: 5px; font-variant-numeric: tabular-nums; }
.jb-hint { margin: 10px 0 0; color: var(--ink-soft); font-size: 13px; }
.jb-left { color: var(--accent-ink); margin-inline-end: 8px; }
.jb-verified { margin: 24px 0 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.55; }
.jb-side-note { margin: 24px 0 0; font-size: 14px; color: var(--ink-soft); line-height: 1.5; }

/* the browse band under the hero: a way in without typing */
.jb-browse { max-width: 720px; margin: 0 auto; padding: 26px 0 10px; border-top: 1px solid var(--line); }
.jb-browse-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.jb-browse-l { font-size: 12.5px; color: var(--ink-soft); margin-inline-end: 4px; }

/* the results page is a little wider than the tender search's 720px: its
   toolbar carries five menus and the switch, and on a desktop they belong on
   one row. Pills lose a little padding for the same reason. */
.jb-list-main .ps-shell { max-width: 860px; }
@media (min-width: 940px) {
  .jb-list-main .ps-filters { flex-wrap: nowrap; gap: 10px; }
  .jb-list-main .ps-filters > * { flex: none; }
  .jb-list-main body.ps-body .ps-facet > summary, body.ps-body .jb-list-main .ps-facet > summary { padding: 6px 12px; white-space: nowrap; }
  .jb-list-main .ps-seg-opt { padding: 4px 11px; white-space: nowrap; }
}

/* the sentence's reading, beside the removable chips: same pill, quieter,
   and not a link — it is what the words meant, not a filter that was picked */
.jb-reading { display: contents; }
.ps-chip.jb-chip-read { background: color-mix(in srgb, var(--ink) 6%, var(--surface));
  border-color: var(--line); color: var(--ink); cursor: default; }

.jb-card-teaser-label { font-weight: 600; color: var(--ink); }

@media (max-width: 640px) {
  .ps-wordmark-lg .jb-wm-sub { display: block; font-size: .62em; margin: 2px 0 0; }
  /* the facts strip stacks two-by-two on a phone instead of four hairline columns */
  .jb-card .ps-fact { flex: 1 1 45%; min-width: 0; margin-bottom: 8px; }
  .jb-card .ps-fact:nth-child(odd) { padding-inline-start: 0; border-inline-start: 0; }
}

/* one job */
.jb-main { max-width: 960px; margin-inline: auto; padding: 0 16px 56px; font-size: 17px; line-height: 1.5; }
.jb-main :focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
.jb-job { max-width: 760px; margin: 24px auto 56px; }
.jb-job .jb-card-top { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: baseline; font-size: 15px; color: var(--ink-soft); margin: 0 0 6px; }
.jb-job .jb-card-pub { font-weight: 600; color: var(--ink); text-decoration: none; }
.jb-job .jb-card-cat { color: var(--accent-ink); text-decoration: none; }
.jb-job .jb-card-pub:hover, .jb-job .jb-card-cat:hover { text-decoration: underline; }
.jb-crumb { font-size: 15px; margin: 0 0 14px; }
.jb-crumb a { color: var(--seal); text-decoration: none; }
.jb-job-title { margin: 4px 0 18px; font-size: clamp(23px, 3.4vw, 32px); line-height: 1.25; text-wrap: balance; }
.jb-facts-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px 24px; margin: 0 0 22px; padding: 18px;
  border: 1.5px solid var(--line); border-radius: 16px; background: var(--card, transparent); }
.jb-facts-list dt { font-size: 14px; color: var(--ink-soft); margin: 0 0 2px; }
.jb-facts-list dd { margin: 0; font-size: 17px; }
.jb-facts-list .is-soon dd { color: var(--accent-ink); font-weight: 600; }
.jb-desc { line-height: 1.65; margin: 0 0 22px; }
.jb-docs h2 { font-size: 18px; margin: 0 0 8px; }
.jb-docs ul { margin: 0 0 22px; padding-inline-start: 1.2em; line-height: 1.8; }
.jb-docs a { color: var(--seal); }
.jb-more-at { font-size: 16px; }
.jb-more-at a { color: var(--seal); }
.jb-desc { white-space: pre-line; }
.jb-apply-top { margin: -8px 0 22px; font-size: 16px; }
.jb-apply-top a { color: var(--seal); font-weight: 600; text-decoration: none; }
.jb-apply-top a:hover { text-decoration: underline; }
/* what the notice says: the lists a seeker reads to decide */
.jb-fit { margin: 0 0 26px; }
.jb-fit-h { font-size: 20px; margin: 22px 0 8px; letter-spacing: -0.005em; }
.jb-fit-h:first-child { margin-top: 0; }
.jb-fit-sub { font-size: 15px; font-weight: 600; color: var(--ink-soft); margin: 12px 0 4px; text-transform: none; }
.jb-fit-sub-nice { color: var(--accent-ink); }
.jb-fit-list { margin: 0; padding-inline-start: 1.15em; line-height: 1.6; }
.jb-fit-list li { margin: 0 0 6px; }
.jb-fit-list li::marker { color: var(--seal); }
.jb-fit-nice li::marker { color: var(--accent); }
.jb-fit-multi { margin: 0 0 12px; padding: 10px 14px; border-radius: 12px; background: color-mix(in srgb, var(--accent) 12%, transparent); font-size: 15px; }
.jb-fit-note { margin: 16px 0 0; font-size: 14px; color: var(--ink-soft); line-height: 1.5; }
.jb-fit-note a { color: var(--seal); }
/* the card's one line from the notice */
.jb-card-teaser { margin: -4px 0 10px; font-size: 15px; color: var(--ink-soft); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.jb-card-teaser-label { color: var(--ink); font-weight: 600; }

/* ── the admin's jobs-board tab: three CSS-only sub-tabs (scrape / audience /
   journeys) and the per-day radios, the same mechanism as the ilsearch panel
   (.ilx-*), with its own ids so both panels can sit in one page. */
.jbx-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin: 0 0 var(--s4); }
.jbx-tabs label { cursor: pointer; padding: 8px 14px; font-size: var(--t-sm); color: var(--ink-soft);
  border-bottom: 2px solid transparent; margin-bottom: -1px; }
.jbx-tabs label:hover { color: var(--ink); }
#jbx-t-scrape:checked ~ .jbx-tabs label[for="jbx-t-scrape"],
#jbx-t-audience:checked ~ .jbx-tabs label[for="jbx-t-audience"],
#jbx-t-journeys:checked ~ .jbx-tabs label[for="jbx-t-journeys"] { color: var(--seal); border-color: var(--seal); font-weight: 600; }
.jbx-pane { display: none; }
#jbx-t-scrape:checked ~ .jbx-pane-scrape,
#jbx-t-audience:checked ~ .jbx-pane-audience,
#jbx-t-journeys:checked ~ .jbx-pane-journeys { display: block; }
.jbx-daypane { display: none; }
#jbx-d-0:checked ~ [data-day="0"], #jbx-d-1:checked ~ [data-day="1"],
#jbx-d-2:checked ~ [data-day="2"], #jbx-d-3:checked ~ [data-day="3"],
#jbx-d-4:checked ~ [data-day="4"], #jbx-d-5:checked ~ [data-day="5"],
#jbx-d-6:checked ~ [data-day="6"] { display: block; }
#jbx-d-0:checked ~ .ilx-days label[for="jbx-d-0"], #jbx-d-1:checked ~ .ilx-days label[for="jbx-d-1"],
#jbx-d-2:checked ~ .ilx-days label[for="jbx-d-2"], #jbx-d-3:checked ~ .ilx-days label[for="jbx-d-3"],
#jbx-d-4:checked ~ .ilx-days label[for="jbx-d-4"], #jbx-d-5:checked ~ .ilx-days label[for="jbx-d-5"],
#jbx-d-6:checked ~ .ilx-days label[for="jbx-d-6"] { border-color: var(--seal); color: var(--seal); }
.jbx-src-bar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 0 0 var(--s4); }
.jbx-cov { font-variant-numeric: tabular-nums; }
.jbx-cov .is-low { color: var(--accent-ink); }
