/* ==========================================================================
   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.  On the surfaces a reader came to *use* — search, and the
                     record itself — a display heading spends exactly the first
                     screen they came for, so identity is carried by the bar and by
                     the record's own head. Reading and reference pages (statistics,
                     the nomenclators, the legal texts, the 404) do carry an h1:
                     they are documents, they are indexed individually, and the
                     router focuses that heading on arrival.
     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: much of the registry's people data is Cyrillic, and a
   Latin-only build from a font host renders those real records in a fallback.
   Self-hosting also keeps the door shut for a content-security policy to be
   added without reopening it — the host currently sends nosniff, DENY and a
   referrer policy, but no CSP yet.

   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;
  /* muted, pulled one step toward ink for text that sits on bg-2: the plain
     rung measures 4.34:1 there, a whisker under AA. */
  --color-muted-strong:color-mix(in srgb, var(--color-muted) 78%, var(--color-fg));

  /* 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);
  /* The modal backdrop, at the value DESIGN.md states for it: black at 45% under
     a small blur. A token rather than a literal so the one place it appears is
     nameable, and so a second overlay cannot quietly pick a different black. */
  --color-backdrop:rgba(0,0,0,0.45);
  --select-arrow:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m6 9 6 6 6-6'/%3e%3c/svg%3e");

  /* 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);
  /* The default card. Neutral and discreet, and deliberately borderless: the
     shadow alone does the separating. */
  --shadow-elevated:
    0 1px 2px rgba(0,0,0,0.05),
    0 4px 10px -2px rgba(0,0,0,0.07);
  --shadow-elevated-hover:
    0 2px 5px rgba(0,0,0,0.07),
    0 8px 18px -3px rgba(0,0,0,0.10);

  /* The 4px grid, tokenised so rhythm is chosen rather than accumulated. */
  --space-1:4px;  --space-2:8px;  --space-3:12px; --space-4:16px;
  --space-5:20px; --space-6:24px; --space-8:32px; --space-10:40px; --space-12:48px;

  --topbar-h:57px;
  --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-muted-strong:color-mix(in srgb, var(--color-muted) 78%, var(--color-fg));

  --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);
  --select-arrow:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2399A29B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m6 9 6 6 6-6'/%3e%3c/svg%3e");

  --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-elevated:
    0 1px 3px rgba(0,0,0,0.4),
    0 4px 12px -3px rgba(0,0,0,0.45);
  --shadow-elevated-hover:
    0 2px 6px rgba(0,0,0,0.45),
    0 10px 22px -4px rgba(0,0,0,0.5);
  --shadow-brand-glow:
    0 1px 0 rgba(255,255,255,0.08) inset,
    0 12px 36px -8px rgba(63,214,143,0.42);
}

/* The palette swap, held still. Set for exactly two frames while the theme class
   changes: without it every transitioned colour keeps the value it resolved under
   the old palette, so the chrome and the primary action stay in the theme the
   reader just left. See asydataTheme.toggle. */
html[data-theme-switching] *,
html[data-theme-switching] *::before,
html[data-theme-switching] *::after {
  transition:none !important;
}

*,*::before,*::after { box-sizing:border-box; }
html { overflow-x:clip; -webkit-text-size-adjust:100%; scroll-padding-top:calc(var(--topbar-h) + var(--space-6)); }

body {
  margin:0; background:var(--color-bg); color:var(--color-fg);
  /* The hero's glow bleeds past the column on purpose; the page must not grow a
     horizontal scrollbar for it. clip, not hidden: no new scroll container. */
  overflow-x:clip;
  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. */
.topbar { position:sticky; top:0; z-index:50;
  background:var(--color-surface); border-bottom:1px solid var(--color-border); }
.topbar__rail { max-width:74rem; margin:0 auto; padding:0 var(--gutter); }
.masthead { display:flex; flex-wrap:nowrap; align-items:center; gap:var(--space-2) var(--space-6);
  min-height:var(--topbar-h); padding-block:var(--space-2); }
/* The brand lockup, as asydata.com sets it: the wordmark, then the surface it is
   sitting on written as a path. It names where you are; it is not a destination. */
.masthead__brand { flex:0 0 auto; display:inline-flex; align-items:baseline; gap:var(--space-2);
  font:700 var(--text-micro)/1.3 var(--font-sans);
  letter-spacing:0.09em; text-transform:uppercase; color:var(--color-brand); }
.masthead__path { font:400 var(--text-caption)/1.3 var(--font-mono);
  letter-spacing:0; text-transform:none; color:var(--color-muted); }

/* Wraps rather than shrinks. The nav used to be the only flexible item in a
   nowrap bar, so between the phone breakpoint and ~1000px it kept its box but not
   its content: the links spilled out and lay across the pulse, the theme button
   and the language switcher, which sit above them and swallowed the clicks. A row
   that can wrap cannot overflow, in any locale — and Russian sets these five
   words wider than Romanian does. */
.masthead__nav { flex:1 1 auto; display:flex; flex-wrap:wrap; align-items:center;
  gap:var(--space-2) var(--space-5); min-width:0; }

/* One nav item, used for every destination, so the header reads as a set of
   links rather than a title with something small next to it. */
.masthead__link {
  position:relative; display:inline-flex; align-items:center; padding:0 0 5px;
  white-space:nowrap; font:500 13.5px/1 var(--font-sans);
  color:var(--color-muted); text-decoration:none;
  transition:color .2s var(--ease);
}
.masthead__link:hover { color:var(--color-fg); }

/* Where you are, said with a rule under the word rather than with size — the
   marketing site's own active state, and the reason the two links now read as a
   pair with one of them current. */
.masthead__link.active { color:var(--color-brand); }
.masthead__link.active::after {
  content:""; position:absolute; left:0; right:0; bottom:0;
  height:2px; border-radius:99px; background:var(--color-brand);
}

/* Present to a screen reader and to the page title, absent from the picture. */
.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 validity seal. Not decoration: it carries the snapshot the whole surface
   answers from, and changes state when that answer goes stale. */
/* A pulse, not a certificate. The header can honestly answer one question for
   every page at once — is the pipeline still landing — so that is all it answers.
   The date it vouches for sits next to the results it certifies, and the rosette
   glyph is gone: a checkmark seal claimed exactly the officialdom the record's own
   text disclaims. */
.health { display:inline-flex; align-items:center; gap:var(--space-2);
  font-size:var(--text-caption); color:var(--color-muted); white-space:nowrap; }
.health__dot { width:8px; height:8px; border-radius:50%; background:var(--color-brand);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--color-brand) 16%, transparent); }
.health[data-state='stale'] { color:var(--color-warn-deep); }
.health[data-state='stale'] .health__dot { background:var(--color-warn);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--color-warn) 18%, transparent); }
.health[data-state='unknown'] .health__dot { background:var(--color-muted-2); box-shadow:none; }

/* Provenance travelling with the answer. */
.tally__source { margin-left:0.35em; 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(auto-fit, minmax(8rem, 1fr));
  gap:var(--space-3) var(--space-5); padding-top:var(--space-4); 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%; }

/* A checkbox filter is a different shape from the rest of the row: one control
   and its own label side by side, not a label stacked over a full-width field. */
.filter--check { display:flex; flex-direction:row; align-items:center; gap:0.5rem;
  grid-column:1 / -1; }
.filter--check input { width:auto; accent-color:var(--color-brand); }
.filter--check span { font:400 var(--text-base)/1.4 var(--font-sans);
  letter-spacing:normal; text-transform:none; }

/* No breakpoint of its own: auto-fit already fits as many tracks as the row can
   hold, and hard-coding a count is what stranded the last filter on its own row
   when the number of filters changed. */

/* --- 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-title)/1.3 var(--font-sans); letter-spacing:-0.02em; }
.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; }

.status { display:inline-flex; align-items:center; gap:0.35rem; white-space:nowrap;
  padding:0.125rem 0.5rem; border:0; border-radius:var(--radius-field);
  font:500 var(--text-label)/1.375 var(--font-sans); }
.status--active { color:var(--color-brand-deep); background:var(--color-brand-soft);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--color-brand) 20%, transparent); }
.status--liquidated { color:var(--color-danger-deep); background:var(--color-danger-soft);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--color-danger) 20%, transparent); }
.status--absent { color:var(--color-warn-deep); background:var(--color-warn-soft);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--color-warn) 20%, transparent); }

/* --- Extract ------------------------------------------------------------- */

.extract { padding:1rem 0 3rem; }
.extract__head { display:flex; flex-wrap:wrap; align-items:center; gap:0.5rem 1.5rem;
  margin-top:var(--space-4); padding:var(--space-5); background:var(--color-surface);
  border-radius:var(--radius-card); box-shadow:var(--shadow-elevated); }
.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:10rem minmax(0,1fr); margin:0; padding:0; }
.fields > dt { grid-column:1; padding:0.5rem 1.5rem 0.5rem 0;
  border-bottom:1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
  font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.05em; text-transform:uppercase;
  color:var(--color-muted); align-self:center; }
.fields > dd { grid-column:2; margin:0; max-width:var(--measure); padding:0.5rem 0;
  border-bottom:1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
  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. */

/* 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:var(--space-6); padding:var(--space-5); background:var(--color-surface);
  border-radius:var(--radius-card); box-shadow:var(--shadow-elevated); }
.section > h2 { margin:0 0 0.85rem; padding-bottom:0;
  font:700 var(--text-title)/1.3 var(--font-sans); letter-spacing:-0.025em; }
/* A rung under the card's own title, for a list that needs naming inside a
   section that already has one. Weight and colour carry the step, not size —
   more space above than below, so it reads as opening a group. */
.section > h3 { margin:1.4rem 0 0.5rem;
  font:600 var(--text-base)/1.35 var(--font-sans); letter-spacing:0.02em;
  text-transform:uppercase; color:var(--color-muted-strong); }

.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:var(--space-3) var(--space-4); border:1px solid var(--color-warn); border-radius:var(--radius-card);
  background:var(--color-warn-soft); color:var(--color-warn-deep); }
/* A struck record is a different finding from an absent one, and the surface
   brief gives it its own ink. Named for what it marks, matching the
   data-struck attribute the extract already carries. */
.notice--struck { 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); }
/* The deep rung, not the plain one: #E11D48 on the page ground measures 4.49:1,
   a hair under AA, and a failure message is the last text that may be hard to
   read. */
