/* ==========================================================================
   b2b.asydata.com — the register, read like a ledger

   ASYDATA is a cabinet where one accountant holds ten firms and the screen is
   full of numbers that carry legal weight. This is the same person on the day
   before signing: they have a counterparty's IDNO and want to know whether the
   company is real, who controls it, what has changed, and whether it lives off
   public money. Same reader, same silence.

   So this is not a document that happens to be on a screen. It is a ledger view
   of one company, and it inherits ASYDATA's north star wholesale — "registrul
   liniștit": the data is the spectacle, the chassis keeps quiet.

   What that means, in their words and enforced here:

     One voice.      A single saturated colour, the forest green, and only for
                     the primary action and the active state. If two things
                     compete for it, one of them is wrong.
     Weight, not size. Hierarchy comes from weight and colour. A section title is
                     15.5px against a 13px body — a gap you feel, not one you
                     measure. Only a metric may be large.
     No page title.  A display heading spends exactly the first screen the reader
                     came for. Identity is carried by the bar and the record's
                     own head.
     Layered, not ruled. Cards lift off slate by a fine border and a low-alpha
                     shadow. Never a hard shadow, never a box drawn for its own
                     sake.
     Aligned figures. Anything comparable down a column is tabular and mono. A
                     column of sums that dances is a bug, not a preference.

   Tokens mirror src/index.css in the ASYDATA frontend; the control kit mirrors
   components/ui. Where the two disagree, that repository is right.
   ========================================================================== */

/* --- Faces ---------------------------------------------------------------
   Self-hosted with Cyrillic subsets: much of the registry's people data is
   Cyrillic, and a Latin-only build renders those real records in a fallback. */

/* Inter and JetBrains Mono arrive from ASYDATA, self-hosted here rather than
   linked from a CDN for the same reason every other face on this page is: much
   of the registry's people data is Cyrillic, and the app declares a strict
   security policy that an external font host would have to be opened for.

   One file per subset, not per weight: Google now serves both families as
   variable fonts, and the four "weights" it hands back are byte-identical. Named
   without a weight and declared across the axis, so the browser fetches 208 KB
   once instead of the same bytes four times. */