.failure { padding:4rem 0; text-align:center; color:var(--color-danger-deep); font:400 var(--text-lg)/1.5 var(--font-sans); }

/* --- Chrome -------------------------------------------------------------- */

.langs { display:flex; gap:var(--space-1); }

/* One chrome control, two widths. */
.theme, .langs button {
  display:inline-flex; align-items:center; justify-content:center;
  height:32px; border:0; border-radius:var(--radius-card);
  background:transparent; color:var(--color-muted); cursor:pointer;
  transition:background-color .2s var(--ease), color .2s var(--ease), transform .2s var(--ease);
}
.theme { width:32px; padding:0; }
.langs button { padding:0 var(--space-2);
  font:600 var(--text-label)/1 var(--font-sans); letter-spacing:0.05em; text-transform:uppercase; }

.theme:hover, .langs button:hover { background:var(--color-bg-2); color:var(--color-fg); }
.theme:active, .langs button:active { transform:scale(0.98); }

/* The selected locale wears the brand tone the badges use -- a tint under an
   inset ring, never a hard border. */
.langs button[aria-pressed='true'] { color:var(--color-brand-deep); background:var(--color-brand-soft);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--color-brand) 20%, transparent); }

.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:var(--radius-field);
  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); }

/* --- 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; }
}

/* Reduced motion is a request to stop things moving, not a request to strip the
   feedback out of the interface. So: no travel and no growth — the seal does not
   stamp, the ownership bar does not fill, hover does not lift, press does not
   compress — while the state changes that carry meaning keep a short colour and
   opacity fade, which no vestibular guidance asks anyone to give up. A blanket
   0.001ms kill takes both, and takes the fade a stale list uses to say it is
   answering an older question. */
@media (prefers-reduced-motion: reduce) {
  *,*::before,*::after {
    animation-duration:0.001ms !important;
    animation-iteration-count:1 !important;
    transition-property:color, background-color, border-color, box-shadow, opacity, fill !important;
    transition-duration:120ms !important;
    scroll-behavior:auto !important;
  }
  /* Nothing translates, scales or rotates, in any state. */
  .load:hover, .request__submit:hover, .doors .browse:hover,
  .load:active, .request__submit:active,
  .theme:active, .langs button:active,
  .browse:hover .browse__arrow, .doors .browse:hover .browse__arrow { transform:none; }
  .share__fill { animation:none; }
  .fin__caret[data-open="true"] { transform:rotate(180deg); }
}

/* --- 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; }

}

/* The record's headline row. The metric ramp exists in the system and the registry
   surface never used it: a company's whole public-money exposure was set at the same
   size and weight as its postcode. These are the four figures the three audiences
   arrive for, and they sit above the identity fields, not three screens under them. */
.metrics--record { margin-top:var(--space-4); }
.metrics--record .metric { gap:0.1rem; }
.metric__note { font-size:var(--text-label); color:var(--color-muted); }
/* A loss is the one number here that should stop a reader mid-scroll. */
.metric--loss .metric__value { color:var(--color-danger-deep); }

/* --- 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; }
/* A loss is a finding, not a smaller number. It was set in the body ink at the
   body weight, indistinguishable from a profit, on the page where the difference
   decides whether someone signs. */
.money--loss { color:var(--color-danger-deep); font-weight:600; }
.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 { display:inline-flex; align-items:center;
  font:500 var(--text-label)/1.375 var(--font-sans);
  padding:0.125rem 0.5rem; border:1px solid var(--color-border);
  border-radius:var(--radius-field); background:var(--color-bg-2); color:var(--color-muted-strong); }

/* Financial statements table. */
.scroll { overflow-x:auto; }
.scroll:focus-visible { outline:2px solid var(--color-brand); outline-offset:2px; }
.fin { width:100%; border-collapse:collapse; font-variant-numeric:tabular-nums; }
.fin th, .fin td { padding:0.75rem 1rem; border-bottom:1px solid var(--color-border); text-align:left; }
.fin th.num, .fin td.num { text-align:right; }
.fin th { padding-top:0.625rem; padding-bottom:0.625rem;
  font:600 var(--text-micro)/1.4 var(--font-sans); letter-spacing:0.05em;
  text-transform:uppercase; color:var(--color-muted-strong); background:var(--color-bg-2);
  white-space:nowrap; }
.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-surface); border:1px solid var(--color-border); border-radius:var(--radius-card);
  color:var(--color-fg); font:inherit; transition:background 0.18s var(--ease); }
.browse:hover { background:var(--color-bg-2); }
a.browse { text-decoration:none; }
.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); background:var(--color-brand-soft);
  border-color:color-mix(in srgb, var(--color-brand) 20%, transparent); }

/* --- 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, .sub__button,
  .filter select, .filter input, .theme, .langs button,
  .pager button, .cls__tab, .filters__disclosure > summary,
  /* Measured under target on a phone and missing from this list: the annex tab
     switch (34px), the menu button (36px), the classifier search box (42px) and
     the back link (32px). The switch is the one that stings — its own rule below
     claims a thumb-sized target and was being outranked by a later selector. */
  .viewsw__b, .menu-btn, .cls__search input, .back { min-height:44px; }
  .menu-btn { min-width:44px; }

  /* Inline links inside dense rows are a different problem: a 44px code link
     would inflate a 1.721-row table by a quarter. These take the 24px AA floor
     via a hit area that grows past the text without moving the row. */
  .cls__code a, .rank__label, .metric__link, .elders li a, .colophon__legal a {
    position:relative; display:inline-block; min-height:24px; }
  .cls__code a::after, .rank__label::after, .metric__link::after,
  .elders li a::after, .colophon__legal a::after {
    content:""; position:absolute; inset:-6px -4px; }
  /* Height alone leaves a 32px-wide target; the mark stays small, the target does not. */
  .theme, .langs button, .pager button { min-width:44px; }
  /* The chip's cross keeps its 24px box and grows a 44px hit area around it, the
     same trick the inline links use — a 44px chip would be a button with a label
     stuck to it. */
  .sub__chip-x { position:relative; }
  .sub__chip-x::after { content:""; position:absolute; inset:-10px; }
  /* A year header is a control on a table row; it grows its target without
     moving the row's rhythm. Was tied to a width breakpoint, so a touch tablet in
     landscape got the 22px desktop target. */
  .fin__yr { padding:0.8rem 0.5rem; margin:-0.8rem -0.5rem; }
}

/* 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 ---------------------------------------------- */


.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:var(--font-mono);
  font-size:var(--text-label); 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-deep); }
/* 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); 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); }

.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); }

/* --- 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; }
/* Sums and identifiers stay above the overlay and selectable, for the same
   reason the IDNO does in a search result: they are meant to be copied. */
.link .num, .link .money { position:relative; z-index:1; cursor:text; }
.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-deep); }

/* 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:42px; 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:disabled, .request__submit:disabled { opacity:0.5; pointer-events:none; }

/* A disclosure stands under the thing it extends, not against it. Every one of
   these buttons follows a list, a table or a sentence, and with no margin of its
   own it sat on the last rule of whatever it followed. */
* + .load { margin-top:var(--space-4); }

/* Outline: the default secondary. Border at rest, strengthened on hover. */
.load { border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-fg);
  box-shadow:var(--shadow-card); }
.load:hover { border-color:var(--color-border-strong); background:var(--color-bg-2);
  transform:translateY(-2px); }

/* Primary: the one action a screen is about. The single-voice rule means the
   green cannot appear twice on the same view. On hover it gains the one
   coloured shadow in the system -- the brand glow -- and lifts with it. */
.request__submit { border:0; background:var(--color-brand); color:var(--color-brand-fg);
  box-shadow:var(--shadow-card); }
.request__submit:hover { background:var(--color-brand-2); box-shadow:var(--shadow-brand-glow);
  transform:translateY(-2px); }

/* The press settles, and it must come after hover so it wins while both hold. */
.load:active, .request__submit:active { transform:scale(0.98); }

/* 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,
.cls__search input:focus-visible, .sub__field input:focus-visible, .sub__pick-search:focus-visible, .nc__input:focus-visible {
  outline:none; border-color:var(--color-brand);
  box-shadow:0 0 0 3px var(--color-brand-soft);
}
.request__field::placeholder, .cls__search input::placeholder, .sub__field input::placeholder, .sub__pick-search::placeholder, .nc__input::placeholder { color:var(--color-muted); opacity:0.8; }
.request__field:hover, .filter select:hover, .filter input:hover,
.cls__search input:hover, .sub__field input:hover, .sub__pick-search:hover, .nc__input:hover { border-color:var(--color-border-strong); }

.filter select {
  appearance:none; -webkit-appearance:none;
  padding-right:2rem;
  background-image:var(--select-arrow);
  background-repeat:no-repeat;
  background-position:right 0.65rem center;
  background-size:14px 14px;
}
/* Edge and IE draw their own arrow on top of ours. */
.filter select::-ms-expand { display:none; }

.filter select, .filter input, .request__field, .cls__search input, .sub__field input, .sub__pick-search, .nc__input {
  height:42px; 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);
}

/* 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__night { display:block; }
.theme__day { display:none; }
html.dark .theme__night { display:none; }
html.dark .theme__day { display:block; }

/* Below the `sm` breakpoint every field goes to 16px: iOS zooms the page when a
   focused input is smaller, and this product is used on a phone mid-task. */
@media (max-width: 40rem) {
  .request__field, .filter select, .filter input, .cls__search input, .sub__field input, .sub__pick-search, .nc__input { font-size:16px; }
}

/* ==========================================================================
   Listing table -- the procurement list, and the shape any future long list
   takes. Table from `sm` up, cards below it, written once.
   ========================================================================== */

/* The header stays with the reader while the page scrolls, parked under the
   topbar. The system asks for the scroll to live inside the container, but this
   is a paged public list on a document page rather than a fixed-height grid, so
   the page keeps the scroll and only the header pins. */
.listing thead th { position:sticky; top:var(--topbar-h); z-index:1; }

/* A column header that is also its own sort trigger — the whole header cell reads
   as a control, not just the text inside it, so the click target matches what a
   reader sees rather than a few pixels of it. */
.listing__sortbtn { display:flex; align-items:center; gap:0.3rem; width:100%;
  border:0; background:none; padding:0; margin:0; font:inherit; text-align:inherit;
  color:inherit; cursor:pointer; }
.listing__sortbtn:hover { color:var(--color-fg); }
.listing__sortbtn[aria-pressed="true"] { color:var(--color-brand-deep); }
.listing__sortbtn span { font-size:0.7em; }

@media (pointer: coarse) {
  .listing__sortbtn { min-height:44px; }
}
.listing__subject { font-weight:500; }
.listing__subject a { color:var(--color-fg); text-decoration:none;
  border-bottom:1px solid var(--color-border-strong); }
.listing__subject a:hover { color:var(--color-brand-deep); border-bottom-color:var(--color-brand); }
.listing__meta { color:var(--color-muted); font-size:var(--text-caption); }
.listing__value { font-weight:600; white-space:nowrap; }

@media (max-width: 44rem) {
  /* Cards. The column heads are dropped, so each cell has to name itself — this
     comment used to claim they did while nothing rendered a label, and the rules
     meant to lay them inline lost the cascade to `.listing td`, so every cell
     computed `block` and a page of 25 procedures ran to 6,500px of stack. */
  .listing thead { display:none; }
  .listing, .listing tbody, .listing tr, .listing td { display:block; width:100%; }
  .listing tr { padding:var(--space-3) 0; border-bottom:1px solid var(--color-border); }
  .listing td { padding:0; border:0; }
  .listing__subject { margin-bottom:var(--space-1); font-size:var(--text-lg); }
  /* All four short cells read as one flowing line of metadata — the element is in
     the selector now, so these actually win against `.listing td` (0-1-1), which
     they did not before. Giving each its own row was the first fix, and it made
     the card taller than the bug did. */
  .listing td.listing__meta { display:inline; }
  .listing td.listing__meta:not(:last-of-type)::after { content:" \00b7 "; color:var(--color-muted-2); }

  /* "în atribuire" and "atribuire directă" are indistinguishable strings once the
     column head is gone, so those two name themselves. The buyer and the category
     do not need it. */
  .listing td[data-label]::before { content:attr(data-label) ": ";
    font:600 var(--text-label)/1.4 var(--font-sans); letter-spacing:0.025em;
    text-transform:uppercase; color:var(--color-muted); }

  /* The deadline is the supplier's deciding field: its own line, at the end. */
  .listing td.listing__deadline { display:block; margin-top:var(--space-1); }
  .listing__value { margin-top:var(--space-2); font-size:var(--text-lg); text-align:left; }
}

/* The bar holds one row only where all five destinations plus the chrome
   genuinely fit beside each other, which is 64rem up. That is a wider band than
   the phone breakpoint the rest of the page turns on, and deliberately so: the
   bar's contents are five words of navigation, and words do not reflow.
   --topbar-h is true only inside this band, which is also the only band where
   the bar is sticky and anything offsets against it. */
@media (min-width: 64rem) {
  .masthead { flex-wrap:nowrap; }
  .masthead__nav { flex:0 1 auto; min-width:0; }
  .masthead__brand, .health, .langs, .theme { flex:0 0 auto; }
  /* The free space belongs between the two groups, not after them. */
  .health { margin-left:auto; }
}

/* Below it the bar is two rows: identity and chrome above, the destinations
   under them at full width. The frame stops being permanent furniture there —
   ninety pixels of sticky bar is most of a tablet's first fold, and this product
   gives the first fold to data. Nothing sticky means nothing offsets, so the
   token goes to zero rather than lying about a height that now varies. */
@media (max-width: 63.99rem) {
  /* One row, as the parent product's own header does it: identity left, the
     controls right, the destinations behind a button. Wrapping five words onto
     two and three rows cost ~99px of every first fold and left one of them alone
     on a line. The language switcher stays in the bar deliberately — it is the
     one control a reader may need before they can read anything. */
  .masthead { flex-wrap:nowrap; gap:var(--space-2); }
  .masthead__nav { display:none; }
  .masthead__brand { flex:0 0 auto; margin-right:auto; }
  .health, .langs, .theme, .menu-btn { flex:0 0 auto; }
}

/* The control, and the panel's close button: the outline button at icon size, the
   same chassis the theme toggle uses. */
.menu-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:36px; height:36px; padding:0; border:1px solid var(--color-border);
  border-radius:var(--radius-card); background:var(--color-surface);
  color:var(--color-fg); cursor:pointer;
  transition:background-color .2s var(--ease), border-color .2s var(--ease); }
.menu-btn:hover { background:var(--color-bg-2); border-color:var(--color-border-strong); }

/* Above 64rem the destinations are in the bar and the control is pointless. Stated
   after the base rule, not before it — same specificity, so order decides. */
@media (min-width: 64rem) {
  .masthead .menu-btn { display:none; }
}

/* The panel. Full-bleed on a phone, because a half-width sheet over a dense page
   reads as an accident. */
.drawer { position:fixed; inset:0; z-index:80; background:var(--color-backdrop);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px); }
.menu { position:fixed; inset:0; z-index:81; display:flex; flex-direction:column;
  gap:var(--space-2); padding:var(--space-4) var(--gutter) var(--space-6);
  background:var(--color-surface); overflow-y:auto; }
.menu:focus { outline:none; }
.menu__top { display:flex; align-items:center; justify-content:space-between;
  margin-bottom:var(--space-4); }

/* Ruled rows, one destination each — the page's own grammar, not a stack of pills. */
.menu__nav { display:flex; flex-direction:column; }
.menu__link { display:block; padding:var(--space-4) 0;
  border-bottom:1px solid var(--color-border);
  font:600 20px/1.3 var(--font-sans); letter-spacing:-0.02em;
  color:var(--color-muted); text-decoration:none;
  transition:color .15s var(--ease); }
.menu__link:hover { color:var(--color-fg); }
/* Where you are, said the way the bar says it: ink, not decoration. */
.menu__link.active { color:var(--color-fg); }

/* The seal, finally written out rather than reduced to an unexplained dot. */
.menu__seal { display:flex; align-items:flex-start; gap:var(--space-2);
  margin:var(--space-6) 0 0; color:var(--color-muted);
  font-size:var(--text-caption); line-height:1.5; }
.menu__seal .health__dot { flex:none; margin-top:0.35em; }
.menu__seal[data-state='stale'] { color:var(--color-warn-deep); }
.menu__seal[data-state='stale'] .health__dot { background:var(--color-warn); }
.menu__seal[data-state='unknown'] .health__dot { background:var(--color-muted-2); box-shadow:none; }

/* The classification reads as a chip plus its published name, one grain coarser
   than the subject beside it. */
.listing__cpv { display:block; margin-top:var(--space-1); color:var(--color-muted);
  font-size:var(--text-label); }

/* ==========================================================================
   The phone's first screen
   A 375x812 screen gives about 700 usable pixels once the browser takes its
   share. Everything below is measured against that budget: the answer has to
   start inside it, not after it.
   ========================================================================== */

/* The filter rack, one tap away rather than in the way. Above the phone
   breakpoint the summary disappears and the row behaves exactly as before. */
.filters__disclosure > summary {
  display:inline-flex; align-items:center; gap:var(--space-2);
  margin-top:var(--space-3); padding:0 var(--space-3);
  height:32px; border:1px solid var(--color-border); border-radius:var(--radius-card);
  background:var(--color-surface); color:var(--color-fg); cursor:pointer;
  font:600 var(--text-caption)/1 var(--font-sans); list-style:none;
}
.filters__disclosure > summary::-webkit-details-marker { display:none; }
.filters__disclosure > summary::after {
  content:""; width:8px; height:8px; border-right:1.5px solid currentColor;
  border-bottom:1.5px solid currentColor; transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .2s var(--ease);
}
.filters__disclosure[open] > summary::after { transform:rotate(-135deg) translate(-2px,-2px); }
.filters__disclosure > summary:hover { background:var(--color-bg-2); }

@media (min-width: 44.01rem) {
  .filters__disclosure > summary { display:none; }
}

@media (max-width: 44rem) {
  /* The record's name is the page, but at 28px it took three lines and 97px of a
     screen that has ~700. Two steps down keeps it the largest thing here without
     spending the answer on it. */
  .extract__title { font-size:20px; }
  .extract__head { margin-top:var(--space-2); padding:var(--space-4); }
  .extract { padding-top:var(--space-2); }

  /* The nav's own row would take three lines on a phone; tightening the rows and
     dropping the path suffix and the pulse's label returns most of it without
     losing anything nameable. The dot still says whether the pipeline is landing. */
  .masthead { gap:var(--space-2); }
  .masthead__path { display:none; }
  /* The pulse keeps its dot in the bar; the sentence lives in the panel. */
  .health__label { display:none; }
  .topbar__rail { padding-block:var(--space-2); }
}

/* --- Statistics annex ------------------------------------------------------
   The register from above. Same rules as everywhere: figures are the spectacle,
   mono and tabular; the green appears only where it means "still standing". */

.stats { padding:1rem 0 3rem; display:grid; gap:var(--space-4); }
.stats__head h1 { margin:0 0 0.5rem; font:700 var(--text-metric)/1.15 var(--font-sans);
  letter-spacing:-0.02em; }
.stats__head .section-note { margin:0; }

.metrics { display:grid; grid-template-columns:repeat(auto-fit, minmax(9.5rem, 1fr));
  gap:var(--space-3); }
.metric { display:grid; gap:0.2rem; padding:var(--space-4);
  background:var(--color-surface); border:1px solid var(--color-border);
  border-radius:var(--radius-card); box-shadow:var(--shadow-card); }
.metric__value { font:600 var(--text-metric)/1.1 var(--font-mono);
  font-variant-numeric:tabular-nums; letter-spacing:-0.02em; }
.metric__label { font-size:var(--text-label); font-weight:600; letter-spacing:0.06em;
  text-transform:uppercase; color:var(--color-muted); }
.metric--good .metric__value { color:var(--color-brand-deep); }
.metric--gone .metric__value { color:var(--color-muted); }
.metrics--inner { margin-top:0.5rem; }
.metrics--inner .metric { box-shadow:none; background:var(--color-surface-2); }

/* Incorporation wave: still-active in brand green over the full-height bar. */
.wave { width:100%; height:auto; margin-top:0.25rem; }
.wave__total { fill:var(--color-border); }
.wave__active { fill:var(--color-brand); }
.wave__year { fill:var(--color-muted); font:400 11px var(--font-mono); }