@font-face { font-family:'Inter'; font-weight:100 900; font-style:normal; font-display:swap;
  src:url('fonts/Inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2192,U+2212,U+2215; }
@font-face { font-family:'Inter'; font-weight:100 900; font-style:normal; font-display:swap;
  src:url('fonts/Inter-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+1E00-1EFF,U+2020,U+20A0-20AB,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Inter'; font-weight:100 900; font-style:normal; font-display:swap;
  src:url('fonts/Inter-cyrillic.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }

@font-face { font-family:'JetBrains Mono'; font-weight:100 800; font-style:normal; font-display:swap;
  src:url('fonts/JetBrainsMono-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2192,U+2212,U+2215; }
@font-face { font-family:'JetBrains Mono'; font-weight:100 800; font-style:normal; font-display:swap;
  src:url('fonts/JetBrainsMono-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+1E00-1EFF,U+2020,U+20A0-20AB,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'JetBrains Mono'; font-weight:100 800; font-style:normal; font-display:swap;
  src:url('fonts/JetBrainsMono-cyrillic.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }

/* --- Tokens -------------------------------------------------------------- */

/* Day is the default; `.dark` on <html> is the night theme, exactly as ASYDATA
   does it. Every value below is that repository's, and where this page needs a
   token it does not have -- a hatch, a "deep" ink for text on a status tint --
   the new one is derived on their pattern rather than invented next to it. */
:root {
  color-scheme:light;

  /* Surfaces -- cool slate, never the warm paper this page began with. Cold
     neutrals read as precise and add no emotion where none is wanted, which is
     the reasoning the accounting side gives, and the shared ramp is what makes
     two products look like one company. */
  --color-bg:#F8FAFC; --color-bg-2:#F1F5F9;
  --color-surface:#FFFFFF; --color-surface-2:#F8FAFC;
  --color-border:#E2E8F0; --color-border-strong:#CBD5E1;

  /* Text */
  /* muted is secondary prose and metadata -- anything the reader actually
     reads. muted-2 is the disabled rung only: at 11-12px it lands at 2.56:1 on
     surface, under AA, so text that carries meaning never sits on it. */
  --color-fg:#0F172A; --color-muted:#64748B; --color-muted-2:#94A3B8;

  /* Brand -- the forest green, and the only saturated colour on the page. Here
     it owns the validity apparatus and the primary action, nothing else. */
  --color-brand:#1F7A4D; --color-brand-2:#3AA073;
  --color-brand-fg:#FFFFFF; --color-brand-soft:#E8F3ED;
  --color-brand-deep:#15603C;

  /* Semantic status, one source. The register only ever needs two of these: a
     superseded record is `warn`, a struck one is `danger`. */
  --color-success:#059669; --color-warn:#D97706;
  --color-danger:#E11D48;  --color-info:#0284C7;
  --color-warn-soft:#FEF3C7;   --color-warn-deep:#78350F;
  --color-danger-soft:#FFE4E6; --color-danger-deep:#9F1239;

  --hatch:rgba(31,122,77,0.045);

  /* Type -- Inter for everything, JetBrains Mono for figures. The serif is gone:
     ASYDATA builds hierarchy from weight, and a second visual identity here is
     the exact thing the system exists to avoid. */
  --font-sans:'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono:'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* The ladder, and the point of it is how little the rungs differ: a section
     title is 15.5px against a 13px body -- a gap you feel rather than measure.
     Only a metric may be large, because a figure is the one thing worth saying
     loudly. */
  --text-micro:10px; --text-label:11px; --text-caption:12px;
  --text-base:13px; --text-lg:14px; --text-title:15.5px; --text-metric:28px;

  /* Shape by role: field, card, panel -- one radius each, so nothing drifts. */
  --radius-field:6px; --radius-card:12px; --radius-panel:16px;

  /* Elevation -- "floating crisp". Three layers at very low alpha: a contact
     shadow, a mid lift, and a wide soft one that does most of the work. A single
     hard shadow reads as a widget; this reads as a sheet resting on the ground. */
  --shadow-card:
    0 1px 3px rgba(0,0,0,0.02),
    0 4px 12px -2px rgba(0,0,0,0.03),
    0 12px 30px -4px rgba(0,0,0,0.04);
  --shadow-card-hover:
    0 1px 3px rgba(0,0,0,0.02),
    0 8px 24px -4px rgba(0,0,0,0.06),
    0 20px 48px -6px rgba(0,0,0,0.08);
  --shadow-soft:0 1px 2px rgba(0,0,0,0.02);
  --shadow-brand-glow:0 4px 14px -2px rgba(31,122,77,0.22);

  --measure:72ch;
  --gutter:clamp(1.25rem, 4vw, 3rem);
  --ease:cubic-bezier(0.16, 1, 0.3, 1);
}

/* Night. Grounds are lifted off near-black towards ~#121212 to avoid halation,
   and kept on a real elevation scale (bg < surface < surface-2) so a dense page
   does not flatten into one dark field. Text is off-white, never pure, or it
   vibrates. Brand and status are desaturated: the day palette at full chroma
   glares on a dark ground. */
html.dark {
  color-scheme:dark;

  --color-bg:#111417; --color-bg-2:#262D35;
  --color-surface:#191D22; --color-surface-2:#20262C;
  --color-border:#2C343C; --color-border-strong:#3A444E;

  --color-fg:#E2E6E1; --color-muted:#99A29B; --color-muted-2:#737C76;

  --color-brand:#3EB27C; --color-brand-2:#57C393;
  --color-brand-fg:#08140D; --color-brand-soft:rgba(62,178,124,0.14);
  /* "deep" means further from the ground, which on a dark ground is lighter. */
  --color-brand-deep:#57C393;

  --color-success:#3EB57E; --color-warn:#E0A84D;
  --color-danger:#E86C7E;  --color-info:#4EA6D4;
  --color-warn-soft:rgba(224,168,77,0.16);    --color-warn-deep:#E8BC72;
  --color-danger-soft:rgba(232,108,126,0.16); --color-danger-deep:#F0919F;

  --hatch:rgba(87,195,147,0.07);

  --shadow-card:
    0 1px 0 rgba(255,255,255,0.04) inset,
    0 1px 2px rgba(0,0,0,0.4),
    0 4px 14px -6px rgba(0,0,0,0.4);
  --shadow-card-hover:
    0 1px 0 rgba(255,255,255,0.06) inset,
    0 16px 36px -8px rgba(0,0,0,0.55),
    0 4px 12px -4px rgba(0,0,0,0.35);
  --shadow-soft:0 1px 2px rgba(0,0,0,0.25);
  --shadow-brand-glow:
    0 1px 0 rgba(255,255,255,0.08) inset,
    0 12px 36px -8px rgba(63,214,143,0.42);
}

*,*::before,*::after { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }

body {
  margin:0; background:var(--color-bg); color:var(--color-fg);
  font:400 var(--text-base)/1.5 var(--font-sans);
  font-synthesis-weight:none; text-rendering:optimizeLegibility;
}

/* --- Browser surfaces: the parts we did not draw still carry the design --- */

::selection { background:var(--color-brand); color:var(--color-brand-fg); }
::placeholder { color:var(--color-muted); opacity:0.8; }

* { scrollbar-width:thin; scrollbar-color:var(--color-border) transparent; }
*::-webkit-scrollbar { width:10px; height:10px; }
*::-webkit-scrollbar-track { background:transparent; }
*::-webkit-scrollbar-thumb { background:var(--color-border); border:3px solid var(--color-bg); border-radius:99px; }
*::-webkit-scrollbar-thumb:hover { background:var(--color-muted-2); }

a { color:var(--color-brand); text-decoration-thickness:1px; text-underline-offset:0.18em; }
a:hover { color:var(--color-brand-deep); }

/* Identifiers are measured values: columns must hold as digits change. */
/* Every identifier, count and sum already carries .num, so this one rule moves
   the whole numeric surface onto the mono face. Slightly smaller because
   JetBrains Mono runs wider than Inter at the same size, and an IDNO should not
   outweigh the company's name beside it. */
.num { font-family:var(--font-mono); font-variant-numeric:tabular-nums;
  font-size:0.94em; letter-spacing:0; }

/* --- Document furniture -------------------------------------------------- */

.sheet { max-width:74rem; margin:0 auto; padding:0 var(--gutter) 3rem; }

/* Compact bar, not a title block. ASYDATA gives the first viewport to data:
   a page-sized heading would spend exactly the space the reader came for. */
.masthead { display:flex; flex-wrap:wrap; align-items:center; gap:0.75rem 1.5rem;
  padding:0.9rem 0; border-bottom:1px solid var(--color-border); }
.masthead__issuer { flex:1 1 auto; display:flex; align-items:baseline; gap:0.75rem;
  margin:0; font:700 var(--text-title)/1.2 var(--font-sans); letter-spacing:-0.025em; }
.masthead__issuer span { font:700 var(--text-micro)/1.3 var(--font-sans);
  letter-spacing:0.09em; text-transform:uppercase; color:var(--color-brand); }
.masthead__issuer a { color:var(--color-fg); text-decoration:none; }
.masthead__issuer a:hover { color:var(--color-brand); }

/* Section navigation reads as navigation, not as part of the title. */
.masthead__link { font:500 var(--text-caption)/1.3 var(--font-sans); color:var(--color-muted);
  text-decoration:none; padding:0.3rem 0.6rem; border-radius:var(--radius-field); }
.masthead__link:hover { color:var(--color-fg); background:var(--color-bg-2); }

/* The validity seal. Not decoration: it carries the snapshot the whole surface
   answers from, and changes state when that answer goes stale. */
.seal { position:relative; display:grid; gap:0.15rem; min-width:15rem;
  padding:0.7rem 1rem 0.7rem 3.1rem; border:1px solid var(--color-brand); border-radius:2px;
  background:repeating-linear-gradient(-45deg, transparent 0 5px, var(--hatch) 5px 6px), var(--color-brand-soft);
  color:var(--color-brand-deep); }
.seal__mark { position:absolute; left:0.85rem; top:50%; transform:translateY(-50%); }
.seal__label { font-size:var(--text-label); font-weight:600; letter-spacing:0.1em; text-transform:uppercase; }
.seal__value { font:600 var(--text-base)/1.4 var(--font-sans); }
.seal__meta { font-size:var(--text-label); color:var(--color-brand); }
.seal[data-state='stale'] { border-color:var(--color-warn); background:var(--color-warn-soft); color:var(--color-warn-deep); }
.seal[data-state='stale'] .seal__meta { color:var(--color-warn); }
.seal[data-state='unknown'] { border-color:var(--color-border); background:var(--color-bg-2); color:var(--color-muted); }
.seal[data-state='unknown'] .seal__meta { color:var(--color-muted); }

/* --- The request line: a form field on a document, not a website search --- */

.request { padding:2.25rem 0 1.5rem; }
.request__label { display:block; margin-bottom:0.4rem;
  font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.025em;
  text-transform:uppercase; color:var(--color-muted); }
.request__line { display:flex; align-items:stretch; gap:0.5rem; }
.request__field { flex:1; min-width:0; }
/* The native search affordance is unstyleable across engines and reads as
   foreign chrome on a document; the request button is the affordance here. */
.request__field::-webkit-search-cancel-button,
.request__field::-webkit-search-decoration { -webkit-appearance:none; appearance:none; }

/* Six filters share one row and split it evenly, so a select can't grow to its
   natural width and push a sibling onto a lonely second line. minmax(0,1fr) lets
   each cell shrink below the control's intrinsic width; the control fills its cell. */
.filters { display:grid; grid-template-columns:repeat(6, minmax(0, 1fr));
  gap:0.85rem 1.25rem; padding-top:1rem; align-items:end; }
.filter { display:grid; gap:0.25rem; }
.filter > span { font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.025em;
  text-transform:uppercase; color:var(--color-muted); }
.filter select, .filter input { min-width:0; width:100%; }

/* Medium widths: two balanced rows of three rather than six cramped columns. */
@media (max-width: 68rem) {
  .filters { grid-template-columns:repeat(3, minmax(0, 1fr)); }
}

/* --- Register: ruled rows, nothing enclosed ------------------------------ */

.tally { display:flex; justify-content:space-between; gap:1rem; padding:1.5rem 0 0.5rem;
  border-bottom:1px solid var(--color-border); font-size:var(--text-label); font-weight:600;
  letter-spacing:0.1em; text-transform:uppercase; color:var(--color-muted); }

.register { list-style:none; margin:0; padding:0; }
.entry { position:relative; cursor:pointer;
  display:grid; grid-template-columns:1fr auto; gap:0.15rem 1.5rem;
  padding:1.15rem 0; border-bottom:1px solid var(--color-border); }
.entry:hover { background:linear-gradient(90deg, var(--color-bg-2), transparent 75%); }
.entry__name a::after { content:""; position:absolute; inset:0; }

/* The identifier is the exception: it sits above the overlay and stays
   selectable, because copying an IDNO is a core action on this page and a
   stretched link would otherwise swallow the selection. */
.entry__ident b { position:relative; z-index:1; cursor:text; }

.entry__name { grid-column:1; margin:0; font:600 var(--text-lg)/1.3 var(--font-sans); letter-spacing:-0.01em; }
.entry__name a { color:var(--color-fg); text-decoration:underline; text-decoration-color:transparent;
  text-decoration-thickness:1px; text-underline-offset:0.16em; transition:text-decoration-color 0.16s var(--ease); }
.entry__name a:hover { color:var(--color-brand-deep); text-decoration-color:var(--color-brand); }

.entry__ident { grid-column:1; margin:0; color:var(--color-muted); }
.entry__ident b { font-weight:500; color:var(--color-fg); }
.entry__place { grid-column:1; margin:0; color:var(--color-muted); }

/* Status is the largest thing after the name — it is what changes the decision.
   Kind sits beneath it in the same cell; spanning rows stretched the middle row. */
.entry__status { grid-column:2; grid-row:1 / span 3; align-self:start; justify-self:end;
  display:grid; gap:0.35rem; justify-items:end; text-align:right; }
.entry__kind { margin:0; font-size:var(--text-label); color:var(--color-muted); }

.status { display:inline-flex; align-items:center; gap:0.4rem; white-space:nowrap;
  padding:0.35rem 0.6rem; border:1px solid currentColor; border-radius:2px;
  font:600 var(--text-label)/1 var(--font-sans); letter-spacing:0.1em; text-transform:uppercase; }
.status--active { color:var(--color-brand); background:var(--color-brand-soft); }
.status--liquidated { color:var(--color-danger); background:var(--color-danger-soft); }
.status--absent { color:var(--color-warn); background:var(--color-warn-soft); }

/* --- Extract ------------------------------------------------------------- */

.extract { padding:1rem 0 3rem; }
.extract__head { display:flex; flex-wrap:wrap; align-items:center; gap:0.5rem 1.5rem;
  margin-top:1rem; padding:1.25rem; background:var(--color-surface);
  border:1px solid var(--color-border); border-radius:var(--radius-card); box-shadow:var(--shadow-card); }
.extract__ident { flex:1 1 24rem; }
.extract__title { margin:0; font:700 var(--text-metric)/1.15 var(--font-sans);
  letter-spacing:-0.025em; text-wrap:balance; }
.extract__legal { margin:0.25rem 0 0; font-size:var(--text-caption); color:var(--color-muted); }
/* A struck record reads as struck: the document says so in its own voice. */
.extract[data-struck='true'] .extract__title { text-decoration:line-through;
  text-decoration-thickness:2px; text-decoration-color:var(--color-danger); }

.fields { display:grid; grid-template-columns:minmax(11rem,16rem) 1fr; margin:0; padding:0; }
.fields > dt { grid-column:1; padding:0.5rem 1.5rem 0.5rem 0; border-bottom:1px solid var(--color-border);
  font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.025em; text-transform:uppercase;
  color:var(--color-muted); align-self:center; }
.fields > dd { grid-column:2; margin:0; padding:0.5rem 0; border-bottom:1px solid var(--color-border);
  font-weight:500; align-self:center; }
.fields > dd[data-empty='true'] { color:var(--color-muted); font-weight:400; font-style:italic; }

/* The blank form: real labels over empty ruled values, so an unsearched page is
   obviously a form awaiting entry rather than a failed load. */
.fields--blank > dt { color:var(--color-muted); }
.fields--blank > dd { min-height:1.7em; }

/* A card, lifted by shadow. The extract used hairline rules on flat ground;
   ASYDATA layers surfaces instead, and the layering is what makes a dense page
   readable without drawing boxes around everything. */
.section { margin-top:1rem; padding:1.25rem; background:var(--color-surface);
  border:1px solid var(--color-border); border-radius:var(--radius-card); box-shadow:var(--shadow-card); }
.section > h2 { margin:0 0 0.85rem; padding-bottom:0;
  font:700 var(--text-title)/1.3 var(--font-sans); letter-spacing:-0.025em; }

.people { list-style:none; margin:0; padding:0; }
.people li { display:flex; flex-wrap:wrap; gap:0.3rem 0.9rem; align-items:baseline;
  padding:0.6rem 0; border-bottom:1px solid var(--color-border); }
.people__name { font-weight:500; }
.people__role { font-size:var(--text-label); font-weight:600; letter-spacing:0.08em;
  text-transform:uppercase; color:var(--color-muted); }
.people__share { margin-left:auto; font-weight:600; color:var(--color-brand-deep); }

.acts { list-style:none; margin:0; padding:0; }
.acts li { display:grid; grid-template-columns:5.5rem 1fr auto; gap:0.9rem; align-items:baseline;
  padding:0.55rem 0; border-bottom:1px solid var(--color-border); }
.acts__code { font-weight:600; color:var(--color-muted); }
.acts__caem { font-size:var(--text-label); color:var(--color-muted); white-space:nowrap; }
.acts li[data-licensed='true'] .acts__code { color:var(--color-brand-deep); }

/* Provenance closes the document, as a certification statement does. Its rule
   spans the sheet; only the reading text is held to a measure. */
.provenance { margin-top:3rem; padding-top:1.25rem; border-top:2px solid var(--color-border-strong);
  font-family:var(--font-sans); color:var(--color-muted); }
.provenance p { margin:0 0 0.5rem; max-width:var(--measure); }
.provenance dl { display:grid; grid-template-columns:max-content 1fr; gap:0.2rem 1rem;
  margin:0.75rem 0 0; font-family:var(--font-sans); font-size:var(--text-label); }
.provenance dt { color:var(--color-muted); text-transform:uppercase; letter-spacing:0.08em; font-weight:600; }
.provenance dd { margin:0; }

/* --- Notices: absence is a finding, stated plainly ----------------------- */

.notice { display:flex; gap:0.75rem; align-items:flex-start; margin:1.25rem 0;
  padding:0.9rem 1.1rem; border:1px solid var(--color-warn); border-radius:2px;
  background:var(--color-warn-soft); color:var(--color-warn-deep); }
.notice--color-danger { border-color:var(--color-danger); background:var(--color-danger-soft); color:var(--color-danger-deep); }
.notice p { margin:0; }
.notice strong { display:block; font-weight:600; }

.empty { padding:2.5rem 0 1.75rem; color:var(--color-muted); font:400 var(--text-lg)/1.5 var(--font-sans); }
.failure { padding:4rem 0; text-align:center; color:var(--color-danger); font:400 var(--text-lg)/1.5 var(--font-sans); }

/* --- Chrome -------------------------------------------------------------- */

.langs { display:flex; gap:0.15rem; }
.langs button { padding:0.35rem 0.5rem; cursor:pointer; border:1px solid transparent; border-radius:2px;
  background:transparent; color:var(--color-muted); font:600 var(--text-label)/1 var(--font-sans);
  letter-spacing:0.08em; text-transform:uppercase; }
.langs button:hover { color:var(--color-fg); }
.langs button[aria-pressed='true'] { color:var(--color-brand-deep); border-color:var(--color-brand); background:var(--color-brand-soft); }

.pager { display:flex; gap:1rem; align-items:center; justify-content:center; padding:2rem 0; }
.pager button { padding:0.6rem 1rem; cursor:pointer; border:1px solid var(--color-border); border-radius:2px;
  background:transparent; color:var(--color-fg); font:600 var(--text-label)/1 var(--font-sans);
  letter-spacing:0.1em; text-transform:uppercase; }
.pager button:hover:not(:disabled) { border-color:var(--color-fg); }
.pager button:disabled { color:var(--color-muted-2); cursor:default; }
.pager span { font-size:var(--text-label); letter-spacing:0.08em; text-transform:uppercase; color:var(--color-muted); }

.back { display:inline-flex; align-items:center; gap:0.4rem; padding:0.5rem 0; margin-bottom:0.5rem;
  border:0; background:transparent; cursor:pointer; color:var(--color-muted);
  font:600 var(--text-label)/1 var(--font-sans); letter-spacing:0.1em; text-transform:uppercase;
  text-decoration:none; }
.back:hover { color:var(--color-brand-deep); }

.colophon { border-top:1px solid var(--color-border); padding:1.5rem 0 3rem;
  color:var(--color-muted); font-size:var(--text-label); }

.visually-hidden { position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* --- The one authored moment ---------------------------------------------
   The seal stamps when a fresh answer lands: a document being certified. It
   fires on results only, so it stays an event rather than an idle. */

@keyframes stamp {
  0%   { transform:scale(1.06) rotate(-1.1deg); opacity:0.5; }
  60%  { transform:scale(0.995) rotate(0.12deg); opacity:1; }
  100% { transform:scale(1) rotate(0deg); opacity:1; }
}
.seal[data-stamping='true'] { animation:stamp 0.44s var(--ease); }

@media (prefers-reduced-motion: reduce) {
  *,*::before,*::after { animation-duration:0.001ms !important; transition-duration:0.001ms !important; }
}

/* --- Narrow: checked on a phone beside a printed contract ---------------- */

@media (max-width: 44rem) {
  .fields { grid-template-columns:1fr; }
  .fields > dt { grid-column:1; padding-bottom:0; border-bottom:0;
    font:600 var(--text-label)/1.4 var(--font-sans); letter-spacing:0.1em;
    text-transform:uppercase; color:var(--color-muted); }
  .fields > dd { grid-column:1; padding-top:0.15rem; }

  .entry { grid-template-columns:1fr; }
  .entry__status { grid-column:1; grid-row:auto; justify-self:start; justify-items:start;
    text-align:left; margin-top:0.5rem; grid-auto-flow:column; align-items:center; gap:0.6rem; }

  .filters { display:grid; grid-template-columns:1fr 1fr; gap:0.75rem 1rem; }
  .filter select, .filter input { min-width:0; width:100%; }

  .acts li { grid-template-columns:4.5rem 1fr; }
  .acts__caem { grid-column:2; }

  .seal { min-width:0; width:100%; }
}

/* --- Enrichment sections: procurement, financials, contact ---------------
   Same ruled-document grammar as the registry fields. Money is tabular and
   emphasised; the honesty notes and attribution carry provenance in the
   document's own voice. */

.section-note { margin:0 0 1rem; max-width:var(--measure); color:var(--color-muted);
  font-family:var(--font-sans); font-size:var(--text-base); }
.attribution { margin:1rem 0 0; color:var(--color-muted); font-size:var(--text-label); font-style:italic; }

.money { font-variant-numeric:tabular-nums; }
.fields > dd.money { font-weight:600; }
.muted { color:var(--color-muted); }

/* Awarded-contract list — ruled rows, nothing enclosed. */
.contracts { list-style:none; margin:1.25rem 0 0; padding:0; }
.contracts li { display:grid; grid-template-columns:9rem 1fr auto; gap:0.4rem 1.25rem;
  align-items:baseline; padding:0.7rem 0; border-bottom:1px solid var(--color-border); }
.contract__date { color:var(--color-muted); font-size:var(--text-label); white-space:nowrap; }
.contract__body { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.3rem 0.7rem; }
.contract__subject { font-weight:500; }
.contract__buyer { color:var(--color-muted); }
.contract__amount { font-weight:600; white-space:nowrap; }
.contract__link { font-size:var(--text-label); }
.contracts li[data-kind="amendment"] .contract__amount::before { content:"± "; color:var(--color-warn); }
.contracts li[data-kind="cancellation"] .contract__subject {
  text-decoration:line-through; text-decoration-color:var(--color-danger); }
.contracts li[data-quarantined="true"] { opacity:0.55; }

.tag { font-size:var(--text-label); font-weight:600; letter-spacing:0.06em; text-transform:uppercase;
  padding:0.1rem 0.45rem; border:1px solid var(--color-border); border-radius:2px; color:var(--color-muted); }

/* Financial statements table. */
.scroll { overflow-x:auto; }
.fin { width:100%; border-collapse:collapse; font-variant-numeric:tabular-nums; }
.fin th, .fin td { padding:0.55rem 0.9rem; border-bottom:1px solid var(--color-border); text-align:left; }
.fin th.num, .fin td.num { text-align:right; }
.fin th { font:600 var(--text-label)/1.4 var(--font-sans); letter-spacing:0.08em;
  text-transform:uppercase; color:var(--color-muted); }
.fin thead th { border-bottom:1px solid var(--color-border-strong); }

@media (max-width: 44rem) {
  .contracts li { grid-template-columns:1fr auto; }
  .contract__date { grid-column:1 / -1; }
}

/* --- Procurement discovery: landing entry + search-row signal ------------ */

.browse { display:flex; width:100%; align-items:center; justify-content:space-between; gap:1rem;
  margin:1.5rem 0; padding:1.1rem 1.25rem; cursor:pointer; text-align:left;
  background:var(--color-bg); border:1px solid var(--color-border-strong); border-radius:2px;
  color:var(--color-fg); font:inherit; transition:background 0.18s var(--ease); }
.browse:hover { background:var(--color-bg-2); }
.browse__body { display:grid; gap:0.15rem; }
.browse__label { font:600 var(--text-lg)/1.2 var(--font-sans); letter-spacing:-0.01em; }
.browse__hint { font-size:var(--text-label); color:var(--color-muted); }
.browse__arrow { font-size:var(--text-lg); color:var(--color-muted); transition:transform 0.18s var(--ease); }
.browse:hover .browse__arrow { transform:translateX(3px); color:var(--color-fg); }

/* One public-contracts marker on a search row. Green tint marks the category,
   like the active-status badge; the money itself stays in ink. */
.entry__proc { grid-column:1; margin:0.35rem 0 0; display:flex; align-items:baseline;
  flex-wrap:wrap; gap:0.4rem 0.6rem; }
.tag--proc { color:var(--color-brand-deep); border-color:var(--color-brand); background:var(--color-brand-soft); }

/* --- Polish pass ---------------------------------------------------------- */

/* Comfortable touch targets, applied to every control rather than to the
   filters alone -- otherwise a select stands taller than the button beside it. */
@media (pointer: coarse) {
  .load, .request__submit, .request__field,
  .filter select, .filter input, .theme, .langs button { min-height:44px; }
}

/* Supplier-ranking mode header: names the ranked view so results read as a
   leaderboard, not a plain match list. The tally rule below is the divider. */
.mode { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.3rem 0.9rem; margin:1.5rem 0 0; }
.mode__label { font:600 var(--text-lg)/1.2 var(--font-sans); letter-spacing:-0.01em; }
.mode__hint { font-size:var(--text-label); color:var(--color-muted); }

/* --- Change-history timeline ---------------------------------------------- */

.load { padding:0.6rem 1.1rem; cursor:pointer; border:1px solid var(--color-border-strong); border-radius:2px;
  background:var(--color-bg); color:var(--color-fg); font:600 var(--text-label)/1 var(--font-sans);
  letter-spacing:0.1em; text-transform:uppercase; }
.load:hover { background:var(--color-bg-2); }

.timeline { list-style:none; margin:1rem 0 0; padding:0; }
.tl { display:grid; grid-template-columns:minmax(9rem,12rem) 1fr; gap:0.5rem 1.5rem;
  padding:0.9rem 0; border-bottom:1px solid var(--color-border); }
.tl__date { color:var(--color-muted); font-weight:500; }
.tl__changes { list-style:none; margin:0; padding:0; display:grid; gap:0.5rem; }
.chg { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.3rem 0.7rem; }
.chg__kind { font-weight:600; }
/* The from/to are normalised comparison values, not prose — mono signals that. */
.chg__diff { display:inline-flex; flex-wrap:wrap; align-items:baseline; gap:0.25rem 0.4rem;
  max-width:100%; font-family:ui-monospace,'Cascadia Code','Consolas',monospace;
  font-size:0.7rem; color:var(--color-muted); word-break:break-word; overflow-wrap:anywhere; }
.chg__from, .chg__to { word-break:break-word; overflow-wrap:anywhere; }
.chg__arrow { color:var(--color-muted); }
.chg__to { color:var(--color-muted); }
/* Appearance / disappearance are events, tinted like the state they imply. */
.chg[data-kind="appeared"] .chg__kind, .chg[data-kind="reappeared"] .chg__kind { color:var(--color-brand-deep); }
.chg[data-kind="disappeared"] .chg__kind { color:var(--color-warn); }
/* Status values are human labels, so they read in the data font, not mono. */
.chg[data-kind="status"] .chg__diff { font-family:var(--font-sans); font-size:var(--text-base); }
.chg[data-kind="status"] .chg__to { font-weight:600; }

/* Activities change as a delta of CAEM names: one activity per line, what left
   struck in red, what arrived in ink. Prose, not mono — these are sentences. */
.delta { flex-basis:100%; list-style:none; margin:0.3rem 0 0; padding:0; display:grid; gap:0.25rem; }
.delta__row { display:grid; grid-template-columns:0.9rem 1fr; gap:0.45rem; align-items:baseline;
  font:400 var(--text-base)/1.35 var(--font-sans); }
.delta__mark { font-weight:600; text-align:center; }
.delta__row--out { color:var(--color-danger); }
.delta__row--in { color:var(--color-muted); }

@media (max-width: 44rem) {
  .tl { grid-template-columns:1fr; gap:0.25rem; }
}

/* --- Change-timeline chart ------------------------------------------------ */

.chart { width:100%; height:auto; max-width:52rem; margin:0.75rem 0; }
.chart__axis { stroke:var(--color-border-strong); stroke-width:1; }
.chart__year { fill:var(--color-muted-2); font:400 12px var(--font-sans); }
.dot { stroke:var(--color-bg); stroke-width:1.5; }
.dot--appeared { fill:var(--color-brand); }
.dot--gone { fill:var(--color-warn); }
.dot--status { fill:var(--color-danger); }
.dot--control { fill:var(--color-fg); }
.dot--detail { fill:var(--color-muted-2); }

.chart__legend { display:flex; flex-wrap:wrap; gap:0.35rem 1.1rem; margin:0 0 1.25rem;
  font-size:var(--text-label); color:var(--color-muted); }
.chart__legend span { display:inline-flex; align-items:center; gap:0.4rem; }
.sw { width:10px; height:10px; border-radius:50%; display:inline-block; }
.sw--appeared { background:var(--color-brand); }
.sw--gone { background:var(--color-warn); }
.sw--status { background:var(--color-danger); }
.sw--control { background:var(--color-fg); }
.sw--detail { background:var(--color-muted-2); }

/* --- Ownership split — the bar fills to the founder's share on load ------- */

.founder { display:block; }
.founder__head { display:flex; flex-wrap:wrap; gap:0.3rem 0.9rem; align-items:baseline; }
.share { height:6px; margin-top:0.45rem; max-width:22rem; background:var(--color-bg-2);
  border-radius:99px; overflow:hidden; }
.share__fill { height:100%; background:var(--color-brand); border-radius:99px;
  transform-origin:left; animation:share-grow 0.9s var(--ease) both; }
@keyframes share-grow { from { transform:scaleX(0); } }

/* --- Ownership network — entities reached through shared people ----------- */

.net { list-style:none; margin:1rem 0 0; padding:0; display:grid; gap:0; }
.net__person { padding:0.95rem 0; border-bottom:1px solid var(--color-border); }
.net__person:last-child { border-bottom:0; }
.net__head { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.4rem 0.9rem; }
.net__who { font:600 var(--text-lg)/1.2 var(--font-sans); letter-spacing:-0.01em; }
.net__count { font-size:var(--text-label); color:var(--color-muted); }

/* Each entity the person reaches, indented under their name and marked with a
   small node. No connecting rule — the page's grammar is horizontal hairlines,
   not vertical stripes, and the node alone carries the "reached through" sense. */
.net__links { list-style:none; margin:0.55rem 0 0; padding:0; display:grid; gap:0.5rem; }
.link { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.3rem 0.7rem;
  position:relative; padding-left:1rem; }
.link::before { content:""; position:absolute; left:0; top:0.5em; width:5px; height:5px;
  border-radius:50%; background:var(--color-muted-2); }
.link__name { font:500 var(--text-base)/1.25 var(--font-sans); color:var(--color-fg); text-decoration:none;
  border-bottom:1px solid var(--color-border-strong); transition:border-color 0.15s var(--ease); }
.link__name:hover { border-bottom-color:var(--color-fg); }
.link:has(a.link__name:not([target])) { cursor:pointer; }
.link:has(a.link__name:not([target])):hover { background:linear-gradient(90deg, var(--color-bg-2), transparent 75%); }
a.link__name:not([target])::after { content:""; position:absolute; inset:-0.2rem -0.4rem; }
.link__role { font-size:var(--text-label); color:var(--color-muted); }
.link__status { font-size:var(--text-label); color:var(--color-muted); }
/* A liquidated (but still-listed) entity: state tinted like a superseded seal. */
.link__status--liquidated, .link__status--absent { color:var(--color-warn); }

/* An entity no longer in the register: dimmed, its node hollowed. */
.link--gone .link__name { color:var(--color-muted); }
.link--gone::before { background:var(--color-bg); border:1px solid var(--color-warn); }


/* ==========================================================================
   ASYDATA control kit — ported from components/ui, not approximated.
   Fixed height per size, one radius, semibold label, a 200ms transition, a
   two-pixel focus ring held off the control by two pixels, and a press that
   settles by 2%. These are the details that make a button feel like theirs.
   ========================================================================== */

.load, .request__submit {
  display:inline-flex; align-items:center; justify-content:center; gap:0.5rem;
  height:36px; padding:0 1rem; border-radius:var(--radius-card);
  font:600 var(--text-lg)/1 var(--font-sans); cursor:pointer;
  transition:background-color .2s var(--ease), border-color .2s var(--ease),
             box-shadow .2s var(--ease), transform .2s var(--ease), color .2s var(--ease);
}
.load:active, .request__submit:active { transform:scale(0.98); }
.load:disabled, .request__submit:disabled { opacity:0.5; pointer-events:none; }

/* Outline: the default secondary. Surface ground, real border, ink label. */
.load { border:1px solid var(--color-border-strong); background:var(--color-surface); color:var(--color-fg); }
.load:hover { background:var(--color-bg-2); }

/* Primary: the one action a screen is about. The single-voice rule means the
   green cannot appear twice on the same view. */
.request__submit { border:0; background:var(--color-brand); color:var(--color-brand-fg); }
.request__submit:hover { background:var(--color-brand-2); }

/* The ring sits off the control, which is why it reads on both a card and the
   page ground. */
:focus-visible { outline:2px solid var(--color-brand); outline-offset:2px; }

.request__field:focus-visible, .filter select:focus-visible, .filter input:focus-visible {
  outline:none; border-color:var(--color-brand);
  box-shadow:0 0 0 3px var(--color-brand-soft);
}
.request__field::placeholder { color:var(--color-muted); opacity:0.8; }
.request__field:hover, .filter select:hover, .filter input:hover { border-color:var(--color-border-strong); }

.filter select, .filter input, .request__field {
  height:36px; padding:0 0.75rem; border:1px solid var(--color-border);
  border-radius:var(--radius-field); background:var(--color-surface); color:var(--color-fg);
  font:400 var(--text-base)/1 var(--font-sans);
  transition:border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.filter select:hover, .filter input:hover { border-color:var(--color-border-strong); }

.section-note, .attribution { font-size:var(--text-caption); line-height:1.5; }
.acts__caem, .people__role, .link__role, .contract__buyer {
  font-size:var(--text-caption); color:var(--color-muted);
}

/* A card answers the pointer by floating a little higher -- their card-hover,
   which is the same three layers opened up rather than a different shadow. */
.section, .extract__head {
  transition:box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.section:hover, .extract__head:hover { box-shadow:var(--shadow-card-hover); }

/* The day/night switch. It is a control, so it is the outline button at icon
   size -- the system has one button, not a special one for the chrome. Which
   glyph shows is decided by the theme class, so no state is held in C#. */
.theme {
  display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:32px; padding:0;
  border:1px solid var(--color-border); border-radius:var(--radius-field);
  background:var(--color-surface); color:var(--color-muted); cursor:pointer;
  transition:background-color .2s var(--ease), color .2s var(--ease),
             border-color .2s var(--ease), transform .2s var(--ease);
}
.theme:hover { background:var(--color-bg-2); color:var(--color-fg); border-color:var(--color-border-strong); }
.theme:active { transform:scale(0.98); }
.theme__night { display:block; }
.theme__day { display:none; }
html.dark .theme__night { display:none; }
html.dark .theme__day { display:block; }