/* Survival by decade. */
.decades { list-style:none; margin:0.25rem 0 0; padding:0; display:grid; gap:0.55rem; }
.decade { display:grid; grid-template-columns:6.5rem minmax(0,1fr) 3.5rem auto;
  gap:0.8rem; align-items:center; }
.decade__label { font-size:var(--text-caption); color:var(--color-muted); }
.decade__bar { height:8px; border-radius:99px; background:var(--color-bg-2); overflow:hidden; }
.decade__fill { display:block; height:100%; border-radius:99px; background:var(--color-brand); }
.decade__pct { font-weight:600; text-align:right; }
.decade__detail { font-size:var(--text-caption); color:var(--color-muted); }

/* Ranked counts: label · thin bar · figure. */
.rank { list-style:none; margin:0.25rem 0 0; padding:0; display:grid; gap:0.5rem; }
.rank__row { display:grid; grid-template-columns:minmax(7rem, 14rem) minmax(2rem,1fr) auto;
  gap:0.8rem; align-items:center; }
.rank__label { font-size:var(--text-base); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; }
.rank__bar { height:6px; border-radius:99px; background:var(--color-bg-2); overflow:hidden; }
.rank__fill { display:block; height:100%; border-radius:99px; background:var(--color-brand-2); }
.rank__count { font-size:var(--text-caption); font-weight:600; text-align:right; }

/* Section pairings. */
/* A fold control beside a heading, not under it: the full-height button is for a
   section the reader has not opened yet, and this one only hides what is already
   there. Smaller, and it does not pull the eye the way the primary does. */
/* align-self:center, opting out of the parent's align-items:stretch, and a fixed
   height rather than auto. The pager's disabled "Înapoi" measured 16px taller than
   its enabled sibling with padding, border, font-size and line-height all provably
   identical — traced to Blazor's own SSR/hydration boundary comments sitting beside
   these buttons as flex siblings, which a plain static button with the same classes
   never reproduced. Rather than chase the exact interaction between that boundary
   comment and stretch's cross-axis sizing, this stops asking the flex algorithm to
   size the button at all. */
.load--quiet { height:auto; padding:0.4rem 0.75rem; box-shadow:none;
  font:500 var(--text-label)/1.4 var(--font-sans);
  align-self:center; height:1.75rem; }
.load--quiet:hover { transform:none; }

/* Where a company turned up to bid. A ruled list rather than a table: the title
   is the only field that wants room, and the rest reads as one line under it. */
@media (max-width: 44rem) {
  /* Measured 194px of box against 789px of content — an ellipsis was hiding three
     quarters of the row. Two lines cost 20px and return the sentence. */
  .rank__label { white-space:normal; overflow:visible; text-overflow:clip;
    display:-webkit-box; -webkit-line-clamp:2; line-clamp:2; -webkit-box-orient:vertical;
    overflow:hidden; }
}

.part__summary { margin:0.4rem 0 0.9rem; font:400 var(--text-caption)/1.6 var(--font-sans);
  color:var(--color-muted-strong); font-variant-numeric:tabular-nums; }
.part { list-style:none; margin:0; padding:0; }
.part__row { display:grid; grid-template-columns:1fr auto; gap:0.2rem var(--space-4);
  align-items:baseline; padding:0.6rem 0; border-bottom:1px solid var(--color-border); }
.part__row:last-child { border-bottom:0; }
.part__head { grid-column:1; display:flex; align-items:center; gap:0.5rem; flex-wrap:wrap; }
.part__title { font-weight:500; }
.part__meta { grid-column:1; display:flex; flex-wrap:wrap; gap:0.15rem 0.9rem;
  font:400 var(--text-label)/1.5 var(--font-sans); color:var(--color-muted); }
.part__bid { grid-column:2; grid-row:1 / span 2; text-align:right; white-space:nowrap;
  font-variant-numeric:tabular-nums; }
.part__bidlbl { display:block; font:600 var(--text-micro)/1.3 var(--font-sans);
  letter-spacing:0.025em; text-transform:uppercase; color:var(--color-muted); }

@media (max-width: 44rem) {
  /* The bid drops under its procedure rather than fighting the title for width. */
  .part__row { grid-template-columns:1fr; }
  .part__bid { grid-column:1; grid-row:auto; text-align:left; }
  .part__bidlbl { display:inline; text-transform:none; letter-spacing:0;
    font-size:var(--text-label); }
}

/* A count and what it is a share of, in one cell: the figure leads and the
   percentage trails it quietly, because "24.853" and "36%" answer the same
   question and two columns would make them look like two findings. */
.stat__share { margin-left:0.4rem; font-size:var(--text-label); color:var(--color-muted); }

.stats__pair { display:grid; gap:var(--space-4); grid-template-columns:1fr 1fr; }
.stats__pair > .section { margin-top:0; }
.stats__triple { display:grid; gap:var(--space-5); grid-template-columns:repeat(3, minmax(0,1fr)); }
.stats h3 { margin:0 0 0.6rem; font:600 var(--text-lg)/1.3 var(--font-sans); }
.stats .section { margin-top:0; }

/* The oldest still standing. */
.elders { list-style:none; margin:0.25rem 0 0; padding:0; display:grid; gap:0.55rem; }
.elders li { display:flex; flex-wrap:wrap; gap:0.35rem 1rem; align-items:baseline; }
.elders__date { font-size:var(--text-caption); color:var(--color-muted); min-width:8.5rem; }
.elders a { color:var(--color-fg); text-decoration:none;
  border-bottom:1px solid var(--color-border-strong); }
.elders a:hover { border-bottom-color:var(--color-fg); }

@media (max-width: 56rem) {
  .stats__triple { grid-template-columns:1fr; }
  .stats__pair { grid-template-columns:1fr; }
}
@media (max-width: 44rem) {
  /* Two rungs down, same as the extract title on a phone — 20px is the ladder's
     mobile display size. */
  .metric__value { font-size:20px; }
  .decade { grid-template-columns:5rem minmax(0,1fr) 3rem; }
  .decade__detail { display:none; }
}

/* On a touch screen every inline link keeps its small mark but grows its target:
   the 16px "MTender" links and 18px nav links were the worst offenders of a page
   where nothing reached 44px. */
@media (pointer: coarse) {
  .contract__link, .link__name, .masthead__link, .entry__name a,
  .listing__subject a, .browse { position:relative; }
  .contract__link::after, .link__name::after, .masthead__link::before,
  .listing__subject a::after {
    content:""; position:absolute; inset:-12px 0;
  }
}

/* A skip link, first in the tab order, visible only when focused. */
.skip {
  position:absolute; left:var(--space-4); top:-100px; z-index:100;
  padding:var(--space-2) var(--space-4); border-radius:var(--radius-field);
  background:var(--color-surface); color:var(--color-fg); box-shadow:var(--shadow-card);
  font:600 var(--text-caption)/1 var(--font-sans); text-decoration:none;
}
.skip:focus-visible { top:var(--space-2); }

/* A list whose query has moved on stops pretending to be the answer. */
.register[data-stale] { opacity:0.45; transition:opacity .2s var(--ease); }

.empty--zero { display:grid; justify-items:start; gap:var(--space-3); }

/* What the product is, said once, below the tools and out of the way of anyone
   who came knowing. The ASYDATA block is the one place the parent product is
   offered, in the same voice as everything else. */
.about { margin-top:var(--space-12); display:grid; gap:var(--space-6);
  grid-template-columns:repeat(auto-fit, minmax(15rem, 1fr));
  padding-top:var(--space-8); border-top:1px solid var(--color-border); }
.about__block h2 { margin:0 0 var(--space-2);
  font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.05em;
  text-transform:uppercase; color:var(--color-muted); }
.about__block p { margin:0; font-size:var(--text-caption); line-height:1.55;
  color:var(--color-muted); max-width:38ch; }
.about__block--asy h2 { color:var(--color-brand); }

.masthead__brand a { color:inherit; text-decoration:none; }
.masthead__brand a:hover { color:var(--color-brand-deep); }

/* --- Statistics annex, wave 2 --------------------------------------------- */

/* Strike-offs: the warn tint, the same voice as a superseded record. */
.wave__gone { fill:var(--color-warn); opacity:0.75; }

/* A ranked label that is also a way in. */
a.rank__label { color:var(--color-fg); text-decoration:none;
  border-bottom:1px solid var(--color-border-strong); }
a.rank__label:hover { border-bottom-color:var(--color-fg); }

/* One aside figure under a list — the leap-day line. */
.stats__aside { margin:0.9rem 0 0; font-size:var(--text-caption); color:var(--color-muted); }
.stats__aside .num { font-weight:600; color:var(--color-fg); }

/* The metric card can carry one link — the holder of the record figure. */
.metric__link { font-size:var(--text-caption); color:var(--color-muted-strong);
  text-decoration:none; border-bottom:1px solid var(--color-border-strong);
  justify-self:start; margin-top:0.15rem; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; max-width:100%; }
.metric__link:hover { color:var(--color-fg); border-bottom-color:var(--color-fg); }

/* Sub-list inside a section (renaming champions under the motion ranks). */
.stats .section h3 { margin-top:1.4rem; }

/* Bar-less rank rows: name and figure only, for narrow columns. The label link's
   rule hugs the text — a grid cell would otherwise stretch it across the column,
   which reads as a form field, not a link. */
.rank--plain .rank__row { grid-template-columns:minmax(0,1fr) auto; }
a.rank__label { justify-self:start; max-width:100%; }

/* The greeting. The blank page opens the way the parent's landing does: a mono
   eyebrow, a headline with one phrase in the brand green, a single human
   subline -- and then the field. A form label over a void read as bureaucracy;
   this reads as an invitation to the same field. */
.hero { position:relative; margin:var(--space-12) 0 var(--space-2); text-align:center; }
.hero__eyebrow { margin:0 0 var(--space-4);
  font:500 var(--text-caption)/1 var(--font-mono); letter-spacing:0.06em;
  color:var(--color-brand); }
.hero__title { margin:0 auto; max-width:22ch;
  font:700 clamp(30px, 4.4vw, 54px)/1.08 var(--font-sans);
  letter-spacing:-0.03em; text-wrap:balance; }
.hero__title span { color:var(--color-brand); }
.hero__sub { margin:var(--space-4) auto 0; max-width:52ch;
  font-size:var(--text-lg); line-height:1.6; color:var(--color-muted); }

/* Their landing's ground: a faint dot grid with a green glow falling from the
   top of the hero, fading before the content below. Both themes read it. */
.hero::before { content:""; position:absolute; z-index:-1;
  inset:calc(-1 * var(--space-10)) -14% calc(-1 * var(--space-12));
  background:
    radial-gradient(640px 340px at 50% 0%,
      color-mix(in srgb, var(--color-brand) 9%, transparent), transparent 72%),
    radial-gradient(color-mix(in srgb, var(--color-fg) 8%, transparent) 1px, transparent 1px);
  background-size:auto, 24px 24px;
  -webkit-mask-image:linear-gradient(to bottom, black 55%, transparent);
  mask-image:linear-gradient(to bottom, black 55%, transparent);
  pointer-events:none; }

/* Hero mode: the field sits on the axis as the one call to action; the label
   survives for assistive tech, the placeholder carries it visually. */
.request--hero { max-width:46rem; margin-inline:auto; padding-top:var(--space-6); }
.request--hero .request__label {
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
/* One step larger than a filter field, because on the blank page this is the
   only thing to do — but never below the phone breakpoint. There, 16px is a
   correctness floor rather than a taste: iOS zooms the viewport when a focused
   input is smaller, and this is the product's primary input. The generic 16px
   rule lost to this one on both specificity and order, so the size is scoped
   rather than restated. */
.request--hero .request__field { height:48px; }
@media (min-width: 40.01rem) {
  .request--hero .request__field { font-size:var(--text-title); }
}
.request--hero .request__submit { height:48px; padding:0 var(--space-6); }
.request--hero .filters__disclosure { text-align:center; }
.request--hero .filters__disclosure > summary { display:inline-flex; }

/* The sources row: their integrations strip, carrying provenance instead. */
.sources { display:flex; flex-wrap:wrap; justify-content:center;
  gap:var(--space-2) var(--space-6); margin:var(--space-6) 0 0;
  font:500 var(--text-label)/1.4 var(--font-mono); letter-spacing:0.02em;
  color:var(--color-fg); }
.sources span::before { content:"\2022"; margin-right:var(--space-2);
  color:var(--color-brand); }
.sources em { font-style:normal; color:var(--color-muted); }

/* The doors: numbered cards that answer the pointer. The number sits in the
   corner the way the parent numbers its sections; the arrow keeps the bottom
   corner and walks on hover, so the whole card reads as one press. */
.doors { display:grid; grid-template-columns:repeat(auto-fit, minmax(15rem, 1fr));
  gap:var(--space-4); margin-top:var(--space-6); }
.doors .browse { flex-direction:column; align-items:stretch; margin:0;
  gap:var(--space-2); padding:var(--space-5); min-height:0;
  transition:box-shadow .2s var(--ease), transform .2s var(--ease),
             border-color .2s var(--ease), background-color .2s var(--ease); }
.doors .browse:hover { background:var(--color-surface);
  border-color:var(--color-border-strong);
  box-shadow:var(--shadow-elevated-hover); transform:translateY(-2px); }
.browse__no { font:600 var(--text-label)/1 var(--font-mono); letter-spacing:0.08em;
  color:var(--color-brand); }
.doors .browse__body { gap:var(--space-1); }
.doors .browse__hint { line-height:1.5; }
/* One rung up from the third grey. Decorative, so no contrast rule binds it —
   but at 2.56:1 the mark that says "this is a door" was barely there until
   hover, on the three cards that are the landing page's whole navigation. */
.doors .browse__arrow { margin-top:var(--space-3); align-self:flex-end;
  color:var(--color-muted); }
.doors .browse:hover .browse__arrow { transform:translateX(4px); color:var(--color-brand); }

@media (max-width: 44rem) {
  .hero { margin-top:var(--space-4); }
}

/* The deadline: the supplier's deciding field. Quiet until it is about to
   close, when it takes the warning ink. */
/* Column ownership. Auto layout starved the subject to a sliver and handed the
   surplus to whichever cell had the longest unbroken content — the CPV
   description. Fixed layout makes the shares law: every column gets exactly its
   fraction and long content wraps inside it instead of bargaining for more. */
.listing { table-layout:fixed; width:100%; }
.listing th:nth-child(1) { width:26%; }
.listing th:nth-child(2) { width:19%; }
.listing th:nth-child(3) { width:15%; }
.listing th:nth-child(4) { width:8%; }
.listing th:nth-child(5) { width:11%; }
.listing th:nth-child(6) { width:7%; }
.listing th:nth-child(7) { width:14%; }
.listing td { overflow-wrap:break-word; }
/* Fixed layout means the short columns can no longer stretch to fit; their
   labels wrap by design rather than forcing the row wider. */
.listing__meta { white-space:normal; }

@media (max-width: 44rem) {
  /* Card mode lays rows as blocks; the column law does not apply there. */
  .listing { table-layout:auto; }
}

.listing__deadline { color:var(--color-muted); font-size:var(--text-caption);
  white-space:nowrap; }
.listing__deadline[data-soon] { color:var(--color-warn-deep); font-weight:600; }


/* Magnitude under the sum: 833 MDL and 26,7 mil MDL were typeset identically,
   and comparing sums is the task on this page. A hairline of brand under each
   figure, scaled to the largest on the page. */
.listing__value { position:relative; }
/* Square-rooted in the component, not linear: procurement on one page spans five
   orders of magnitude, and linearly every row but the largest drew at zero. */
.listing__bar { display:block; margin-left:auto; margin-top:3px; height:3px;
  min-width:2px; border-radius:var(--radius-field);
  background:color-mix(in srgb, var(--color-brand) 45%, transparent); }
@media (max-width: 44rem) {
  .listing__bar { margin-left:0; }
}

/* --- Official classifiers: a reference table, not a search page ----------- */

/* Same document rhythm as the statistics sheet -- this is another view over
   published reference data, and reading it should feel the same. */
.cls { padding:1rem 0 3rem; display:grid; gap:var(--space-4); }
.cls__head h1 { margin:0 0 0.5rem; font:700 var(--text-metric)/1.15 var(--font-sans);
  letter-spacing:-0.02em; }
.cls__head .section-note { margin:0; }

/* Four nomenclators, chosen not filtered: they are separate documents, so the
   control reads as tabs rather than as another facet of one list. */
.cls__tabs { display:flex; flex-wrap:wrap; gap:0.5rem; }
/* The caption rung, not the label rung. 11px is the documented floor for a short
   UPPERCASE label; this is the primary navigation of a document page in sentence
   case, and it was reading a step below the table it governs. */
.cls__tab { padding:0.45rem 0.9rem; border:1px solid var(--color-border);
  border-radius:var(--radius-card); background:var(--color-surface);
  color:var(--color-muted-strong); font:500 var(--text-caption)/1.4 var(--font-sans);
  cursor:pointer; transition:background-color 120ms ease, color 120ms ease, border-color 120ms ease; }
.cls__tab:hover { border-color:var(--color-border-strong); color:var(--color-fg); }
.cls__search { display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap; }
.cls__search input { min-width:0; }
.cls__search input::-webkit-search-cancel-button,
.cls__search input::-webkit-search-decoration { -webkit-appearance:none; appearance:none; }
.cls__count { color:var(--color-muted); font-size:var(--text-label); white-space:nowrap; }

/* The branch control. It sits in the name cell rather than a column of its own,
   because a column of carets down a nomenclator is a column of furniture — and
   the indent already says where a row sits. */
.cls__twist { border:0; background:none; cursor:pointer; padding:0.35rem;
  margin:-0.35rem 0.15rem -0.35rem -0.45rem; color:var(--color-muted);
  border-radius:var(--radius-field); vertical-align:middle; }
.cls__twist:hover { color:var(--color-fg); background:var(--color-bg-2); }
.cls__twist svg { display:block; transition:transform 120ms ease; }
/* A row that can open reads as a branch; a leaf keeps the body face. */
.cls__name:has(.cls__twist) { font-weight:500; }

@media (pointer: coarse) {
  .cls__twist { padding:0.7rem; margin:-0.7rem 0 -0.7rem -0.7rem; }
}

/* The table scrolls inside its own box: a long locality name must never make the
   whole document scroll sideways, and two hundred codes must not push the source
   line off the bottom of the world. An explicit max-height is what makes the
   sticky header below actually stick — the system asks for it on every scroll
   container, and without one this box never became a vertical scroller and the
   header never engaged. */
.cls__scroll { max-height:min(70vh, 40rem); overflow:auto; border:1px solid var(--color-border);
  border-radius:var(--radius-card); background:var(--color-surface);
  overscroll-behavior:contain; }

@media (max-width: 44rem) {
  /* One scrollbar per page. A 568px box holding 1.721 rows inside a document that
     also scrolls is the trap the listing table already refused; the classifiers
     table now follows its own sibling. */
  .cls__scroll { max-height:none; overflow:visible; }
}

.cls__table { width:100%; border-collapse:collapse; }
.cls__table th { position:sticky; top:0; z-index:1; text-align:left; padding:0.6rem 0.9rem;
  background:var(--color-surface-2); 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); white-space:nowrap; }
.cls__table td { padding:0.5rem 0.9rem; border-bottom:1px solid var(--color-border);
  vertical-align:top; }
.cls__table tbody tr:last-child td { border-bottom:none; }
.cls__table tbody tr:hover td { background:var(--color-surface-2); }

/* The code is the thing being looked up, so it is set in the mono face and given
   a fixed column rather than being left to wrap next to the name. */
.cls__code { width:1%; white-space:nowrap; color:var(--color-fg); }
.cls__name { color:var(--color-fg); }

@media (max-width:640px) {
  .cls__table th, .cls__table td { padding:0.45rem 0.6rem; }
  .cls__count { width:100%; }
}

/* The locality type, set quietly beside the name: it disambiguates rather than
   informs, so it must not compete with the name it qualifies. */
.cls__kind { margin-left:0.5rem; color:var(--color-muted); font-size:var(--text-caption); }

/* --- One classifier code, on its own page ------------------------------- */

.cls--code .cls__head h1 { display:flex; flex-wrap:wrap; align-items:baseline; gap:0.6rem; }
.cls--code .cls__head h1 .num { color:var(--color-brand); }
.cls__eyebrow { margin:0 0 0.35rem; font:600 var(--text-label)/1.45 var(--font-sans);
  letter-spacing:0.025em; text-transform:uppercase; color:var(--color-muted); }

/* The trail back up the tree. Small, quiet, and always present: a reader who
   landed here from a search engine has no other way to know where they are. */
.crumbs { display:flex; flex-wrap:wrap; align-items:center; gap:0.4rem;
  margin-bottom:var(--space-3); color:var(--color-muted); font-size:var(--text-caption); }
.crumbs a { color:var(--color-muted); }
.crumbs a:hover { color:var(--color-fg); }
.crumbs [aria-current="page"] { color:var(--color-fg); font-family:var(--font-mono); }

.cls__back { font-size:var(--text-caption); }

/* Tabs are links now, so they need the anchor reset the buttons did not. */
.cls__tab { display:inline-block; text-decoration:none; }
/* The soft tint, matching the annex switch. Two surfaces were answering "you are
   here" two opposite ways — solid brand on one, a tint on the other — so a reader
   moving between them had to relearn the signal. The tint is the one that survives
   wrapping and does not spend the accent on navigation furniture. */
.cls__tab[aria-current="page"] { background:var(--color-brand-soft);
  border-color:var(--color-brand); color:var(--color-brand-deep); font-weight:600; }
.cls__code a { text-decoration:none; }
.cls__code a:hover { text-decoration:underline; }

/* --- Notification sign-up ------------------------------------------------ */

/* A filled card, flat at rest: an offer, not a hero. One green accent (chips and
   the submit button); everything else is the cool slate ramp. */
.sub { margin-top:var(--space-6); padding:var(--space-5);
  border:1px solid var(--color-border); border-radius:var(--radius-card);
  background:var(--color-bg-2); }
.sub__title { margin:0 0 0.35rem; font:700 var(--text-title)/1.3 var(--font-sans);
  letter-spacing:-0.02em; }
.sub__lead { margin:0; max-width:60ch; color:var(--color-muted-strong);
  font-size:var(--text-caption); line-height:1.55; }

/* The name check: one field, one verdict, then the evidence. The verdict strip
   is the only colored element -- the rows under it are a listing like any other,
   because the finding is the tier, not the table. */
.nc__form { margin-top:var(--space-4); display:flex; gap:var(--space-3); flex-wrap:wrap; }
.nc__input { flex:1 1 260px; min-width:0; }
/* The universal `* + .load` disclosure margin lands on this button too and
   shoved it below the field it belongs beside; in this row the two are one
   control. On touch the button's 44px floor applies, so the field rises to
   meet it. */
.nc__form .load { margin-top:0; }
@media (pointer: coarse) { .nc__input { min-height:44px; } }
/* The verdict wears the app's notice dress -- full tone border, soft ground,
   deep ink -- because it is one: a finding stated plainly, not a new species
   of callout. */
.nc__verdict { margin-top:var(--space-5); padding:var(--space-3) var(--space-4);
  border:1px solid var(--color-border); border-radius:var(--radius-card);
  background:var(--color-surface-2);
  display:flex; gap:var(--space-3); align-items:baseline; flex-wrap:wrap; }
.nc__verdict[data-tone="danger"] { border-color:var(--color-danger);
  background:var(--color-danger-soft); color:var(--color-danger-deep); }
.nc__verdict[data-tone="warn"] { border-color:var(--color-warn);
  background:var(--color-warn-soft); color:var(--color-warn-deep); }
.nc__verdict[data-tone="ok"] { border-color:var(--color-brand);
  background:var(--color-brand-soft); color:var(--color-brand-deep); }
.nc__verdict[data-tone="info"] { border-color:var(--color-info); }
.nc__against { font-size:var(--text-caption); opacity:0.78; }
.nc__table { margin-top:var(--space-4); }
/* The similarity column hugs its number; the registered name is the column
   that earns the width. Without this the auto layout dealt the near-empty
   first column half the table. */
.nc__table th:first-child, .nc__table td.nc__pct { width:1%; }
.nc__pct { white-space:nowrap; }
.nc__pctnum { font-weight:600; }
.nc__pctnum[data-tier="danger"] { color:var(--color-danger); }
.nc__pctnum[data-tier="warn"] { color:var(--color-warn-deep); }
.nc__pctnum[data-tier="far"] { color:var(--color-muted-strong); }
.nc__bar { display:inline-block; width:64px; height:4px; margin-left:0.5rem;
  vertical-align:middle; background:var(--color-bg-2); border-radius:var(--radius-field);
  overflow:hidden; }
.nc__bar i { display:block; height:100%; background:var(--color-border-strong); }
.nc__contains { margin-left:0.5rem; background:var(--color-warn-soft); color:var(--color-warn-deep); }
.nc__method { margin-top:var(--space-5); max-width:70ch; }

.sub__form { margin-top:var(--space-4); display:grid; gap:var(--space-4); }

/* Field picker ---------------------------------------------------------- */
.sub__pick { display:grid; gap:0.4rem; }
.sub__label { font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.025em;
  text-transform:uppercase; color:var(--color-muted-strong); }

/* Chosen fields as removable chips: the tonal token — brand tint, brand text. */
.sub__chips { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:0.4rem; }
.sub__chip { display:inline-flex; align-items:center; gap:0.35rem;
  padding:0.2rem 0.35rem 0.2rem 0.6rem; border-radius:var(--radius-field);
  background:var(--color-brand-soft); color:var(--color-brand-deep);
  font-size:var(--text-caption); font-weight:600; }
/* 24px is the floor, not the drawing: the mark stays 12px, the target does not.
   At 18px this was the one control in the product below the minimum, and it is
   the only way to take a chosen field back off the list. */
.sub__chip-x { display:inline-grid; place-items:center; width:24px; height:24px;
  padding:0; border:0; border-radius:var(--radius-field); cursor:pointer;
  color:var(--color-brand); background:transparent; }
.sub__chip-x:hover { background:color-mix(in srgb, var(--color-brand) 16%, transparent); }

.sub__pick-search { max-width:22rem; }

/* The checklist scrolls inside its own border — the density rule; the page never
   scrolls to reach the end of 48 fields. */
.sub__options { list-style:none; margin:0; padding:0.25rem; display:grid; gap:1px;
  max-height:14rem; overflow-y:auto;
  border:1px solid var(--color-border); border-radius:var(--radius-field);
  background:var(--color-surface); }
.sub__option label { display:flex; align-items:center; gap:0.6rem;
  padding:0.4rem 0.55rem; border-radius:var(--radius-field); cursor:pointer;
  font-size:var(--text-base); color:var(--color-fg); }
/* The full label now arrives from the server, so the shortening happens here —
   where the reader can still hover it, and where the checkbox row keeps one line. */
.sub__option-label { flex:1 1 auto; min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.sub__option-count { flex:none; color:var(--color-muted-strong);
  font-variant-numeric:tabular-nums; font-size:var(--text-caption); }
/* Two columns above the phone breakpoint, and a taller box: forty-five fields at
   seven visible rows was six scroll passes to see the set. */
.sub__options { max-height:min(50vh, 26rem); }
@media (min-width: 40.01rem) {
  .sub__options { grid-template-columns:1fr 1fr; }
}
.sub__option label:hover { background:var(--color-bg-2); }
.sub__option input[type=checkbox] { width:1rem; height:1rem; margin:0; flex:none;
  accent-color:var(--color-brand); cursor:pointer; }
.sub__option--empty { padding:0.75rem 0.55rem; color:var(--color-muted-strong);
  font-size:var(--text-caption); }
.sub__pick-note { margin:0; color:var(--color-muted-strong); font-size:var(--text-caption); }

/* Email + submit share the last row, wrapping under the picker. */
.sub__row { display:flex; flex-wrap:wrap; gap:var(--space-3); align-items:end; }
.sub__field { display:grid; gap:0.25rem; flex:1 1 18rem; min-width:0; }
.sub__button { flex:none; height:42px; padding:0 1.3rem; cursor:pointer;
  border:1px solid var(--color-brand); border-radius:var(--radius-card);
  background:var(--color-brand); color:var(--color-brand-fg);
  font:600 var(--text-base)/1 var(--font-sans);
  transition:background .15s var(--ease), border-color .15s var(--ease); }
.sub__button:hover:not(:disabled) { background:var(--color-brand-2); border-color:var(--color-brand-2); }
.sub__button:disabled { opacity:0.6; cursor:default; }

/* Reserves its line so the form does not jump when a message appears. */
.sub__status { min-height:1.4rem; margin:var(--space-3) 0 0; font-size:var(--text-caption);
  color:var(--color-fg); }
.sub__status--ok { color:var(--color-brand-deep); }
.sub__status--bad { color:var(--color-danger); }
.sub__privacy { margin:0.35rem 0 0; color:var(--color-muted-strong); font-size:var(--text-caption); }
.sub__privacy a { color:var(--color-brand); }

@media (max-width:640px) {
  .sub__button { width:100%; min-height:44px; }
  .sub__pick-search { max-width:none; }
}

/* --- Subscribe page + confirm/unsubscribe outcomes ----------------------- */

.abonare { padding:1rem 0 3rem; max-width:var(--measure); }
.abonare__head h1 { margin:0 0 0.5rem; font:700 var(--text-metric)/1.15 var(--font-sans);
  letter-spacing:-0.02em; }
.abonare__head .section-note { margin:0 0 1rem; }

/* Where a confirmation or unsubscribe link lands. Named apart from .notice: that
   is the inline warning callout on a record, and sharing the word made the two
   overwrite each other — the callouts lost their horizontal padding, and a
   successful confirmation rendered as an amber warning laid out in a row. */
.outcome { padding:2.5rem 0 3rem; max-width:var(--measure); }
.outcome__title { margin:0 0 0.5rem; font:700 var(--text-metric)/1.15 var(--font-sans);
  letter-spacing:-0.02em; }
.outcome__body { margin:0 0 1.25rem; color:var(--color-muted-strong);
  font-size:var(--text-lg); line-height:1.6; }
.outcome__link { color:var(--color-brand); font-size:var(--text-base); }

/* --- Home landing: subscribe call to action ----------------------------- */

/* Distinct from the numbered browse rows above it: this is an action, not a
   place to browse. Filled surface, one primary affordance on the right. */
.home-cta { margin-top:var(--space-5); display:flex; align-items:center; gap:var(--space-4);
  padding:var(--space-4) var(--space-5); text-decoration:none;
  border:1px solid var(--color-border); border-radius:var(--radius-card);
  background:var(--color-brand-soft);
  transition:border-color .15s var(--ease); }
.home-cta:hover { border-color:var(--color-brand); }
.home-cta__text { display:grid; gap:0.15rem; }
.home-cta__title { font:700 var(--text-title)/1.3 var(--font-sans); letter-spacing:-0.02em;
  color:var(--color-fg); }
.home-cta__sub { font-size:var(--text-caption); color:var(--color-muted-strong); }
.home-cta__action { flex:none; margin-left:auto; padding:0 1.2rem; height:40px;
  display:inline-grid; place-items:center; border-radius:var(--radius-card);
  background:var(--color-brand); color:var(--color-brand-fg);
  font:600 var(--text-base)/1 var(--font-sans); white-space:nowrap;
  transition:background .15s var(--ease); }
.home-cta:hover .home-cta__action { background:var(--color-brand-2); }

@media (max-width:640px) {
  .home-cta { flex-direction:column; align-items:stretch; text-align:left; }
  .home-cta__action { margin-left:0; width:100%; height:44px; }
}

/* ==========================================================================
   Print. A due-diligence check ends with something to file, and Ctrl+P produced
   four thousand pixels of chrome, hero grid and sticky bar. On paper the record
   is the whole document: the frame goes, the surfaces flatten, and every section
   opens because a collapsed disclosure prints as an unanswered question.
   ========================================================================== */
@media print {
  /* The palette is redeclared rather than overridden piecemeal: ink on paper is a
     medium, not a theme, and a reader who prints from the night theme would
     otherwise get off-white text on white. Every existing rule then prints
     correctly without knowing print exists. */
  :root, html.dark {
    color-scheme:light;
    --color-bg:#FFFFFF; --color-bg-2:#FFFFFF;
    --color-surface:#FFFFFF; --color-surface-2:#FFFFFF;
    --color-fg:#000000; --color-muted:#3A3A3A; --color-muted-2:#3A3A3A;
    --color-muted-strong:#1A1A1A;
    --color-border:#9A9A9A; --color-border-strong:#5A5A5A;
    --color-brand:#000000; --color-brand-deep:#000000; --color-brand-fg:#FFFFFF;
    --color-brand-soft:#FFFFFF;
    --shadow-card:none; --shadow-card-hover:none; --shadow-soft:none;
    --shadow-elevated:none; --shadow-elevated-hover:none; --shadow-brand-glow:none;
    --hatch:transparent;
  }

  .topbar, .skip, .langs, .theme, .back, .home-cta, .about, .doors, .hero,
  .pager, .filters, .filters__disclosure, .request, .sub { display:none !important; }

  html, body { background:var(--color-bg); color:var(--color-fg); }
  .sheet { max-width:none; padding:0; }

  /* Layered surfaces mean nothing on paper; rules do. */
  .section, .extract__head, .metric {
    box-shadow:none; border:0; border-top:1px solid var(--color-border); border-radius:0;
    padding:0.6rem 0 0; margin-top:0.9rem; break-inside:avoid; }
  .scroll, .cls__scroll, .fin__detail { overflow:visible; max-height:none; }

  /* A disclosure that prints shut prints a question the page already answered. */
  #proc-contracts, #history-panel, #connections-panel, #acts-all,
  #auth-suppliers, #live-list { display:block !important; }
  .load { display:none !important; }

  /* Provenance is the point of a printed extract, so it stays whole. */
  .provenance { break-inside:avoid; border-top:2px solid var(--color-fg); }
  a { color:var(--color-fg); text-decoration:none; }
  .entry, .tl, .contracts li { break-inside:avoid; }
}

/* --- Legal documents: privacy and terms ---------------------------------- */

/* Reading pages, not data sheets: everything is held to the measure, and the
   document rhythm comes from the section headings alone. Body text steps up one
   rung -- two thousand words at label size is hostile, and there is no column
   of figures here to align with. */
.legal { padding:1rem 0 3rem; max-width:var(--measure); }
.legal__head h1 { margin:0 0 0.5rem; font:700 var(--text-metric)/1.15 var(--font-sans);
  letter-spacing:-0.02em; }
.legal__head .section-note { margin:0 0 1rem; }
.legal__section { margin-top:var(--space-6); }
.legal__section h2 { margin:0 0 0.5rem; font:700 var(--text-title)/1.3 var(--font-sans);
  letter-spacing:-0.025em; }
.legal__section p, .legal__section li { font-size:var(--text-lg); line-height:1.6; }
.legal__section p { margin:0 0 0.75rem; }
.legal__section ul { margin:0 0 0.75rem; padding-left:1.25rem; }
.legal__section li { margin:0 0 0.35rem; }
.legal__section li::marker { color:var(--color-muted); }

/* The footer's second line. Same quiet register as the colophon itself; links
   underline only on hover so the line does not shout. */
.colophon__legal { display:flex; gap:var(--space-5); margin-top:0.6rem; }
.colophon__legal a { color:var(--color-muted); text-decoration:none; }
.colophon__legal a:hover { color:var(--color-fg); text-decoration:underline; }

/* --- Full statement detail — the filed annexes under a summary year --------- */

.ind__title { margin:1.1rem 0 0.35rem; font:600 var(--text-base)/1.3 var(--font-sans);
  color:var(--color-fg); }
.ind { width:100%; border-collapse:collapse; font-size:var(--text-caption); }
.ind th { font:600 var(--text-label)/1.4 var(--font-sans); text-transform:uppercase;
  letter-spacing:0.06em; color:var(--color-muted); text-align:left;
  padding:0.3rem 0.6rem; border-bottom:1px solid var(--color-border-strong); }
.ind th.num, .ind td.num { text-align:right; }
.ind td { padding:0.3rem 0.6rem; border-bottom:1px solid var(--color-border);
  vertical-align:baseline; }
.ind tr:last-child td { border-bottom:0; }
/* Component lines indent under their total, as on the filing form. */
.ind__sub th:first-child { padding-left:1.6rem; color:var(--color-muted-strong); }

/* --- Financials: years down, metrics across --------------------------------- */

/* The comparison axis is vertical, which is what tabular-nums and right alignment
   are for. Metrics-across put it horizontal and, worse, let each cell pick its own
   unit, so one row read "241,6 mii · -2 mil · 909,8 mii". A column is one metric,
   so it carries one scale, named once in its header. */
.fin--y { width:100%; }
.fin--y thead th { background:transparent; vertical-align:bottom; }
.fin--y th[scope="col"] { border-bottom:1px solid var(--color-border-strong); }

/* The year is the row's name, so it is a th — but a row header is data, not a
   band: it keeps the body's face and drops the uppercase micro treatment the
   column heads wear. */
.fin--y tbody th.fin__yrcell, .ind tbody th {
  font:500 var(--text-base)/1.5 var(--font-sans); letter-spacing:0;
  text-transform:none; color:var(--color-fg); text-align:left; white-space:nowrap; }
.fin--y tbody tr:hover td, .fin--y tbody tr:hover th { background:var(--color-surface-2); }
.fin--y .fin__row--open th, .fin--y .fin__row--open td { background:var(--color-surface-2); }
.fin--y td.num { font-family:var(--font-mono); }

.ind tbody th { font-size:var(--text-caption); font-weight:500; text-align:left;
  border-bottom:1px solid var(--color-border); }
.ind__sub th:first-child { padding-left:1.6rem; color:var(--color-muted-strong);
  font-weight:400; }

/* "MDL mld" under the metric name. Not uppercased with the header — "MDL MLD"
   reads as two abbreviations rather than a unit. */
.fin__unit { display:block; font:500 var(--text-micro)/1.2 var(--font-sans);
  letter-spacing:0.04em; text-transform:none; color:var(--color-muted); }

/* A year header is the way into its statement. Padded to a real touch target. */
/* 24px is the floor; this measured 23.6 and failed it by four tenths of a pixel
   on a desktop pointer, where none of the coarse-pointer expansion applies. */
.fin__yr { border:0; background:none; padding:0.4rem 0.2rem; margin:-0.4rem -0.2rem;
  min-height:24px; cursor:pointer; font:inherit;
  color:var(--color-brand); display:inline-flex; align-items:center; gap:0.3rem; }
.fin__yr:hover { color:var(--color-brand-deep); text-decoration:underline; }
/* At rest a year is a row label, not a call to action. Six green years in a column
   spent the accent six times on the same decision; the caret carries the affordance
   and the hover above still says it is pressable. */
.fin__yr { color:var(--color-fg); }
.fin__caret { transition:transform 0.15s ease-out; display:block; }
.fin__caret[data-open="true"] { transform:rotate(180deg); }

/* The opened statement: a sunk sheet under the table, scrollable on its own. */
.fin__detail { margin-top:0.9rem; padding:0.4rem 0.9rem 1.1rem;
  background:var(--color-surface-2); border:1px solid var(--color-border);
  border-radius:var(--radius-field); overflow-x:auto; }
.ind__year { margin:0.8rem 0 0; font:600 var(--text-base)/1.3 var(--font-sans); }

/* The two readings of one filing, and the switch between them. Plain leads; the
   statement as filed is one press away and stays complete, because it is the
   provenance for everything the plain view says. */
.ind__head { display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-3); flex-wrap:wrap; }
.viewsw { display:inline-flex; border:1px solid var(--color-border-strong);
  border-radius:var(--radius-field); overflow:hidden; }
.viewsw__b { border:0; background:none; cursor:pointer; padding:0.35rem 0.7rem;
  font:500 var(--text-label)/1.4 var(--font-sans); color:var(--color-muted-strong); }
.viewsw__b + .viewsw__b { border-left:1px solid var(--color-border-strong); }
.viewsw__b:hover { background:var(--color-surface); }
.viewsw__b[aria-pressed="true"] { background:var(--color-brand-soft); color:var(--color-brand-deep); }

/* The annex switch: the same control, but naming sections rather than two views of
   one thing — so it wraps instead of squeezing five labels onto one line, and it
   marks the current one with aria-selected as a tablist must. */
/* Detached rather than joined, because this one wraps. A joined control that
   breaks onto a second row puts row two flush under row one with no divider and
   doubles a border against the container's own — it reads as broken chrome. Five
   sections wrap; two views of one report do not, so only this variant changes. */
.viewsw--tabs { flex-wrap:wrap; gap:var(--space-2); margin:0 0 var(--space-6);
  border:0; border-radius:0; overflow:visible; }
.viewsw--tabs .viewsw__b { padding:0.55rem 0.9rem; font-size:var(--text-caption);
  border:1px solid var(--color-border-strong); border-radius:var(--radius-field); }
.viewsw--tabs .viewsw__b + .viewsw__b { border-left:1px solid var(--color-border-strong); }

/* The search box keeps room for its own clear control; the native one is
   suppressed a few rules down and nothing replaced it, so a phone user who
   mistyped had to select-all-and-delete. */
.cls__field { position:relative; display:flex; flex:1 1 18rem; min-width:0; }
.cls__field input { flex:1; min-width:0; padding-right:2.5rem; }
.cls__clear { position:absolute; right:0.35rem; top:50%; transform:translateY(-50%);
  display:flex; align-items:center; justify-content:center; width:2rem; height:2rem;
  border:0; background:none; cursor:pointer; color:var(--color-muted);
  font:400 var(--text-lg)/1 var(--font-sans); border-radius:var(--radius-field); }
.cls__clear:hover { color:var(--color-fg); background:var(--color-bg-2); }
.viewsw__b[aria-selected="true"] { background:var(--color-brand-soft); color:var(--color-brand-deep); }

/* Indent by the depth the form's own arithmetic implies, capped so a deep annex
   never walks the labels off a phone. */
.ind tr[data-depth] th:first-child { padding-left:0.6rem; }
.ind tr[data-depth="1"] th:first-child { padding-left:1.1rem; }
.ind tr[data-depth="2"] th:first-child { padding-left:1.7rem; }
.ind tr[data-depth="3"] th:first-child { padding-left:2.3rem; }
.ind tr[data-depth="4"] th:first-child { padding-left:2.9rem; }

/* Four answers, then the same filing as proportions. */
.plain__cards { display:grid; gap:var(--space-3); margin:0.9rem 0 1.4rem;
  grid-template-columns:repeat(auto-fit, minmax(9.5rem, 1fr)); }
.plain__card { background:var(--color-surface); border:1px solid var(--color-border);
  border-radius:var(--radius-field); padding:0.7rem 0.85rem; }
.plain__lbl { margin:0; font:600 var(--text-label)/1.4 var(--font-sans);
  letter-spacing:0.025em; text-transform:uppercase; color:var(--color-muted); }
.plain__val { margin:0.2rem 0 0.15rem; font:600 var(--text-title)/1.25 var(--font-sans);
  font-variant-numeric:tabular-nums; }
.plain__note { margin:0; font:400 var(--text-caption)/1.45 var(--font-sans);
  color:var(--color-muted-strong); }
.plain__h { margin:1.3rem 0 0.4rem; font:600 var(--text-base)/1.3 var(--font-sans); }

/* One bar, whose bands always total it. The gap is the sheet showing through, so
   touching bands stay separable without a stroke around each one. */
.plain__bar { display:flex; gap:2px; height:2rem; margin:0.5rem 0 0.6rem;
  border-radius:var(--radius-field); overflow:hidden; }
.plain__bar--thin { height:1.35rem; }
.plain__seg { display:block; min-width:1px; }
.plain__seg--c1 { background:var(--color-muted-strong); }
.plain__seg--c2 { background:var(--color-muted); }
.plain__seg--c3 { background:var(--color-muted-2); }
.plain__seg--c4 { background:color-mix(in srgb, var(--color-muted-2) 55%, var(--color-surface)); }
.plain__seg--tax { background:var(--color-warn); }
.plain__seg--profit { background:var(--color-brand); }
.plain__seg--own { background:var(--color-brand); }
.plain__seg--lt { background:var(--color-muted-strong); }
.plain__seg--cur { background:var(--color-warn); }
.plain__seg--rest { background:var(--color-muted-2); }

.plain__key { display:flex; flex-wrap:wrap; gap:0.3rem 1.1rem; margin:0 0 0.4rem;
  padding:0; list-style:none; font:400 var(--text-caption)/1.5 var(--font-sans);
  color:var(--color-muted-strong); font-variant-numeric:tabular-nums; }
.plain__key li { display:inline-flex; align-items:center; gap:0.4rem; }
.plain__dot { width:9px; height:9px; border-radius:50%; display:inline-block; flex:none; }
.plain__dot--c1 { background:var(--color-muted-strong); }
.plain__dot--c2 { background:var(--color-muted); }
.plain__dot--c3 { background:var(--color-muted-2); }
.plain__dot--c4 { background:color-mix(in srgb, var(--color-muted-2) 55%, var(--color-surface)); }
.plain__dot--tax { background:var(--color-warn); }
.plain__dot--profit { background:var(--color-brand); }
.plain__dot--own { background:var(--color-brand); }
.plain__dot--lt { background:var(--color-muted-strong); }
.plain__dot--cur { background:var(--color-warn); }
.plain__dot--rest { background:var(--color-muted-2); }

.plain__warn { margin:0.5rem 0 0; padding:0.5rem 0.7rem; border-radius:var(--radius-field);
  background:var(--color-danger-soft); color:var(--color-danger-deep);
  font:500 var(--text-caption)/1.5 var(--font-sans); }

/* Money that actually left: a label, its share of the largest payment, the sum. */
.plain__paid { margin:0.4rem 0 0; padding:0; list-style:none; }
.plain__paid li { display:grid; grid-template-columns:minmax(6rem, 11rem) 1fr auto;
  align-items:center; gap:var(--space-3); padding:0.25rem 0;
  font:400 var(--text-caption)/1.5 var(--font-sans); }
.plain__paidlbl { color:var(--color-muted-strong); }
.plain__track { height:0.6rem; background:var(--color-surface);
  border:1px solid var(--color-border); border-radius:999px; overflow:hidden; }
.plain__fill { display:block; height:100%; background:var(--color-muted-strong); }
.plain__paidamt { text-align:right; font-variant-numeric:tabular-nums; }

.plain__peer { margin:1.1rem 0 0; font:400 var(--text-caption)/1.6 var(--font-sans);
  color:var(--color-muted-strong); }

@media (max-width: 44rem) {
  /* Two answers across rather than four down. At 375px a 9.5rem minimum falls to
     a single column and spends 364px of the screen on four figures; 8rem fits
     two, which is the shape the cards were drawn for. */
  .plain__cards { grid-template-columns:repeat(auto-fit, minmax(8rem, 1fr)); }
  .plain__bar { height:1.6rem; }

  /* The label and the sum carry the comparison on their own — the rows are
     ordered by size — and the track was the first thing to become unreadable. */
  .plain__paid li { grid-template-columns:1fr auto; }
  .plain__track { display:none; }

  /* This switch decides what the whole panel says, so it gets a thumb-sized
     target and a legible size. 11px is the floor for a label, not for a control
     someone presses — the same reason the year buttons grow here. */
  .viewsw__b { padding:0.85rem 1rem; font-size:var(--text-caption); }

  /* Half-steps for the depth cue. Row labels do not wrap, so the filed statement
     scrolls sideways inside its own panel, and every rem of indent is a rem more
     of that scroll. Four levels still read apart at this step. */
  .ind tr[data-depth] th:first-child { padding-left:0.35rem; }
  .ind tr[data-depth="1"] th:first-child { padding-left:0.75rem; }
  .ind tr[data-depth="2"] th:first-child { padding-left:1.15rem; }
  .ind tr[data-depth="3"] th:first-child { padding-left:1.55rem; }
  .ind tr[data-depth="4"] th:first-child { padding-left:1.95rem; }
}

@media (max-width: 44rem) {
  /* One card per year. Six metric columns cannot fit a phone, and the answer is
     not a sideways scroll — it is the two-form rule the design system already
     states: table from `sm` up, cards below, one component. */
  .fin--y thead { display:none; }
  .fin--y, .fin--y tbody, .fin--y tr, .fin--y td, .fin--y th { display:block; width:100%; }
  .fin--y tbody tr { padding:var(--space-3) 0; border-bottom:1px solid var(--color-border); }
  .fin--y tbody tr:last-child { border-bottom:0; }
  .fin--y th, .fin--y td { border:0; padding:0; }

  /* The year heads its card. */
  .fin--y tbody th.fin__yrcell { margin-bottom:var(--space-2);
    font:700 var(--text-title)/1.3 var(--font-sans); }

  /* Each figure names itself and sits opposite its label, so the card reads as a
     two-column sheet rather than a stack of unlabelled numbers. */
  .fin--y tbody td { display:flex; align-items:baseline; justify-content:space-between;
    gap:var(--space-4); padding:0.3rem 0; text-align:right; }
  .fin--y tbody td::before { content:attr(data-label); flex:none; text-align:left;
    font:600 var(--text-label)/1.45 var(--font-sans); letter-spacing:0.025em;
    text-transform:uppercase; color:var(--color-muted); }

  /* The opened statement fits the phone edge to edge — no sideways nudge. */
  .fin__detail { padding:0.25rem 0.45rem 0.9rem; }
  .ind th, .ind td { padding:0.3rem 0.35rem; }
}

/* Revenue vs profit, six years. Brand green earns the revenue bar; profit takes
   the amber, and a loss simply hangs below the axis — no extra colour for it. */
.finchart { width:100%; height:auto; margin:1rem 0 0.25rem; }
.finchart__axis { stroke:var(--color-border-strong); stroke-width:1; }
.finchart__year { fill:var(--color-muted); font:500 12px var(--font-mono); }
.finchart__rev { fill:var(--color-brand); }
/* Was --color-warn, which on this same record means "older than 14 days". A
   status token painting a data series trains the reader to misread both. */
.finchart__profit { fill:var(--color-muted-strong); opacity:0.9; }
.sw--rev { background:var(--color-brand); }
.sw--profit { background:var(--color-muted-strong); }

/* Small screens, declared after the chart's base rules so the cascade holds:
   SVG type is sized in viewBox units — 30 units on a ~300px render of the
   960-unit canvas lands at a legible ~9px — and the year buttons grow to a
   real thumb target without moving the table's rhythm. */
@media (max-width: 44rem) {
  .finchart .finchart__year { font-size:30px; font-weight:600; }
  .finchart { margin-top:0.5rem; }
  .fin__yr { padding:0.8rem 0.5rem; margin:-0.8rem -0.5rem; }
}
