/* Info Man — data-terminal design system, in two themes.
   This is the ONLY stylesheet the site ships: Bootstrap was removed in Phase B, so the reset below
   and the "Identity / framework classes" section at the foot of this file own everything its reboot,
   grid, nav and form components used to provide. No external fonts.

   THEMING. Every colour the site paints flows through a semantic token below. :root carries the DARK
   theme, which is the historical default and is unchanged to the byte. The light theme is declared
   twice, and deliberately: once inside a prefers-color-scheme query for readers who have expressed no
   choice, and once under [data-theme="light"] for readers who have. CSS cannot share one declaration
   list across a media boundary, so the two copies are kept honest by a test that parses this file and
   asserts they declare the same tokens with the same values.

   Contrast: every light text token is >= 4.5:1 on --ground (cream) and on --surface-1 (paper). The
   palette this was derived from fails that at its muted grey (4.34), its amber (1.73) and its red
   (3.42); those three are darkened here rather than copied. */

:root {
  color-scheme: dark;

  /* Ground + layered surfaces (near-black charcoal → lifted steel). */
  --ground: #0C0E0D;
  --surface-1: #141815;
  --surface-2: #1B201C;
  --surface-3: #232A26;
  --border: #2A2F2C;
  --border-strong: #3A403C;

  /* Ink (steel / silver). Contrast on --ground: ink 14.05, muted 7.69, faint 4.33. */
  --ink: #D7DDD9;
  --ink-muted: #9AA6A0;
  --ink-faint: #7C8880;

  /* Forest-green accent — THE accent (links, live markers, cheapest highlights).
     accent 7.29 on ground; accent-strong 8.97; on-accent text 7.29 on accent. */
  --accent: #46B27A;
  --accent-strong: #5BC48D;
  --accent-dim: rgba(70, 178, 122, 0.14);
  --on-accent: #0C0E0D;

  /* Restrained secondary: amber = "up / priciest", danger = strong warning.
     Both distinct from the accent green (which carries "down / cheap = good"). */
  --amber: #E0A34A;
  --danger: #E56B54;
  --danger-strong: #ef8570;
  --on-danger: #ffffff;

  /* Chart-only inks. */
  --steel: #7E93AE;
  --grid: #333A36;

  --focus: #5BC48D;

  /* THE FLAG, ONE SET IN BOTH THEMES. The owner's rule is that the flag's colours are not altered to
     suit a background, so the yellow is the flag's own #FDB913 everywhere and the ground is what
     yields: every place the flag appears — the wordmark, the menu control's bars, the drawer's top
     stripe — is backed by --brand-plaque below. The green and the red are the brighter pair rather
     than the flag's printed #006A44/#C1272D because both of those measure under 2.5:1 on any dark
     ground and would simply not be seen; the yellow needed no such adjustment. */
  --flag-yellow: #FDB913;
  --flag-green: #2FA36A;
  --flag-red: #E0543F;

  /* The deep green ink used to back the flag where it lands on a light surface. Only the drawer's top
     stripe needs it — the drawer keeps a paper surface in the light theme — so it is transparent here,
     the dark theme's drawer already being dark. */
  --brand-plaque: transparent;

  /* THE DEEP BAND. Two blocks carry the wordmark — the sticky header and the home page's brand block —
     and both are dark ground in BOTH themes, which is what lets the flag keep its own colours instead
     of being darkened to survive cream paper. Every --band- token below is the value the ink, the
     surfaces and the accent take INSIDE those two blocks; the rule that applies them is "header,
     .page-head". Here they are simply this theme's own values, because here the whole page is already
     the band's ground and nothing needs to change when a reader crosses into it. */
  --band-ground: #0C0E0D;
  --band-surface-1: #141815;
  --band-ink: #D7DDD9;
  --band-ink-muted: #9AA6A0;
  --band-ink-faint: #7C8880;
  --band-border: #2A2F2C;
  --band-border-strong: #3A403C;
  --band-accent: #46B27A;
  --band-accent-strong: #5BC48D;
  --band-accent-dim: rgba(70, 178, 122, 0.14);
  --band-on-accent: #0C0E0D;
  --band-hover: rgba(255, 255, 255, 0.06);

  /* The brand block is a PANEL only where it has to be one — in the light theme, where it is a deep
     rectangle cut out of cream paper. Here the page is already that ground, so it stays bare type and
     the dark home page is untouched. */
  --band-panel: transparent;
  --band-panel-pad: 0;

  /* Tinted washes and hairlines. Every one of these was an rgba() literal repeated through the file;
     as tokens they can differ per theme, which they must — a translucent white lifts a dark surface
     and dirties a cream one. */
  --accent-line: rgba(70, 178, 122, 0.4);
  --accent-line-strong: rgba(70, 178, 122, 0.5);
  --accent-wash: rgba(70, 178, 122, 0.12);
  --accent-pulse: rgba(70, 178, 122, 0.5);
  --accent-pulse-out: rgba(70, 178, 122, 0);
  --amber-line: rgba(224, 163, 74, 0.4);
  --amber-wash: rgba(224, 163, 74, 0.12);
  --amber-rule: rgba(224, 163, 74, 0.55);
  --info: #8fb8e8;
  --info-line: rgba(110, 160, 220, 0.45);
  --info-wash: rgba(110, 160, 220, 0.12);
  --good: #8fc79b;
  --good-line: rgba(110, 180, 130, 0.45);
  --good-wash: rgba(110, 180, 130, 0.12);
  --code-ink: #d63384;
  --overlay: rgba(0, 0, 0, 0.5);
  --footer-bg: rgba(10, 12, 11, 0.6);
  --drawer-bg: rgba(6, 8, 7, 0.92);
  --hover-wash: rgba(255, 255, 255, 0.06);
  --page-glow-1: rgba(70, 178, 122, 0.05);
  --page-glow-2: rgba(126, 147, 174, 0.04);

  /* Chart inks, referenced from the inline-SVG builders as var(--chart-*). They are NOT decoration:
     a series that vanishes into the background is a missing fact, so each one is checked against the
     ground it is drawn on. 1-11 are the categorical series palette, in the order the builders index
     them, so a chart keeps its colours when the theme flips. */
  --chart-axis: #4A544E;
  --chart-text: #9AA6A0;
  --chart-muted: #4A544E;
  --chart-1: #5BC48D;
  --chart-2: #E0A34A;
  --chart-3: #7E93AE;
  --chart-4: #C98BD9;
  --chart-5: #6FB3D9;
  --chart-6: #D98B6F;
  --chart-7: #9BC46F;
  --chart-8: #C46F9B;
  --chart-9: #6FC4B3;
  --chart-10: #B3A36F;
  --chart-11: #D96C6C;

  /* One mark per module — the tile's top rule, its icon, and the drawer entry's icon. */
  --mod-home: #8b949e;
  --mod-fuel: #e3a008;
  --mod-electricity: #d4a72c;
  --mod-weather: #6cb8e6;
  --mod-heating: #db6d28;
  --mod-food: #f0883e;
  --mod-offers: #d4537e;
  --mod-housing: #56d4dd;
  --mod-taxes: #bc8cff;
  --mod-news: #58a6ff;
  --mod-markets: #39d353;
  --mod-cases: #a5d6ff;
  --mod-initiatives: #db61db;
  --mod-migration: #ffa657;
  --mod-forests: #2ea043;
  --mod-cars: #f85149;
  --mod-auctions: #a371f7;
  --mod-funding: #3fb950;
  --mod-assistance: #4ec9b0;
  --mod-map: #c9a66b;
  --mod-numbers: #7fb0d6;
  --mod-privacy: #8b949e;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;

  --radius: 10px;
  --radius-sm: 6px;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --shadow: 0 1px 0 rgba(255, 255, 255, 0.02) inset, 0 8px 24px rgba(0, 0, 0, 0.35);
}

/* ----- Light theme -----
   Cream paper against forest ink. Declared twice on purpose — see the note at the top of this file;
   a test pins the two copies identical. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
  color-scheme: light;

  --ground: #f5f1e8;
  --surface-1: #fffdf9;
  --surface-2: #fbf8f1;
  --surface-3: #f1ece1;
  --border: #dfe4df;
  --border-strong: #c7cfc7;

  --ink: #152a27;
  --ink-muted: #5c6a65;
  --ink-faint: #626f6a;

  --accent: #225f49;
  --accent-strong: #1a4c3a;
  --accent-dim: rgba(34, 95, 73, 0.1);
  --on-accent: #fffdf9;

  --amber: #8a5a12;
  --danger: #b03a20;
  --danger-strong: #a33218;
  --on-danger: #fffdf9;

  --steel: #41607f;
  --grid: #e4e8e2;

  --focus: #225f49;

  --flag-yellow: #FDB913;
  --flag-green: #2FA36A;
  --flag-red: #E0543F;
  --brand-plaque: #0d2c22;

  --band-ground: #163d31;
  --band-surface-1: #12362c;
  --band-ink: #f2f6f3;
  --band-ink-muted: #b3cbc0;
  --band-ink-faint: #9db5aa;
  --band-border: rgba(242, 246, 243, 0.22);
  --band-border-strong: rgba(242, 246, 243, 0.38);
  --band-accent: #7fd3a4;
  --band-accent-strong: #9ce0ba;
  --band-accent-dim: rgba(127, 211, 164, 0.18);
  --band-on-accent: #0d2c22;
  --band-hover: rgba(242, 246, 243, 0.1);
  --band-panel: #163d31;
  --band-panel-pad: var(--space-5);

  --accent-line: rgba(34, 95, 73, 0.35);
  --accent-line-strong: rgba(34, 95, 73, 0.5);
  --accent-wash: rgba(34, 95, 73, 0.08);
  --accent-pulse: rgba(34, 95, 73, 0.45);
  --accent-pulse-out: rgba(34, 95, 73, 0);
  --amber-line: rgba(138, 90, 18, 0.35);
  --amber-wash: rgba(240, 174, 45, 0.16);
  --amber-rule: rgba(138, 90, 18, 0.55);
  --info: #1c5fa8;
  --info-line: rgba(28, 95, 168, 0.35);
  --info-wash: rgba(223, 234, 240, 0.9);
  --good: #1d6b2c;
  --good-line: rgba(29, 107, 44, 0.35);
  --good-wash: rgba(225, 238, 227, 0.9);
  --code-ink: #a32267;
  --overlay: rgba(21, 42, 39, 0.4);
  --footer-bg: rgba(255, 253, 249, 0.75);
  --drawer-bg: rgba(255, 253, 249, 0.96);
  --hover-wash: rgba(21, 42, 39, 0.05);
  --page-glow-1: rgba(34, 95, 73, 0.04);
  --page-glow-2: rgba(65, 96, 127, 0.03);

  --chart-axis: #8f9c90;
  --chart-text: #5c6a65;
  --chart-muted: #748179;
  --chart-1: #1f7a52;
  --chart-2: #9a6410;
  --chart-3: #41607f;
  --chart-4: #7b4a91;
  --chart-5: #1f6d94;
  --chart-6: #a4522f;
  --chart-7: #5a7524;
  --chart-8: #93386b;
  --chart-9: #0f6f63;
  --chart-10: #7a6420;
  --chart-11: #a83a3a;

  --mod-home: #5b6670;
  --mod-fuel: #8a5f04;
  --mod-electricity: #7d6410;
  --mod-weather: #256f96;
  --mod-heating: #96471a;
  --mod-food: #9c5324;
  --mod-offers: #9c2f56;
  --mod-housing: #0f6e75;
  --mod-taxes: #6b3fa0;
  --mod-news: #1c5fa8;
  --mod-markets: #1c7a35;
  --mod-cases: #2f6591;
  --mod-initiatives: #8a2f8a;
  --mod-migration: #8a5320;
  --mod-forests: #1d6b2c;
  --mod-cars: #a8322c;
  --mod-auctions: #6a3fa8;
  --mod-funding: #1f7538;
  --mod-assistance: #12705f;
  --mod-map: #6f5426;
  --mod-numbers: #2b5f85;
  --mod-privacy: #5b6670;

  --shadow: 0 1px 0 rgba(255, 255, 255, 0.6) inset, 0 6px 18px rgba(21, 42, 39, 0.08);
  }
}

:root[data-theme="light"] {
  color-scheme: light;

  --ground: #f5f1e8;
  --surface-1: #fffdf9;
  --surface-2: #fbf8f1;
  --surface-3: #f1ece1;
  --border: #dfe4df;
  --border-strong: #c7cfc7;

  --ink: #152a27;
  --ink-muted: #5c6a65;
  --ink-faint: #626f6a;

  --accent: #225f49;
  --accent-strong: #1a4c3a;
  --accent-dim: rgba(34, 95, 73, 0.1);
  --on-accent: #fffdf9;

  --amber: #8a5a12;
  --danger: #b03a20;
  --danger-strong: #a33218;
  --on-danger: #fffdf9;

  --steel: #41607f;
  --grid: #e4e8e2;

  --focus: #225f49;

  --flag-yellow: #FDB913;
  --flag-green: #2FA36A;
  --flag-red: #E0543F;
  --brand-plaque: #0d2c22;

  --band-ground: #163d31;
  --band-surface-1: #12362c;
  --band-ink: #f2f6f3;
  --band-ink-muted: #b3cbc0;
  --band-ink-faint: #9db5aa;
  --band-border: rgba(242, 246, 243, 0.22);
  --band-border-strong: rgba(242, 246, 243, 0.38);
  --band-accent: #7fd3a4;
  --band-accent-strong: #9ce0ba;
  --band-accent-dim: rgba(127, 211, 164, 0.18);
  --band-on-accent: #0d2c22;
  --band-hover: rgba(242, 246, 243, 0.1);
  --band-panel: #163d31;
  --band-panel-pad: var(--space-5);

  --accent-line: rgba(34, 95, 73, 0.35);
  --accent-line-strong: rgba(34, 95, 73, 0.5);
  --accent-wash: rgba(34, 95, 73, 0.08);
  --accent-pulse: rgba(34, 95, 73, 0.45);
  --accent-pulse-out: rgba(34, 95, 73, 0);
  --amber-line: rgba(138, 90, 18, 0.35);
  --amber-wash: rgba(240, 174, 45, 0.16);
  --amber-rule: rgba(138, 90, 18, 0.55);
  --info: #1c5fa8;
  --info-line: rgba(28, 95, 168, 0.35);
  --info-wash: rgba(223, 234, 240, 0.9);
  --good: #1d6b2c;
  --good-line: rgba(29, 107, 44, 0.35);
  --good-wash: rgba(225, 238, 227, 0.9);
  --code-ink: #a32267;
  --overlay: rgba(21, 42, 39, 0.4);
  --footer-bg: rgba(255, 253, 249, 0.75);
  --drawer-bg: rgba(255, 253, 249, 0.96);
  --hover-wash: rgba(21, 42, 39, 0.05);
  --page-glow-1: rgba(34, 95, 73, 0.04);
  --page-glow-2: rgba(65, 96, 127, 0.03);

  --chart-axis: #8f9c90;
  --chart-text: #5c6a65;
  --chart-muted: #748179;
  --chart-1: #1f7a52;
  --chart-2: #9a6410;
  --chart-3: #41607f;
  --chart-4: #7b4a91;
  --chart-5: #1f6d94;
  --chart-6: #a4522f;
  --chart-7: #5a7524;
  --chart-8: #93386b;
  --chart-9: #0f6f63;
  --chart-10: #7a6420;
  --chart-11: #a83a3a;

  --mod-home: #5b6670;
  --mod-fuel: #8a5f04;
  --mod-electricity: #7d6410;
  --mod-weather: #256f96;
  --mod-heating: #96471a;
  --mod-food: #9c5324;
  --mod-offers: #9c2f56;
  --mod-housing: #0f6e75;
  --mod-taxes: #6b3fa0;
  --mod-news: #1c5fa8;
  --mod-markets: #1c7a35;
  --mod-cases: #2f6591;
  --mod-initiatives: #8a2f8a;
  --mod-migration: #8a5320;
  --mod-forests: #1d6b2c;
  --mod-cars: #a8322c;
  --mod-auctions: #6a3fa8;
  --mod-funding: #1f7538;
  --mod-assistance: #12705f;
  --mod-map: #6f5426;
  --mod-numbers: #2b5f85;
  --mod-privacy: #5b6670;

  --shadow: 0 1px 0 rgba(255, 255, 255, 0.6) inset, 0 6px 18px rgba(21, 42, 39, 0.08);
}

/* ----- Reset -----
   Everything Bootstrap's reboot silently provided and the page rendering depends on. Each rule here
   reproduces a rule that used to match live elements, so removing bootstrap.min.css cost nothing
   visually. Element rules the design system re-states (body, headings, links) still follow below and
   win by source order. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

@media (prefers-reduced-motion: no-preference) {
  :root {
    scroll-behavior: smooth;
  }
}

h1, h2, h3, h4, h5, h6 {
  margin-top: 0;
  margin-bottom: 0.5rem;
  font-weight: 500;
  line-height: 1.2;
}

/* Fluid heading scale below 1200px, fixed above — the sizes the Identity and Error pages render at. */
h1 { font-size: calc(1.375rem + 1.5vw); }
h2 { font-size: calc(1.325rem + 0.9vw); }
h3 { font-size: calc(1.3rem + 0.6vw); }
h4 { font-size: calc(1.275rem + 0.3vw); }
h5 { font-size: 1.25rem; }
h6 { font-size: 1rem; }

@media (min-width: 1200px) {
  h1 { font-size: 2.5rem; }
  h2 { font-size: 2rem; }
  h3 { font-size: 1.75rem; }
  h4 { font-size: 1.5rem; }
}

p {
  margin-top: 0;
  margin-bottom: 1rem;
}

dl, ol, ul {
  margin-top: 0;
  margin-bottom: 1rem;
}

ol, ul {
  padding-left: 2rem;
}

hr {
  margin: 1rem 0;
  color: inherit;
  border: 0;
  border-top: 1px solid;
  opacity: 0.25;
}

b, strong {
  font-weight: bolder;
}

code, kbd, pre, samp {
  font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 1em;
}

code {
  font-size: 0.875em;
  color: var(--code-ink);
  overflow-wrap: break-word;
}

img, svg {
  vertical-align: middle;
}

table {
  caption-side: bottom;
  border-collapse: collapse;
}

th {
  text-align: -webkit-match-parent;
}

thead, tbody, tfoot, tr, td, th {
  border-color: inherit;
  border-style: solid;
  border-width: 0;
}

label {
  display: inline-block;
}

button {
  border-radius: 0;
}

button, input, optgroup, select, textarea {
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

button, select {
  text-transform: none;
}

select {
  overflow-wrap: normal;
}

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
  appearance: button;
}

button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
  cursor: pointer;
}

[type="search"] {
  -webkit-appearance: textfield;
  appearance: textfield;
  outline-offset: -2px;
}

summary {
  display: list-item;
  cursor: pointer;
}

[role="button"] {
  cursor: pointer;
}

/* 16px everywhere, narrow screens included. At the old 15px the 0.75rem floor rendered at 11.25px
   on exactly the devices that most need legible type; one root size means the floor means 12px. */
html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  margin: 0;
  display: flex;
  flex-direction: column;
  background-color: var(--ground);
  color: var(--ink);
  font-family: var(--font-sans);
  line-height: 1.55;
  /* Subtle rune-as-texture: a faint engraved grain, never decorative kitsch. */
  background-image:
    radial-gradient(circle at 18% -10%, var(--page-glow-1), transparent 42%),
    radial-gradient(circle at 100% 0%, var(--page-glow-2), transparent 38%);
  background-attachment: fixed;
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-sans);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  color: var(--accent-strong);
  text-decoration: underline;
}

/* Numbers wear mono + tabular figures — the data-terminal feel. */
.mono,
.stat__value,
.tile__metric,
.data-table td.num,
.data-table th.num,
time {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ----- Layout scaffold (sticky footer via flex, no absolute positioning) ----- */

.page-main {
  flex: 1 0 auto;
  width: 100%;
}

.page-body {
  padding-bottom: var(--space-4);

  /* THE HEIGHT OF THE STICKY HEADER, as a number the page below it can use — for the anchor targets'
     scroll-margin and for /skaiciai's own sticky group bar. It cannot be derived in CSS: <header> is
     the ticker plus the nav row, and the nav's primary link list WRAPS between 720 and 880px (two rows
     at 840–879, three at 720–839), so the stack is 108/112/118/171/148/124 px measured at 375 / 600 /
     700 / 780 / 860 / 1280 on 2026-08-15, signed out. These are the no-scripting fallback and are right
     for that case; site.js replaces them with what the header actually measures, which is what covers a
     signed-in reader (the account name widens the row and moves the wrap). */
  --header-stack: 108px;
}

@media (min-width: 576px) {
  .page-body { --header-stack: 112px; }
}

@media (min-width: 640.02px) {
  .page-body { --header-stack: 118px; }
}

@media (min-width: 720px) {
  .page-body { --header-stack: 171px; }
}

@media (min-width: 840px) {
  .page-body { --header-stack: 148px; }
}

@media (min-width: 880px) {
  .page-body { --header-stack: 124px; }
}

/* A heading a link can land on clears the sticky header instead of scrolling under it. Inert until
   something actually navigates to a fragment, which before the two group rails almost nothing did. */
.section-title[id] {
  scroll-margin-top: calc(var(--header-stack, 124px) + var(--space-3));
}

/* The one page gutter. 1120px is narrower than Bootstrap's old container-xl step (1140px) and applies
   at every breakpoint, so the measure never jumps as the viewport grows. The 0.75rem side padding is
   the gutter the tables, footer and nav all measure themselves against — .table-bleed's 1096px is
   1120 minus these two. */
.container {
  width: 100%;
  max-width: 1120px;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  margin-left: auto;
  margin-right: auto;
}

/* Only genuinely wide screens widen: a laptop at 1280–1439 keeps the 1120px it has today. The grids
   and tables are the reason — offers cards auto-fill, so they gain a column instead of leaving a
   band of dead space on the right. Prose is unaffected because every prose block is capped in ch
   (.legal 70ch, hero copy 60ch), not by the container. */
@media (min-width: 1440px) {
  .container {
    max-width: 1360px;
  }

  /* Prose does not follow the container. At 1360px a page-level sentence runs ~190 characters —
     roughly triple a comfortable measure — so sentences stop at 75ch while the grids and tables
     beside them take the full width. Inert inside tiles and cards, which are far narrower than
     75ch already; .legal sets its own 70ch. */
  .page-body > p,
  .notice,
  .tile__note {
    max-width: 75ch;
  }
}

/* ----- Macro ticker (site-wide strip above the nav) ----- */

/* The ticker and the nav both live in one <header>, so one sticky block carries both: no offset
   arithmetic, and no dependence on the ticker's height staying 2.75rem. Both have been sticky since
   the layout batch that made them so, and they stay that way. What is NOT in here is the data-update
   bar: it sits after </header> in the markup and scrolls away with the page. Its height is therefore
   not part of the sticky element, so nothing changes size at the moment the header detaches — a
   sticky box that loses a child on scroll is exactly the jump this arrangement avoids.
   Above page content and Leaflet's internal panes (which reach ~1000), below the drawer overlay
   (1100) and the drawer (1200) so the menu still covers the bar that opened it. */
header {
  position: sticky;
  top: 0;
  z-index: 1050;
}

/* ----- THE DEEP BAND -----
   The masthead and the home page's brand block are ONE surface in the light theme: a deep green
   rectangle the whole header sits in — ticker, nav row and update strip together, rather than a dark
   nav sandwiched between two cream strips — and the same green under the large wordmark on the home
   page. The reason is the flag. Its yellow measures 1.7:1 on cream and the owner's rule is that the
   flag's colours are never altered to suit a background, so the background is what yields.

   Every control inside inherits its ink from here rather than being restyled one by one: the block
   REDECLARES the palette tokens, so the nav links, the two buttons, the badge, the theme switch, the
   language chip and the ticker all keep the rules they already had and simply resolve them against
   the band. In the dark theme every --band- token is that theme's own value, so nothing there moves.
   Contrast on #163d31: ink 11.03, muted 7.00, faint 5.50, accent 6.73, and the flag's own three at
   6.95 / 3.76 / 3.15 — all three above the 3:1 a bar or a letterform stroke is held to.

   The update bar is listed here even though it is no longer inside <header>: it was taken out of the
   sticky element so it would scroll away, and it has to keep reading as the block that closes the
   masthead rather than as a stray strip in the page. */
header,
.update-bar,
.page-head {
  --ground: var(--band-ground);
  --surface-1: var(--band-surface-1);
  --surface-2: var(--band-surface-1);
  --ink: var(--band-ink);
  --ink-muted: var(--band-ink-muted);
  --ink-faint: var(--band-ink-faint);
  --border: var(--band-border);
  --border-strong: var(--band-border-strong);
  --accent: var(--band-accent);
  --accent-strong: var(--band-accent-strong);
  --accent-dim: var(--band-accent-dim);
  --on-accent: var(--band-on-accent);
  --focus: var(--band-accent);
  --hover-wash: var(--band-hover);
}

header {
  background-color: var(--band-ground);
}

.macro-ticker {
  background-color: var(--surface-1);
  border-bottom: 1px solid var(--border);
  /* Fixed height + hidden overflow: the marquee track is wider than the viewport and must never
     become page-level horizontal scroll. The height is sized to the item font below — a slim strip,
     not a banner — so changing one means changing the other. */
  height: 2.75rem;
  overflow: hidden;
}

.macro-ticker__track {
  display: flex;
  width: max-content;
  height: 100%;
  /* The duration is the time to travel ONE GROUP, so it scales with the group's content: a group is
     4 copies of the item sequence (see the view), and 1228s over the ~22 100 px eighteen items at
     0.95rem measure holds the ~18 px/s reading speed the original five-item strip read at. Change the
     item count or the font size, change this. */
  animation: macro-ticker-scroll 1228s linear infinite;
}

.macro-ticker:hover .macro-ticker__track,
.macro-ticker:focus-within .macro-ticker__track {
  animation-play-state: paused;
}

.macro-ticker__group {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding-right: var(--space-5);
  white-space: nowrap;
}

.macro-ticker__item {
  font-size: 0.95rem;
  color: var(--ink-muted);
}

/* Deliberately NOT smaller than the value: label and value share the item's font size, and the
   hierarchy between them is carried by colour and weight alone. A size step here reads as an
   unbalanced strip rather than as emphasis. */
.macro-ticker__label {
  color: var(--ink-muted);
}

/* The number is what the strip is for: full-contrast ink (14.05 on ground) and heavier than the
   label and period around it, which stay muted. */
.macro-ticker__value {
  font-family: var(--font-mono);
  color: var(--ink);
  font-weight: 600;
}

.macro-ticker__period,
.macro-ticker__source {
  color: var(--ink-faint);
  font-size: 0.8rem;
}

/* Phones read the strip at arm's length off a 375 px viewport: keep the value/label contrast step
   but give the whole strip back a little height. */
@media (max-width: 640px) {
  .macro-ticker {
    height: 2.375rem;
  }

  .macro-ticker__item {
    font-size: 0.85rem;
  }

  .macro-ticker__period,
  .macro-ticker__source {
    font-size: 0.75rem;
  }
}

/* The track holds the group twice, so -50% lands exactly on the second copy's start — the two groups
   are identical and the track has no gap of its own, which is what makes -50% exactly one group wide.
   The strip is then gapless for every offset iff one group is at least as wide as the viewport (the
   view repeats the item sequence enough times to guarantee that). */
@keyframes macro-ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .macro-ticker__track {
    animation: none;
  }

  /* Static strip: the values must stay reachable, so scrolling moves inside the strip only. */
  .macro-ticker {
    overflow-x: auto;
  }
}

/* ----- Top nav ----- */

/* The nav is one row at every width: brand, the four primary links, then the Meniu button and the
   language switch. Everything else lives in the drawer, so the bar no longer wraps or collapses and
   there is no breakpoint machinery left — only the primary links drop out below 720px. */
.site-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0;
  /* Opaque, not the old 92% wash: the bar is sticky now, so page content scrolls under it. */
  background-color: var(--ground);
  border-bottom: 1px solid var(--border);
}

.site-nav > .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}

.site-nav__primary {
  display: flex;
  flex-grow: 1;
  gap: var(--space-2);
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}

@media (max-width: 719.98px) {
  .site-nav__primary {
    display: none;
  }
}

.site-nav__end {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* Still used by the drawer's page list and by the account list in _LoginPartial. */
.site-nav__list {
  display: flex;
  flex-direction: column;
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}

/* Wide-tracked wordmark — replaceable by an image without layout shift (see assets/brand/). */
.brand-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5ch;
  padding-top: 0.3125rem;
  padding-bottom: 0.3125rem;
  margin-right: var(--space-4);
  font-family: var(--font-sans);
  font-weight: 800;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-size: 0.95rem;
  color: var(--ink);
  white-space: nowrap;
}

.brand-wordmark:hover {
  color: var(--ink);
  text-decoration: none;
}

.brand-wordmark .brand-logo {
  display: block;
  height: 24px;
  width: auto;
}

/* THE MARK'S COLOURS. They live here rather than in the SVG because only a stylesheet can answer the
   theme the reader CHOSE rather than the one the operating system prefers; the partial ships outlines
   and nothing else. The three stops are the flag's three bands, cut across the whole word at the same
   two heights, and EVERY letter is cut by them — the i included, which used to wear an accent green of
   its own and read as a letter that had been left out of the mark. Its dot sits above the gradient's
   span, which userSpaceOnUse clamps to the first stop, so it comes out all yellow — the same all-yellow
   dot the app icon carries. The tones no longer differ per theme — the GROUND does: both blocks that
   carry the mark are the deep band (see "header, .page-head" below), so the flag is never altered to
   fit a background. Nothing in the wordmark is carried by colour alone — the letters spell the name
   whether or not any of this resolves, and the SVG's own title says it too. */
.brand-logo__band-yellow {
  stop-color: var(--flag-yellow);
}

.brand-logo__band-green {
  stop-color: var(--flag-green);
}

.brand-logo__band-red {
  stop-color: var(--flag-red);
}

.site-nav .nav-link {
  color: var(--ink-muted);
  font-size: 0.95rem;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
}

.site-nav .nav-link:hover,
.site-nav .nav-link:focus {
  color: var(--ink);
}

.menu-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5ch;
  padding: 0.3rem 0.7rem;
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1;
  color: var(--ink);
  background-color: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
}

.menu-button:hover {
  border-color: var(--accent);
}

/* Count of pages behind the menu, so the button reads as "there is more here" rather than as a
   decoration. Same accent-dim/accent pair the ticker and chips use. aria-hidden in the markup: the
   button already announces "Meniu" and a screen reader gets the real list from the drawer. */
.menu-button__badge {
  display: inline-block;
  min-width: 1.35em;
  padding: 0.05rem 0.3rem;
  border-radius: 999px;
  background-color: var(--accent-dim);
  color: var(--accent);
  font-size: 0.75rem;
  line-height: 1.45;
  text-align: center;
}

/* Small phones cannot afford it. Measured at a 360px viewport: the top bar (logo + account + Meniu
   + LT/EN) already lands within ~1px of the container, and the badge adds 25px to the button, which
   pushed the row 27px past the edge and gave the whole page a horizontal scrollbar. The badge is
   aria-hidden decoration, so dropping it below 576px costs nothing but the hint -- and below 720px
   the bar carries no primary links at all, so Meniu is already visibly the only way in.
   If the badge is ever wanted on phones too, the room has to come from the LT/EN switch or the
   wordmark, not from here. */
@media (max-width: 575.98px) {
  .menu-button__badge {
    display: none;
  }
}

.account-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5ch;
  padding: 0.3rem 0.55rem;
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1;
  background-color: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
}

.account-button:hover {
  border-color: var(--accent);
}

.account-button--out {
  color: var(--ink-muted);
}

.account-button--in {
  color: var(--accent);
  border-color: var(--accent);
  background-color: var(--accent-dim);
}

.account-button__icon {
  position: relative;
  display: inline-flex;
}

.account-button__dot {
  position: absolute;
  top: -3px;
  right: -3px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: var(--accent-strong);
  border: 1px solid var(--ground);
}

.account-button__name {
  color: var(--ink);
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 719.98px) {
  .account-button__name {
    display: none;
  }
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100dvh;
  width: min(320px, 85vw);
  padding: var(--space-5);
  background-color: var(--surface-1);
  border-left: 1px solid var(--border);
  overflow-y: auto;
  z-index: 1200;
  transform: translateX(100%);
  transition: transform 0.25s ease;
}

.drawer.open {
  transform: translateX(0);
}

.drawer__close {
  display: block;
  margin-left: auto;
  padding: 0 0.35rem;
  font-family: inherit;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink-muted);
  background-color: transparent;
  border: 0;
  cursor: pointer;
}

.drawer__close:hover {
  color: var(--ink);
}

.drawer__list {
  margin-top: var(--space-3);
}

.drawer__sep {
  margin: var(--space-4) 0;
  border: 0;
  border-top: 1px solid var(--border);
}

.drawer a,
.drawer .nav-link {
  display: block;
  padding: 0.6rem 0;
  font-size: 1.05rem;
  color: var(--ink);
}

/* A page link in the drawer carries its module's icon in its module's colour. The LABEL keeps the
   ordinary ink: the colour is there to make a long list scannable, not to rank the entries in it. */
.drawer .drawer__link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* A shade larger than the .icon default: the drawer's own type is 1.05rem, and at the shared size the
   glyph read as an afterthought beside it rather than as the entry's mark. Qualified by .drawer
   because the shared .icon rule is declared further down this file and would otherwise win the tie. */
.drawer .drawer__icon {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--tile-accent, var(--ink-muted));
}

.drawer a:hover,
.drawer .nav-link:hover {
  color: var(--accent);
  text-decoration: none;
}

.drawer button.nav-link {
  padding: 0.6rem 0;
  font-family: inherit;
  font-size: 1.05rem;
  color: var(--ink);
  background-color: transparent;
  border: 0;
  cursor: pointer;
}

.drawer button.nav-link:hover {
  color: var(--accent);
}

.drawer-overlay {
  position: fixed;
  inset: 0;
  background-color: var(--overlay);
  opacity: 0;
  transition: opacity 0.25s ease;
  z-index: 1100;
}

.drawer-overlay.open {
  opacity: 1;
}

body.drawer-locked {
  overflow: hidden;
}

/* LT | EN switch */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.lang-switch a {
  color: var(--ink-muted);
  padding: 2px 4px;
  border-radius: 4px;
}

.lang-switch a:hover {
  color: var(--ink);
  text-decoration: none;
}

.lang-switch a.is-active {
  color: var(--on-accent);
  background-color: var(--accent);
}

.lang-switch .sep {
  color: var(--border-strong);
}

/* ----- Theme switch -----
   Sits beside the language switch and reads the same way: a small muted control that says which way
   it will take you. The two marks both ship; the theme in force hides the one that describes it, so
   the button always shows the theme it OFFERS rather than the one already on. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  cursor: pointer;
  line-height: 1;
}

.theme-toggle:hover {
  color: var(--ink);
  border-color: var(--border-strong);
}

.theme-toggle__moon {
  display: none;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .theme-toggle__sun {
    display: none;
  }

  :root:not([data-theme="dark"]) .theme-toggle__moon {
    display: inline-block;
  }
}

:root[data-theme="light"] .theme-toggle__sun {
  display: none;
}

:root[data-theme="light"] .theme-toggle__moon {
  display: inline-block;
}

/* ----- Data-update bar -----
   A thin strip closing the sticky header: what the site does (collects automatically) and what day it
   is saying it. Both are facts — there is no clock and no weather here. */
.update-bar {
  background-color: var(--surface-1);
  border-bottom: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: 0.75rem;
  margin-bottom: var(--space-5);
}

.update-bar > .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 2rem;
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}

/* The dot rides the FIRST LINE of the sentence, not the middle of the block. As a flex row centred on
   its own box it was right at desktop width and wrong the moment the label wrapped: at 375px
   "Duomenys atnaujinami automatiškai" takes two lines, and the dot floated into the gap between them,
   level with neither. Set inline it sits on the middle of the x-height, which is where a bullet
   belongs and is where it stays however many lines the sentence takes. */
.update-bar__live .live-dot {
  display: inline-block;
  vertical-align: middle;
  margin-right: var(--space-2);
}

.update-bar__date {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ----- Tricolour burger -----
   Three bars in the flag's colours. Decoration on a control that already says "Meniu" in words, so
   the colour carries nothing a reader could miss. Thin on purpose: an accent, not a banner.
   The bars need no backing of their own: the header they sit in is the deep band in both themes, and
   the flag's own yellow measures 6.95 on it. It would have measured 1.7 on cream, which is the whole
   reason the band exists. */
.menu-button__icon {
  display: inline-flex;
  flex-direction: column;
  justify-content: space-between;
  width: 1rem;
  height: 0.7rem;
}

.menu-button__icon i {
  display: block;
  height: 2px;
  border-radius: 1px;
  background-color: var(--flag-yellow);
}

.menu-button__icon i:nth-child(2) { background-color: var(--flag-green); }
.menu-button__icon i:nth-child(3) { background-color: var(--flag-red); }

/* The same hairline again, this time closing the running TICKER line inside the sticky header — so the
   flag stays on screen at every scroll position rather than only at the top of the page. Identical
   construction to the drawer's (7px, 2px inset, plaque behind, three equal segments yellow → green →
   red), because two stripes built two ways would drift apart the first time either is touched. It
   lives inside <header>, which is the sticky element, between the ticker and the nav; the update bar
   below the header deliberately is not sticky, and scrolls away. */
.header-stripe {
  display: flex;
  height: 7px;
  padding: 2px;
  background-color: var(--brand-plaque);
}

.header-stripe i {
  flex: 1;
  background-color: var(--flag-yellow);
}

.header-stripe i:nth-child(2) { background-color: var(--flag-green); }
.header-stripe i:nth-child(3) { background-color: var(--flag-red); }

/* The same three colours as a hairline across the top of the opened drawer, and on the same plaque
   for the same reason: the drawer's own surface is cream in the light theme. The 2px inset is what
   makes the backing visible at all — three bars stretched edge to edge would cover it entirely. */
.drawer__stripe {
  display: flex;
  height: 7px;
  padding: 2px;
  background-color: var(--brand-plaque);
  margin: calc(-1 * var(--space-4)) calc(-1 * var(--space-4)) var(--space-4);
}

.drawer__stripe i {
  flex: 1;
  background-color: var(--flag-yellow);
}

.drawer__stripe i:nth-child(2) { background-color: var(--flag-green); }
.drawer__stripe i:nth-child(3) { background-color: var(--flag-red); }

/* Section headers inside the drawer. */
.drawer__group {
  margin: var(--space-4) 0 var(--space-2);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.drawer__group:first-of-type {
  margin-top: var(--space-2);
}

/* ----- Hero / page headings ----- */

.hero {
  margin-bottom: var(--space-6);
}

.hero__title {
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  margin: 0 0 var(--space-2);
}

/* Sized in em so the mark scales with the clamped title above rather than sitting at the 1.2rem an
   .icon is everywhere else, which beside a 2.6rem heading reads as a stray bullet. */
.hero__title .hero__icon {
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.4rem;
  vertical-align: -0.06em;
  color: var(--tile-accent, var(--ink-muted));
}

.hero__strapline {
  color: var(--ink-muted);
  max-width: 60ch;
  margin: 0;
  font-size: 1.05rem;
}

/* The zero above is for the home block, where the grid spaces the line. In a module page's own flow
   the next thing is a bento, a notice or a note, and none of those carries a top margin — the
   strapline ended flush against the box under it on /degalai, /elektra, /bustas, /maistas,
   /aukcionai and /naujienos. */
.page-body > .hero__strapline {
  margin-bottom: var(--space-4);
}

/* The motto. Distinct from the strapline above it by COLOUR and a rule rather than by a new type size:
   full ink against the strapline's muted grey, with an accent bar that reads it as a statement rather
   than a third line of description. */
.hero__motto {
  color: var(--ink);
  max-width: 60ch;
  margin: var(--space-3) 0 0;
  padding-left: var(--space-3);
  border-left: 2px solid var(--accent);
  font-size: 1.05rem;
}

/* Its own line inside the motto block, muted against the motto's full ink — the same colour step
   the strapline takes above it, so the block reads as one claim plus its quieter qualifier. */
.hero__motto-second {
  display: block;
  color: var(--ink-muted);
}

.hero__logo {
  display: block;
  height: 48px;
  width: auto;
}

.hero__install {
  margin: var(--space-4) 0 0;
}

/* ----- Home: the compact heading block -----
   What the hero was, minus the screen height. The mark, the one line saying what the site is, and the
   one claim it makes — then straight into the board. Same tokens and the same colour steps as .hero,
   at the sizes a dashboard can afford to give a masthead. */

/* THE TOP OF THE PAGE, side by side once there is room: what the site is on the left, what it most
   recently gained on the right. One column first, so the phone layout is the one a viewport gets by
   default rather than the one it has to earn, and in that column the introduction comes first in the
   DOM and therefore first on the screen. The lead takes the wider track — it holds sentences, and the
   card holds dated one-liners. */
.home-intro {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

@media (min-width: 900px) {
  .home-intro {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    /* Two shared row tracks: the opener and the changelog fill the first, the notices panel and the
       holiday card sit in the second — so the second row STARTS on one line in both columns instead
       of each column stacking to its own rhythm. Subgrid is what shares the tracks; each column is
       exactly two grid children for exactly this reason (the lead's head + standing notice are one
       wrapper). With no notices the lead simply leaves its second track to the holiday card's height. */
    grid-template-rows: auto auto;
    align-items: start;
  }

  /* Only the track SHARING belongs in the query: both columns are grids with a gap at every width
     (below), and subgrid is the part that has no meaning until there is a second column to line up
     with. */
  .home-intro__lead,
  .home-intro__aside {
    grid-row: span 2;
    grid-template-rows: subgrid;
  }
}

/* The lead is two blocks — the opener and the notices panel — and the rule below zeroes the opener's
   last child's bottom margin, so neither block supplies its own separation. The gap has to come from
   here, at EVERY width: it lived inside the 900px query while the subgrid work was being done, and
   under 900px the feedback notice and the notices panel met edge to edge with nothing between them.
   The same one-column-plus-gap shape the aside just below already uses, for the same reason. */
.home-intro__lead {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
}

.home-intro__lead > :last-child,
.home-intro__opener > :last-child {
  margin-bottom: 0;
}

/* The aside holds two panels now — the changelog and the next holiday — and panels carry no margin of
   their own, so without a gap here they meet edge to edge and read as one card with a rule through it.
   The same track the side column uses, for the same reason. */
.home-intro__aside {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
}

/* The brand block, cut out of the paper as the same deep rectangle the masthead is — see "THE DEEP
   BAND" above for why. The padding is a token because it is nothing at all in the dark theme, where
   the block is bare type on the page's own ground and this change must not move it. The standing
   notice stays OUTSIDE, on the light paper: it is a message about the site, not part of the brand. */
.page-head {
  margin-bottom: var(--space-5);
  padding: var(--band-panel-pad);
  border-radius: var(--radius);
  background-color: var(--band-panel);
}

.page-head__title {
  margin: 0 0 var(--space-2);
  font-size: 1rem;
  line-height: 1;
}

.page-head__title .brand-logo {
  display: block;
  height: 38px;
  width: auto;
}

.page-head__strapline {
  color: var(--ink-muted);
  max-width: 70ch;
  margin: 0;
  font-size: 0.95rem;
}

/* Full ink against the strapline's muted grey, with the accent bar that reads it as a statement
   rather than a third line of description. Both sentences on one line here — the block is compact
   now, and the qualifier is a clause rather than a paragraph. */
.page-head__motto {
  color: var(--ink);
  max-width: 70ch;
  margin: var(--space-2) 0 0;
  padding-left: var(--space-3);
  border-left: 2px solid var(--accent);
  font-size: 0.95rem;
}

.page-head__motto-second {
  color: var(--ink-muted);
}

.page-head__install {
  margin: var(--space-3) 0 0;
}

.section-title {
  font-size: 1.25rem;
  margin: var(--space-6) 0 var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}

.home-tabs {
  display: flex;
  /* Two tabs fit any phone; five do not — /migracija's strip wants 432 px of the 345 available at
     375 px, and without this the row silently squeezes its labels instead of taking a second line. */
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-6) 0 var(--space-3);
  border-bottom: 1px solid var(--border);
}

.home-tab {
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--ink-muted);
  font-family: inherit;
  font-size: 1.05rem;
  padding: 0.4rem 0.75rem;
  cursor: pointer;
}

.home-tab:hover {
  color: var(--ink);
}

.home-tab[aria-selected="true"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ----- Counter strip (small mono stats) ----- */

.stat-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  padding: var(--space-3) 0;
  margin-bottom: var(--space-5);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.stat__value {
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--ink);
}

.stat__label {
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ----- Icons -----
   One inline <symbol> set per document (Pages/Shared/_IconSprite.cshtml, Tabler Icons, MIT), used as
   <svg class="icon"><use href="#i-fuel" /></svg>. The sprite itself never renders. */

.icon-sprite {
  display: none;
}

.icon {
  width: 1.2rem;
  height: 1.2rem;
  flex: none;
  vertical-align: -0.18em;
}

/* ----- Per-module accents -----
   One colour per module, set as --tile-accent on whatever carries the module's mark: a home tile's top
   rule and its icon, and the drawer entry's icon. Dark-only site (there is no light theme and no
   prefers-color-scheme switch anywhere in this file), so one value per module is the whole story.

   The accent is NEVER the only carrier of meaning. Every place one appears, the module's name is
   written beside it and its icon is drawn in it, so the colour is recognition, not information —
   which is what lets neighbouring modules share a family of hues without any of them having to be
   distinguishable by a reader who cannot tell them apart. The one rule the palette does keep is that
   no two ADJACENT drawer entries carry near-identical hues, because that is where they are read as a
   list rather than one at a time.

   Deliberately NOT applied to a tile's number: the big figure keeps the neutral ink (and the green
   "this is the cheapest" highlight) it has everywhere else on the site, so a colour can never be
   mistaken for a judgement about the value. */

.accent-home { --tile-accent: var(--mod-home); }
.accent-fuel { --tile-accent: var(--mod-fuel); }
.accent-electricity { --tile-accent: var(--mod-electricity); }
.accent-weather { --tile-accent: var(--mod-weather); }
.accent-heating { --tile-accent: var(--mod-heating); }
.accent-food { --tile-accent: var(--mod-food); }
.accent-offers { --tile-accent: var(--mod-offers); }
.accent-housing { --tile-accent: var(--mod-housing); }
.accent-taxes { --tile-accent: var(--mod-taxes); }
.accent-news { --tile-accent: var(--mod-news); }
.accent-markets { --tile-accent: var(--mod-markets); }
.accent-cases { --tile-accent: var(--mod-cases); }
.accent-initiatives { --tile-accent: var(--mod-initiatives); }

/* /iniciatyvos: signatures collected as a share of required — a plain quotient, no animation. */
.init-progress {
  height: 8px;
  margin: 0.5rem 0;
  border-radius: 4px;
  background: var(--surface-3);
  overflow: hidden;
}

.tile__subject {
  margin: 0.35rem 0 0.5rem;
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.35;
}

.init-progress__fill {
  height: 100%;
  border-radius: 4px;
  background: var(--mod-initiatives);
}
.accent-migration { --tile-accent: var(--mod-migration); }
.accent-forests { --tile-accent: var(--mod-forests); }
.accent-cars { --tile-accent: var(--mod-cars); }
.accent-auctions { --tile-accent: var(--mod-auctions); }
.accent-funding { --tile-accent: var(--mod-funding); }
.accent-assistance { --tile-accent: var(--mod-assistance); }
.accent-map { --tile-accent: var(--mod-map); }
.accent-numbers { --tile-accent: var(--mod-numbers); }
.accent-privacy { --tile-accent: var(--mod-privacy); }

/* /pagalba stacks its programme cards one per row rather than in the bento's columns: each card
   carries a paragraph of statutory conditions, and a 260px column would set that prose four words
   wide. A grid only for its gap — .panel itself has no margin, so consecutive panels would touch. */
.assistance-list {
  display: grid;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

/* ----- /pagalba: a programme card is a native <details> -----
   The page carries fourteen programmes, each with a paragraph of statutory conditions, a table of
   amounts and a list of traps — around 17 700 px of document, which is the owner's „reikia daug
   scrolinti". Collapsed, the same page is a list of names and amounts a reader can read in one screen
   and open the one they came for. Nothing is hidden behind scripting: <details> opens on click, on
   Enter, on Space and under the browser's own find-in-page, with or without site.js. */

.assistance-card {
  /* .panel is a flex column with padding; here the summary owns the padding so its hover wash and its
     tap target reach the card's own edges. Overflow clips that wash to the rounded corners. */
  display: block;
  padding: 0;
  overflow: hidden;
  scroll-margin-top: calc(var(--header-stack, 124px) + var(--space-3));
}

.assistance-card__summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  /* 2.75rem before padding is counted: a touch target, not a line of text. */
  min-height: 2.75rem;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  /* The default triangle differs between engines and cannot be coloured per theme; the chevron below
     is drawn from currentColor and follows both. */
  list-style: none;
}

.assistance-card__summary::-webkit-details-marker {
  display: none;
}

.assistance-card__summary:hover {
  background-color: var(--hover-wash);
}

/* Inset, because the card clips its own overflow — an outline at a positive offset would be cut off
   along the top edge, which is exactly the edge a keyboard reader is looking at. */
.assistance-card__summary:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.assistance-card__name {
  flex: 1 1 auto;
  min-width: 0;
  /* The name and its one amount are one heading: a summary may hold either phrasing content or a
     single heading element, not a heading and a sibling span, and keeping the h3 is what keeps the
     programme reachable by "next heading" while the card is shut. */
  line-height: 1.35;
}

/* Muted and never bold: the name is what is being scanned and the figure is what confirms it. Measured
   on the card's surface at 5.58:1 in the light theme and 7.12:1 in the dark one. */
.assistance-card__amount {
  font-weight: 400;
  color: var(--ink-muted);
  white-space: nowrap;
}

/* The same muted second half of a summary, for the cards whose second half is a PHRASE rather than a
   figure (/pranesimai/logines-klaidos states each fallacy's gist there). Everything but the wrapping:
   nowrap keeps a "129,50 €" whole, and would push a clause off the right edge of a phone. */
.assistance-card__gist {
  font-weight: 400;
  color: var(--ink-muted);
}

.assistance-card__summary::after {
  content: "";
  flex: none;
  width: 0.45rem;
  height: 0.45rem;
  margin-left: auto;
  color: var(--ink-faint);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-0.15rem) rotate(45deg);
  transition: transform 0.15s ease;
}

.assistance-card[open] > .assistance-card__summary::after {
  transform: translateY(0.1rem) rotate(-135deg);
}

/* Open, the summary becomes the card's head — the same hairline .panel__head draws. */
.assistance-card[open] > .assistance-card__summary {
  border-bottom: 1px solid var(--border);
}

.assistance-card > .legal {
  padding: var(--space-3) var(--space-4) var(--space-4);
}

@media (prefers-reduced-motion: reduce) {
  .assistance-card__summary::after {
    transition: none;
  }
}

/* ----- Bento grid of data tiles ----- */

.bento {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  /* /skaiciai draws the home strip's own cards in this grid, and three of them span two columns
     (see .number-card--wide) — a spanning card that does not fit the columns left over leaves a hole
     and the section ends ragged. Dense lets a later one-column card back-fill it. A no-op in every
     other bento on the site: nothing in them spans, and dense reorders nothing when all items are
     one cell wide. */
  grid-auto-flow: dense;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  box-shadow: var(--shadow);
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

/* The module's own colour along the top edge, thicker than the rest of the border so it reads as a
   rule rather than as an uneven frame. Falls back to the ordinary border for a tile with no accent. */
.tile {
  border-top-width: 2px;
  border-top-color: var(--tile-accent, var(--border));
}

a.tile:hover {
  border-color: var(--accent);
  color: inherit;
  text-decoration: none;
  transform: translateY(-2px);
}

/* The whole tile is the link, so the whole tile has to show focus — the "Atidaryti →" line inside it
   is a span and never takes the ring on its own. */
a.tile:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Hovering an accented tile must not throw away the module's mark, so only the three other sides
   follow the green hover; the top rule stays the module's own colour. */
a.tile:hover {
  border-top-color: var(--tile-accent, var(--accent));
}

.tile__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

/* Carried on the class rather than inherited from the tag, because a card title is not always a
   heading: the home tiles are <p> (their whole card is one link, and an h3 after the h1 that the tab
   enhancement hides is a heading-order violation to axe), while /parama/projektai uses h2 and /parama
   h3. line-height and letter-spacing are the two the grouped h1–h5 rule used to supply, so without
   them here a <p> title would render at the body's 1.55 and no tracking. */
.tile__title {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
}

.panel__icon {
  color: var(--tile-accent, var(--ink-muted));
}

.tile__metric {
  font-size: 1.7rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.1;
}

.tile__metric .unit {
  font-size: 0.85rem;
  color: var(--ink-muted);
  font-family: var(--font-sans);
}

.tile__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: 0.9rem;
}

.tile__row .k {
  color: var(--ink-muted);
}

.tile__row .city {
  color: var(--ink);
  font-family: var(--font-sans);
}

.tile__row .v {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  /* Most values here are prices, which never need breaking — but /parama/projektai puts a
     beneficiary's registered name in this slot, and one 277px unbroken Austrian institute name
     pushed the whole DOCUMENT sideways at 360px. A flex item will not shrink below its longest
     word unless the word is allowed to break. */
  min-width: 0;
  overflow-wrap: anywhere;
}

.tile__note {
  font-size: 0.85rem;
  color: var(--ink-muted);
  margin: 0;
}

/* The class started life inside a tile, where the flex gap spaces it and the zero above is right. It
   is now also the site's page-level small print — the caveats under a figure, the "what this counts"
   line before a table — and there NOTHING spaced it: five notes on /degalai rendered as one grey
   slab at 0px apart, and the last of them ended flush against the panel below. Restored to the
   paragraph rhythm the prose pages already read at, in the page's own flow only, so no tile or panel
   gains a margin on top of the gap it already has. */
.page-body > .tile__note {
  margin: var(--space-3) 0;
}

.tile__headline {
  font-size: 0.92rem;
  color: var(--ink);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.tile__cta {
  margin-top: auto;
  font-size: 0.85rem;
  color: var(--accent);
  font-weight: 600;
}

.tile__value--good {
  color: var(--accent-strong);
}

/* The line that replaced the always-on "VEIKIA" badge: when a module was last heard from, said once,
   quietly, at the foot of the panel. A badge on every panel said the same thing nine times and so said
   nothing; this says something different on each one. Faint, but --ink-faint clears 4.33:1 on the
   ground, so it is still readable rather than merely present. */
.panel__fresh {
  margin-top: auto;
  padding-top: var(--space-1);
  font-size: 0.75rem;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* The trend line under a price tile's figures. Full width, no axes and no labels: the tile already
   states the latest value and its date in words, and this only says which way it has been going. */
.sparkline {
  margin-top: 0.15rem;
  color: var(--tile-accent, var(--ink-muted));
  opacity: 0.85;
}

.tile--soon {
  background-color: transparent;
  border-style: dashed;
  box-shadow: none;
}

.tile--soon .tile__title,
.tile--soon .tile__note {
  color: var(--ink-faint);
}

/* ----- "Kas naujo": the site's own changelog, a panel in the side column ----- */

.home-news__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.home-news__item {
  font-size: 0.9rem;
}

/* WCAG 1.4.1, flagged by Lighthouse: these links sit INSIDE a sentence, so the accent colour is the
   only thing marking them — and colour alone is not a distinction. The site's base `a` underlines on
   hover, which is a pointer affordance and reaches nobody who is simply reading. Underlined at rest
   here, at the same offset .source-link uses, so the two in-text link idioms sit at one height. */
.home-news__item a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* The disclosure holding entries four and beyond. Its own list keeps the gap the visible one has. */
.home-news__more {
  margin-top: var(--space-2);
}

.home-news__more > summary {
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--accent);
}

.home-news__more > summary:hover {
  color: var(--accent-strong);
}

.home-news__more > .home-news__list {
  margin-top: var(--space-2);
}

/* Faint and tabular so the dates line up down the left and the sentences stay the loud part. */
.home-news__date {
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  margin-right: 0.5rem;
}

/* ----- "Svarbūs pranešimai": announcements under the intro, normally absent entirely ----- */

/* The one panel on the page that is allowed to interrupt: amber is the site's own "this matters now"
   colour (act-soon, priciest), and the same weight-not-alarm recipe the emphasized cards use — a
   stronger border and the tile elevation, NO background wash, because a wash under --ink-faint (the
   dates in this very panel) fails AA in the dark theme. The icon takes the amber so the mark and the
   border read as one signal. */
/* Doubled class because .panel declares its border later in this file and would win the tie —
   the panel chrome stays, only the border's colour and weight are overruled. */
.panel.home-notices {
  border-color: var(--amber-rule);
  border-width: 2px;
  box-shadow: var(--shadow);
}

.home-notices .panel__icon {
  color: var(--amber);
}

.home-notices__item + .home-notices__item {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}

/* Same faint tabular date as the changelog's: the two lists sit in the same eyeline. */
.home-notices__date {
  display: block;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
}

.home-notices__body {
  margin: var(--space-1) 0 0;
  font-size: 0.9rem;
}

/* The acts, on their own row and wrapping rather than pushing the column wide — a notice may rest on
   more than one, and the column is the narrow side of the intro on a phone. */
.home-notices__acts {
  margin: var(--space-2) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: 0.9rem;
}

/* ----- Home: the category rail -----
   One stop per module. On a phone it scrolls sideways INSIDE itself rather than wrapping into three
   rows of chips or pushing the document wide — the overflow is on the list, never on the page. */

.category-rail {
  margin-bottom: var(--space-5);
}

.category-rail__list {
  display: flex;
  gap: var(--space-2);
  /* The 4px inset is the focus ring's room. "overflow-x: auto" makes this a scroll container in BOTH
     axes, and a scroll container clips at its padding box — with no top padding the ring's 2px
     outline at 2px offset was cut off above every chip, and the first chip's leading edge with it.
     The negative margin puts the rail back where it was drawn. */
  margin: 0 -4px;
  padding: 4px 4px var(--space-2);
  list-style: none;
  overflow-x: auto;
  scrollbar-width: thin;
  /* Each link stops at the rail's left edge rather than half under it. */
  scroll-snap-type: x proximity;
}

.category-rail__item {
  flex: none;
  scroll-snap-align: start;
}

/* GHOST CHIPS. Navigation has to read as lighter than the board it sits above, or the two blocks
   compete and neither is read first — so a chip at rest is a label and a mark and nothing else, and
   the surface and the outline appear only under a pointer. The 1px transparent border is not
   decoration: it holds the chip's width so nothing shifts sideways when one is hovered. */
.category-rail__link {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem var(--space-2);
  border: 1px solid transparent;
  border-radius: 999px;
  background-color: transparent;
  color: var(--ink-muted);
  font-size: 0.8rem;
  white-space: nowrap;
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.category-rail__link:hover {
  border-color: var(--border);
  background-color: var(--hover-wash);
  color: var(--ink);
  text-decoration: none;
}

.category-rail__link:focus-visible {
  background-color: var(--hover-wash);
  color: var(--ink);
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Decoration: the label beside it is what is read out, so the colour carries recognition only. */
.category-rail__icon {
  width: 1rem;
  height: 1rem;
  color: var(--tile-accent, var(--ink-muted));
}

/* ----- Home: the two-column content grid -----
   Modules a reader reads in the main column, things they act on in the side one. One column below
   900px, where two would leave both too narrow to hold a price row. */

.content-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

@media (min-width: 900px) {
  .content-grid {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: start;
  }
}

.content-grid__main,
.content-grid__side {
  display: grid;
  gap: var(--space-4);
  /* minmax(0,…) rather than auto: without it a long headline sets the column's floor and the grid
     grows past its track, which is where a horizontal document scrollbar comes from. */
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 1200px) {
  .content-grid__main {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ----- Home: a data panel -----
   The tile's surface, without the tile's "the whole card is one link": a panel holds real links now
   (its action, and the news rows), and a link inside a link is invalid HTML. */

.panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-top-width: 2px;
  border-top-color: var(--tile-accent, var(--border));
  border-radius: var(--radius);
  padding: var(--space-4);
  box-shadow: var(--shadow);
  min-width: 0;
}

.panel__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}

.panel__titles {
  flex: 1 1 auto;
  min-width: 0;
}

.panel__title {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0;
}

.panel__subtitle {
  margin: 0.15rem 0 0;
  font-size: 0.8rem;
  color: var(--ink-muted);
}

/* margin-left rather than only the titles' flex-grow: when the head wraps on a phone the action drops
   to a row of its own, and without this it would land under the icon instead of on the right edge. */
.panel__action {
  flex: none;
  margin-left: auto;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
  white-space: nowrap;
}

.panel__action:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* The module pages stack panels straight in the page's own flow, where the home page's grid gap does
   not exist — without this the borders of two consecutive panels touch. Scoped to a flow child so a
   panel inside either home grid keeps taking its spacing from the gap and nothing else. */
.page-body > .panel {
  margin-bottom: var(--space-5);
}

/* Same join from the other side. The rule above gives a panel a bottom margin and no top one, so a
   panel opening under a line of page text sat on it: the notes above "Miestai" on /degalai and the
   staples panel on /akcijos both started at 0px. The note's own paragraph margin would space it, but
   a bordered panel is a section break rather than the next paragraph, so this join takes the same
   distance two panels keep from each other. */
.page-body > .tile__note + .panel {
  margin-top: var(--space-5);
}

/* /parama/projektai renders its result cards as bare flow children — no grid, no list — so the cards'
   own borders touched. The panels' rule one step up, at the tile's smaller scale. */
.page-body > .tile {
  margin-bottom: var(--space-4);
}

/* A panel title that IS a link: the offers digest's per-type sections have always rendered their
   heading as plain ink rather than accent-and-underline (it is the section's name, not a call to
   action), and moving them into a panel head must not change that. */
.panel__title a {
  color: var(--ink);
  text-decoration: none;
}

.panel__title a:hover {
  color: var(--accent-strong);
}

/* A table inside a panel stops at the panel's inner edge. .table-bleed's negative margin is measured
   against its containing block, so left alone a bled table draws across the panel's own border and
   shadow on wide viewports; the table still scrolls inside .table-wrap when it needs more room. */
.panel .table-bleed {
  margin-inline: 0;
}

/* ----- Home: the newest stories, as rows in the side column ----- */

.news-rows__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.news-rows__item + .news-rows__item {
  border-top: 1px solid var(--border);
}

.news-rows__link {
  display: block;
  padding: var(--space-2) 0;
  color: var(--ink);
}

.news-rows__link:hover {
  color: var(--ink);
  text-decoration: none;
}

.news-rows__link:hover .news-rows__headline {
  text-decoration: underline;
}

.news-rows__link:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.news-rows__date {
  display: block;
  font-size: 0.75rem;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.news-rows__headline {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.88rem;
}

/* Phones. Nothing here goes below 0.75rem — the floor the whole stylesheet is held to — and nothing
   is allowed to set a width the viewport cannot hold: the rail scrolls inside itself, the content
   grid is one column, and every panel's contents are free to shrink (min-width: 0) rather than
   propping the grid open. The document itself never gains a horizontal scrollbar. */
@media (max-width: 719.98px) {
  .page-head__title .brand-logo {
    height: 32px;
  }

  .panel {
    padding: var(--space-3);
  }

  .panel__head {
    flex-wrap: wrap;
  }
}

/* ----- /skaiciai: the group bar that stays with the reader -----
   The index is three sections of number-cards in one long column, and the headings that name them are
   off the screen within a scroll of arriving. The bar is the home rail's chips in a sticky strip: plain
   anchors, so the map and the jump both work with no scripting, and an opaque ground so the cards that
   pass under it stay unreadable rather than half-readable. Below the site header, never over it —
   --header-stack is the height the header actually has (see .page-body). */

.numbers-nav {
  position: sticky;
  top: var(--header-stack, 124px);
  z-index: 900;
  /* The gutter's worth of bleed on both sides, so a card scrolling under the bar disappears at the
     page's edge rather than at the container's. */
  margin: 0 calc(-1 * var(--space-3)) var(--space-4);
  padding: 0 var(--space-3);
  background-color: var(--ground);
  border-bottom: 1px solid var(--border);
}

/* The rail's own scroll container, minus the bottom padding it uses when it sits in page flow. */
.numbers-nav__list {
  margin-bottom: 0;
  padding-bottom: 4px;
}

/* A heading the bar itself would cover: the anchor has to clear the header AND the bar. */
.numbers-nav ~ .section-title[id] {
  scroll-margin-top: calc(var(--header-stack, 124px) + 3.5rem);
}

/* ----- "Lithuania in numbers": one card per indicator, denser than a module tile ----- */

.numbers-grid {
  display: grid;
  /* Narrower than .bento's 260px: these are stat cards, not module tiles, so more fit per row and the
     section reads as one block. At 375px the minimum still exceeds the column, which collapses it to a
     single clean stack rather than a squeezed two-up. */
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  /* The three two-column cards (see .number-card--wide) cannot start mid-row, so each one that does not
     fit the columns left over leaves a hole and the section ends ragged. Dense lets a later one-column
     card back-fill that hole, which reorders cards visually against the DOM — acceptable here because
     the cards are peers with no reading order between them. A no-op below 700px, where nothing spans. */
  grid-auto-flow: dense;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.number-card {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
}

/* Same rule a home tile carries, for the same reason: a card that stands for a MODULE rather than for
   one indicator wears that module's colour along its top edge. The 28 indicator cards set no
   --tile-accent and so fall back to the ordinary border and look exactly as they did. */
.number-card {
  border-top-width: 2px;
  border-top-color: var(--tile-accent, var(--border));
}

/* Smaller than the 1.2rem an .icon is elsewhere: it sits inside a 0.78rem uppercase label, not beside
   a tile heading. Decorative — the module's name is written next to it. */
.number-card__icon {
  width: 0.95rem;
  height: 0.95rem;
  margin-right: 0.3rem;
  color: var(--tile-accent, var(--ink-muted));
}

.number-card__label {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.number-card__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.25;
  /* Poverty carries two numbers and the wage labels are long: wrap rather than overflow the card. */
  overflow-wrap: anywhere;
}

.number-card__period,
.number-card__source {
  font-size: 0.75rem;
  color: var(--ink-faint);
}

.number-card__source {
  margin-top: auto;
  padding-top: var(--space-2);
}

.number-card__change {
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}

/* Cards that carry two numbers prefix each line with which number it is about. */
.number-card__change-of {
  color: var(--ink-faint);
}

.number-card__secondary {
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}

/* A fertility rate means nothing without the level it is read against, so the benchmark is part of
   the card rather than a footnote. */
.number-card__benchmark {
  font-size: 0.78rem;
  color: var(--ink-faint);
}

/* The one card that carries a paragraph. It is all sourced numbers, so it reads at body contrast
   rather than as a footnote — but it is prose, so it wraps and breathes. */
.number-card__consequence {
  margin: var(--space-2) 0 0;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--ink-muted);
}

/* Only where there IS a second column to take: below this the grid is a single stack and a span would
   invent an implicit column to overflow into. */
@media (min-width: 700px) {
  .number-card--wide {
    grid-column: span 2;
  }
}

/* The four cards the grid is read from — see MacroPresentation.Emphasized. Weight, not alarm: the
   accent outline the site already uses for "this is the one" (chips, pager, source rows), the
   elevation a .tile carries, and a figure a step larger. Composes with --wide; both may be on one card.
   NO background wash, and that is a contrast decision rather than a taste one: --accent-dim over
   --surface-1 takes --ink-faint — the period and the source line, which are the card's dates — to
   3.9:1 in the dark theme, under the 4.5 this stylesheet holds every light token to. The border and
   the shadow buy the same separation and touch nothing that is read. */
.number-card--focus {
  border-color: var(--accent-line-strong);
  border-width: 2px;
  box-shadow: var(--shadow);
}

.number-card--focus .number-card__value {
  font-size: 1.45rem;
}

/* The arrow already carries the direction; the colour carries whether that direction is welcome for
   THIS indicator (see MacroPresentation.RiseIsWorse) — the same accent-good / amber-worse pair the
   rest of the site uses for cheapest-price and act-soon. */
.number-card__change--better {
  color: var(--accent-strong);
}

.number-card__change--worse {
  color: var(--amber);
}

.number-card__change--flat {
  color: var(--ink-faint);
}

/* Teaser tiles for the gated modules say what they are without pretending to be reachable. */
.tile__note--faint {
  color: var(--ink-faint);
}

/* ----- Tags / badges ----- */

.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.2em 0.55em;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  color: var(--ink-muted);
  white-space: nowrap;
}

.tag--live {
  color: var(--accent-strong);
  border-color: var(--accent-line);
  background-color: var(--accent-dim);
}

.tag--soon {
  color: var(--ink-faint);
}

/* The only badge a home tile still carries, and it is a warning: this module's newest data is older
   than that module is ever normally allowed to get, so the pipeline behind it has stopped. Amber
   rather than danger red — the figures on the tile are still true, they are simply old. */
.tag--stale {
  color: var(--amber);
  border-color: var(--amber-line);
}

.tag--platform {
  color: var(--ink-muted);
  border-color: var(--border-strong);
}

/* Green live dot */
.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-pulse);
  animation: live-pulse 2.4s ease-out infinite;
  flex: none;
}

@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 var(--accent-pulse); }
  70% { box-shadow: 0 0 0 7px var(--accent-pulse-out); }
  100% { box-shadow: 0 0 0 0 var(--accent-pulse-out); }
}

/* ----- Data tables ----- */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
}

/* Wide tables break out of the 1120px .container so every column fits (e.g. the auction date on
   /auctions). The negative margin is clamped at 0, so a table is never narrower than the column it
   broke out of — which also makes the bleed inert below ~1200px viewports (phones included).
   50vw counts the scrollbar, so each edge lands up to half a scrollbar INSIDE the 40px gutter,
   never outside it: the page itself can never gain a horizontal scrollbar from this. */
.table-bleed {
  display: flex;
  justify-content: center;
  margin-inline: min(0px, calc(50% - 50vw + 40px));
  margin-bottom: var(--space-4);
}

/* The bordered wrapper shrink-wraps its table and stays centred, so only genuinely wide tables
   expand. 1096px = .container's 1120px max-width minus its 12px gutters: tables that already fit
   keep exactly the width they have today. */
.table-bleed > * {
  flex: 0 1 auto;
  min-width: min(100%, 1096px);
  max-width: 100%;
  margin-bottom: 0;
}

/* The floor follows the container on wide screens: 1336px = the 1360px container minus its 12px
   gutters, the same relationship 1096px has to 1120px. Must sit AFTER the rule above — same
   specificity, so source order decides. */
@media (min-width: 1440px) {
  .table-bleed > * {
    min-width: min(100%, 1336px);
  }
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  color: var(--ink);
  background-color: var(--surface-1);
}

.data-table th,
.data-table td {
  padding: var(--space-2) var(--space-4);
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.data-table thead th {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-weight: 600;
  background-color: var(--surface-2);
}

.data-table th.num,
.data-table td.num {
  text-align: right;
}

.data-table tbody tr:last-child td {
  border-bottom: none;
}

.data-table tbody tr:hover td {
  background-color: var(--surface-2);
}

.price-best {
  color: var(--accent-strong);
  font-weight: 600;
}

/* Pill next to the cheapest price in each fuel column; .tag's treatment at table scale. */
.badge-cheapest {
  display: inline-block;
  margin-left: 0.4em;
  padding: 0.1em 0.45em;
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  background-color: var(--accent-dim);
  color: var(--accent-strong);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
}

/* Sortable headers: the class is added by fuel-sort.js, so no affordance shows without JS. */
.data-table th.sortable {
  cursor: pointer;
  user-select: none;
}

.data-table th.sortable::after {
  content: "↕";
  margin-left: 0.4em;
  color: var(--ink-faint);
}

.data-table th.sortable[aria-sort="ascending"]::after {
  content: "↑";
  color: var(--accent-strong);
}

.data-table th.sortable[aria-sort="descending"]::after {
  content: "↓";
  color: var(--accent-strong);
}

.data-table th.sortable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.price-high {
  color: var(--amber);
}

.muted-inline {
  color: var(--ink-muted);
}

.data-table tr.data-table__total td {
  font-weight: 700;
  border-top: 2px solid var(--border);
  background-color: var(--surface-2);
}

/* Taxes: NPD is shown, not subtracted, so its row must not read like the withheld ones above it. */
.data-table tr.taxes-row--info td {
  color: var(--ink-muted);
  font-style: italic;
}

.taxes-check {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.9rem;
}

/* ----- Food basket comparison bars ----- */

.food-bars {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.food-bar {
  display: grid;
  grid-template-columns: 5.5rem 1fr auto;
  align-items: center;
  gap: var(--space-3);
}

.food-bar__label {
  font-weight: 600;
  color: var(--ink);
}

.food-bar__track {
  position: relative;
  height: 1.35rem;
  background-color: var(--surface-2);
  border-radius: var(--radius);
  overflow: hidden;
}

.food-bar__fill {
  display: block;
  height: 100%;
  background-color: var(--steel);
  border-radius: var(--radius);
  min-width: 2px;
}

.food-bar--best .food-bar__fill {
  background-color: var(--accent-strong);
}

.food-bar--best .food-bar__label {
  color: var(--accent-strong);
}

.food-bar__value {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 480px) {
  .food-bar {
    grid-template-columns: 4.5rem 1fr;
    grid-template-areas: "label value" "track track";
    row-gap: 2px;
  }
  .food-bar__label { grid-area: label; }
  .food-bar__value { grid-area: value; }
  .food-bar__track { grid-area: track; }
}

/* ----- Segmented control ----- */

/* One choice out of a few, as connected pills. The inputs underneath are ordinary radios — the arrow
   keys, the label association and the single-choice announcement are all still the browser's, and the
   only thing this stylesheet does is paint the label the checked one sits behind. */
.segmented {
  display: inline-flex;
  align-items: stretch;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background-color: var(--surface-2);
}

.segmented__option {
  position: relative;
  display: inline-flex;
}

/* Invisible, NOT removed: display:none or visibility:hidden would take the radio out of the tab order
   and the arrow-key group with it. It keeps its place, receives focus, and hands its focus ring to the
   label beside it through :focus-visible below. */
.segmented__option input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.segmented__label {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.85rem;
  border-radius: 999px;
  font-size: 0.85rem;
  color: var(--ink-muted);
  white-space: nowrap;
  cursor: pointer;
}

.segmented__label:hover {
  color: var(--ink);
}

/* The site's button pair, unchanged: --on-accent on --accent is what .btn-accent already ships in both
   themes, so the active segment inherits a contrast that is already carried. */
.segmented__option input:checked + .segmented__label {
  background-color: var(--accent);
  color: var(--on-accent);
}

.segmented__option input:focus-visible + .segmented__label {
  outline: 2px solid var(--accent-line-strong);
  outline-offset: 2px;
}

/* ----- News filters ----- */

/* One quiet toolbar rather than four scattered fields: the same surface, border and radius the page's
   cards use, so the bar reads as a single control group sitting above the feed. */
.news-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-3) 0 var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background-color: var(--surface-1);
}

.news-filter__field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.news-filter__group {
  border: 0;
  margin: 0;
  padding: 0;
}

/* A legend carries a browser default padding a plain label does not; zeroing it lines this caption up
   with the labels beside it. */
.news-filter__group legend {
  padding: 0;
  margin-bottom: 0.25rem;
}

/* One height for every control in the bar. A select, a date field and a pill row are sized by three
   different UA rules and came out 36, 39 and 37 px apart on their own; 2.5rem is above all three, so
   they line up by growing into it rather than by being clipped into it. */
.news-filter .news-filter__input,
.news-filter .segmented,
.news-filter .btn-accent {
  min-height: 2.5rem;
}

/* The date control is a fixed-width field; 14rem of minimum (what a search box needs) would leave it
   two thirds empty and push the button onto its own line. */
.news-filter__input[type="date"] {
  min-width: 10rem;
}

.news-filter__clear {
  color: var(--ink-muted);
  font-size: 0.9rem;
}

/* ----- News lead ----- */

/* The newest entry, and only that. It is bigger because it arrived last, not because anything ranked
   it: this feed is chronological end to end and there is no "top story" here to render. */
.news-lead {
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* THE PHONE RULE: stacked and full-width by default — the picture is the width of the card and the
   text sits under it. The side-by-side form is opened by a min-width query below, so the narrow layout
   is the one a viewport gets rather than the one it has to earn. */
.news-lead__image {
  width: 100%;
  height: 180px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
}

.news-lead__body {
  min-width: 0;
}

/* One step up from .news-item__title's 1.05rem and no further: the page's h1 is 2rem, and a lead
   reaching for that would read as a second page title. */
.news-lead__title {
  font-size: 1.35rem;
  line-height: 1.3;
  margin: 0 0 var(--space-2);
}

@media (min-width: 720px) {
  .news-lead {
    flex-direction: row;
    align-items: flex-start;
  }

  /* Twice the list thumbnail's 72px box, in 3:2 — the same picture the list shows small, shown large. */
  .news-lead__image {
    flex: none;
    width: 216px;
    height: 144px;
  }

  .news-lead__body {
    flex: 1;
  }
}

/* ----- News list ----- */

.news-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* The day separator: a dated rule between sections of the list, in the section-title rhythm but two
   sizes down and muted. It orders the feed; it must not compete with the stories under it. It is not a
   heading — the story titles are the page's h2s and a date above them would outrank them. */
.news-day {
  margin: var(--space-3) 0 0;
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
  color: var(--ink-muted);
}

.news-day:first-child {
  margin-top: 0;
}

.news-item {
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

/* min-width:0 so a long unbroken URL in the summary cannot push the row wider than its container. */
.news-item__body {
  flex: 1;
  min-width: 0;
}

/* Headline thumbnail. The bytes come from the outlet's own server (hotlinked, never stored here), so
   the aspect ratios are whatever each outlet publishes: a fixed box plus cover keeps rows the same
   height. No empty variant — a story without a picture simply has no box. */
.news-thumb {
  flex: none;
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
}

/* The story's opening line, and the page's h2. Sized down hard from the global heading scale, which
   starts at 2rem for page and section titles and would shout across fifty feed rows. */
.news-item__title {
  font-size: 1.05rem;
  line-height: 1.35;
  margin: 0 0 var(--space-2);
}

/* The primary action of the whole page: the title IS the way out to the outlet. Ink rather than accent,
   like the home page's story rows — a list where every headline is green reads as a list of links
   rather than a list of stories — with the underline arriving on hover. */
.news-item__link {
  color: var(--ink);
}

.news-item__link:hover,
.news-item__link:focus-visible {
  color: var(--accent-strong);
  text-decoration: underline;
}

.news-item__summary {
  margin: 0 0 var(--space-3);
  color: var(--ink);
  white-space: pre-line;
}

.news-item__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.82rem;
  color: var(--ink-muted);
}

/* ----- City link grid ----- */

.city-grid {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-4);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: var(--space-2);
}

.city-grid a {
  display: block;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background-color: var(--surface-1);
  color: var(--ink);
}

.city-grid a:hover {
  border-color: var(--accent);
  color: var(--accent-strong);
  text-decoration: none;
}

/* ----- Charts ----- */

.chart-frame {
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  overflow-x: auto;
}

.chart-frame svg {
  display: block;
  min-width: 480px;
}

/* ----- Fuel station map (framed light OSM artifact inside the dark system) ----- */

.map-frame {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: var(--space-4);
}

.fuel-map {
  height: 440px;
  width: 100%;
  background-color: var(--surface-1);
}

.map-noscript {
  padding: var(--space-4);
}

/* divIcon price chip: dark chip, steel border by default, green for the cheapest-3 by 95. */
.fuel-marker-icon {
  background-color: var(--surface-2);
  border: 1.5px solid var(--steel);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 15px;
  text-align: center;
  box-shadow: 0 1px 4px var(--overlay);
}

.fuel-marker-icon.is-best {
  border-color: var(--accent-strong);
  color: var(--accent-strong);
}

/* Stations outside the page's own place: present so the map is not a lie about where our data ends,
   but never competing with the ones the page is about. */
.fuel-marker-icon.is-away {
  border-color: var(--border-strong);
  color: var(--ink-muted);
  opacity: 0.8;
}

/* Leaflet popups stay light (readable over light tiles) — only tighten the type. */
.fuel-popup strong {
  display: block;
  margin-bottom: 2px;
}

.fuel-popup__addr {
  margin-bottom: 4px;
}

.fuel-popup__date {
  margin-top: 4px;
  color: var(--ink-faint);
  font-size: 0.82em;
}

.map-dagger {
  color: var(--ink-faint);
  cursor: help;
}

/* ----- Compact link list (the 50 municipality pages under /degalai) ----- */

/* auto-fill on a min track keeps 50 links to two columns at 375px and never overflows the viewport. */
.link-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: var(--space-1) var(--space-4);
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
}

.link-grid > li {
  min-width: 0;
}

.link-grid .muted-inline {
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* ----- Notices ----- */

.notice {
  background-color: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  color: var(--ink-muted);
  font-size: 0.9rem;
  margin-bottom: var(--space-4);
}

/* A notice that carries its sentences as paragraphs would otherwise end on a paragraph's 1rem
   bottom margin ON TOP of the box's own padding, leaving the text sitting visibly high in the box. */
.notice p:last-child {
  margin-bottom: 0;
}

/* No accent of its own: a notice belongs to no module, so the mark takes the muted colour of the
   line it sits in rather than borrowing a module's. */
.notice__icon {
  width: 0.95rem;
  height: 0.95rem;
  margin-right: 0.3rem;
}

.highlight-line {
  font-size: 1.1rem;
  color: var(--ink);
}

.highlight-line .accent {
  color: var(--accent-strong);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ----- Buttons ----- */

.btn-accent {
  display: inline-block;
  background-color: var(--accent);
  color: var(--on-accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-5);
  font-weight: 600;
}

.btn-accent:hover {
  background-color: var(--accent-strong);
  color: var(--on-accent);
  text-decoration: none;
}

/* .btn / .btn-primary are the Identity area's button vocabulary (they come from the compiled Identity
   UI pages, whose markup we cannot edit). Geometry matches what Bootstrap rendered; the colours are
   the brand green rather than Bootstrap blue, as they already were. */
.btn {
  display: inline-block;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink);
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  background-color: transparent;
  border: 1px solid transparent;
  border-radius: 0.375rem;
}

.btn:disabled {
  opacity: 0.65;
  pointer-events: none;
}

.btn-lg {
  padding: 0.5rem 1rem;
  font-size: 1.25rem;
  border-radius: 0.5rem;
}

.btn-primary {
  color: var(--on-accent);
  background-color: var(--accent);
  border-color: var(--accent);
}

.btn-primary:hover,
.btn-primary:active {
  color: var(--on-accent);
  background-color: var(--accent-strong);
  border-color: var(--accent-strong);
  text-decoration: none;
}

.btn-danger {
  color: var(--on-accent);
  background-color: var(--danger);
  border-color: var(--danger);
}

.btn-danger:hover,
.btn-danger:active {
  color: var(--on-accent);
  background-color: var(--danger-strong);
  border-color: var(--danger-strong);
  text-decoration: none;
}

.btn-link {
  color: var(--accent);
  text-decoration: underline;
}

.btn-link:hover {
  color: var(--accent-strong);
}

/* ----- Source / timestamp footers on data pages ----- */

.data-footer {
  margin-top: var(--space-6);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: 0.82rem;
}

.data-footer p {
  margin: 0 0 2px;
}

/* 2px between lines that are each ~20px tall read as one block of grey rather than as a source, a
   collection time and a generation time. The last line keeps the 2px above, so the footer does not
   grow a gap at its foot; only the joins between lines open. */
.data-footer p + p {
  margin-top: var(--space-2);
}

.backlink {
  display: inline-block;
  margin-bottom: var(--space-3);
  font-size: 0.85rem;
  color: var(--ink-muted);
}

/* ----- Site footer ----- */

.site-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  background-color: var(--footer-bg);
  color: var(--ink-muted);
  font-size: 0.82rem;
  padding: var(--space-4) 0;
  margin-top: var(--space-8);
}

.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  justify-content: space-between;
}

/* Brighter than the rest of the footer row so it does not read as another piece of small print. It is
   a plain flex child, so at narrow widths it wraps onto its own line like every other span here. */
.site-footer__motto {
  color: var(--ink);
}

.site-footer__live {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.install-app {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--accent);
  font-size: inherit;
  font-family: inherit;
  padding: 0.25rem 0.75rem;
  cursor: pointer;
}

.install-app:hover {
  border-color: var(--accent);
}

.install-app-hint {
  color: var(--ink-muted);
  font-size: inherit;
}

.btn-directions {
  display: inline-flex;
  align-items: center;
  gap: 0.4ch;
  padding: 0.2rem 0.5rem;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--accent);
  font-size: 0.78rem;
  line-height: 1.3;
  white-space: nowrap;
}

.btn-directions:hover {
  border-color: var(--accent);
  text-decoration: none;
}

.btn-directions__icon {
  flex-shrink: 0;
}

.cell-action {
  margin-top: 0.35rem;
}

/* Fuel trip calculator. .trip-calc itself carries no display, so the user agent's [hidden] keeps
   the whole block out of a JS-off page; the flex row below is a child and never overrides it. */
.trip-calc {
  margin: 0 0 var(--space-4);
}

.trip-calc__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.trip-calc__field {
  display: inline-flex;
  align-items: center;
  gap: 0.6ch;
  font-size: 0.85rem;
}

.trip-calc__input {
  display: inline-block;
  width: 5.5rem;
}

/* The table's cells are nowrap; this line is prose, and letting it wrap keeps it from widening the
   address column on a phone. */
.trip-line {
  margin-top: 0.35rem;
  font-size: 0.78rem;
  line-height: 1.35;
  white-space: normal;
}

/* ----- Focus states (visible, accent ring) ----- */

/* The list is enumerated rather than "*", so anything focusable and not named here falls back to
   the browser's own ring — a different width, offset and colour from every other control on the
   page. <summary> is the one such element the site uses: it is focusable natively, it is not an
   anchor or a button, and it carries no tabindex. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
.btn:focus-visible,
.form-control:focus,
.nav-link:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  box-shadow: none;
}

/* Respect reduced-motion: kill the pulse + hover transforms. */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  a.tile:hover {
    transform: none;
  }
}

/* Small screens: no horizontal overflow at 375px. */
@media (max-width: 575.98px) {
  .container {
    padding-left: var(--space-4);
    padding-right: var(--space-4);
  }

  .stat-strip {
    gap: var(--space-4);
  }

  /* THE HEADER ROW'S PHONE BUDGET, and the one place on the site where a few pixels decide whether
     the whole DOCUMENT scrolls sideways. The sticky bar's right cluster (account + Meniu + theme +
     LT/EN) is a fixed-width run of controls that cannot wrap and will not shrink, so at 360px it
     used to run 40px past the gutter and every page inherited a horizontal scrollbar. Measured at
     360 / 375 / 390: the row needs 399px at rest and the narrowest viewport offers 328px of content
     box, so the difference is taken from spacing and from the wordmark rather than from any control
     — nothing here is hidden, because each of the four is the only way to reach what it opens. */
  .site-nav > .container {
    gap: var(--space-2);
  }

  /* Redundant below 720px: the primary links are gone, so the container's own gap is the only
     separation the wordmark needs. */
  .brand-wordmark {
    margin-right: 0;
  }

  .brand-wordmark .brand-logo {
    height: 20px;
  }

  .site-nav__end {
    gap: var(--space-2);
  }

  .menu-button,
  .account-button {
    padding-left: var(--space-2);
    padding-right: var(--space-2);
  }

  .lang-switch {
    gap: 2px;
  }

  .lang-switch a {
    padding-left: 3px;
    padding-right: 3px;
  }
}

/* Auctions: city filter chips + type badge */
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1rem 0 1.25rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 0.85rem;
  color: var(--ink-muted);
  text-decoration: none;
  white-space: nowrap;
}

.chip:hover {
  color: var(--ink);
  border-color: var(--accent);
}

.chip--active,
.chip[aria-pressed="true"] {
  color: var(--accent-strong);
  border-color: var(--accent-line-strong);
  background-color: var(--accent-dim);
}

.chip--muted {
  color: var(--ink-faint);
  cursor: default;
}

/* The fuel switch above the station map is the same chip as a <button>: the state it carries lives in
   the page rather than in a URL, so aria-pressed is what lights it up. A fuel no station on the map
   prices is disabled — picking it would only empty the map. */
.chip--btn {
  background: transparent;
}

.chip--btn:disabled,
.chip--btn:disabled:hover {
  color: var(--ink-faint);
  border-color: var(--border);
  cursor: default;
}

.chip__count {
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

.badge {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
  /* Bare .badge (no modifier) is a white pill; every --modifier below re-colours it. */
  color: var(--on-danger);
  text-align: center;
  vertical-align: baseline;
  border: 1px solid var(--border-strong);
  white-space: nowrap;
}

.badge--auction {
  color: var(--accent-strong);
  border-color: var(--accent-line);
  background-color: var(--accent-dim);
}

/* Enforcement lots (not currently ingested) render visually distinct but neutral. */
.badge--enforcement {
  color: var(--ink-muted);
  border-color: var(--border-strong);
}

/* EU funding: deadline-proximity badge (amber = "act soon", distinct from the accent green). */
.badge--deadline {
  color: var(--amber);
  border-color: var(--amber-line);
  margin-left: var(--space-2);
}

/* EU funding: the LLM eligibility card, visually set apart under its honesty label. */
.funding-ai {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
}

.funding-ai__label {
  margin-bottom: var(--space-2);
  color: var(--ink-faint);
}

.funding-ai__text {
  margin: 0;
  color: var(--ink-muted);
  white-space: pre-line;
}

/* EU funding: portal facet filter bar (region / sector / applicant chip rows). */
.funding-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: var(--space-4) 0 var(--space-5);
}

.filter-group {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
}

.filter-label {
  flex: 0 0 auto;
  min-width: 7.5rem;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.filter-group .filter-chips {
  margin: 0;
}

/* Funded-projects: the prominent hub → projects link, and the no-JS search / municipality GET forms. */
.funding-nav {
  margin: var(--space-3) 0 var(--space-4);
}

.funding-search,
.funding-muni-form,
.offers-form,
.taxes-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-3) 0;
}

.funding-input,
.offers-input,
.taxes-input,
.news-filter__input {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
  color: var(--ink);
  font-size: 0.9rem;
  min-width: 14rem;
}

/* EU funding: the honesty note next to a title-derived locality (source facts carry none). */
.funding-derived-note {
  color: var(--ink-faint);
  font-size: 0.85em;
}

/* Funding hub: the badge row (status + EU-level + source) at the top of every card. */
.funding-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

/* Direct-EU marker: a distinct soft blue, apart from the green accent and amber deadline. */
.badge--eu {
  color: var(--info);
  border-color: var(--info-line);
  background-color: var(--info-wash);
}

/* Source badge: small, neutral, linked to the source's own site. */
.badge--source {
  color: var(--ink-muted);
  border-color: var(--border-strong);
  text-decoration: none;
}

a.badge--source:hover {
  color: var(--ink);
  border-color: var(--accent);
}

/* Direct-EU explanatory note under a card head / detail status, and the EU section lead. */
.funding-eu-note {
  margin: 0 0 var(--space-2);
  color: var(--info);
  font-size: 0.85rem;
}

.funding-eu-lead {
  margin-bottom: var(--space-4);
}

/* The primary (audience) facet row is set slightly apart from the esinvesticijos sub-facets. */
.filter-group--audience {
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-1);
  border-bottom: 1px solid var(--border);
}

.funding-facet-note {
  margin: var(--space-2) 0 0;
  color: var(--ink-faint);
  font-size: 0.8rem;
}

/* Funding hub: on narrow screens let long facet chip labels wrap instead of forcing horizontal scroll. */
@media (max-width: 560px) {
  .funding-filters .chip {
    white-space: normal;
  }
}

/* Server-side pager (shared by /auctions and /funding). Dark tokens, no JS. */
.pager {
  margin: var(--space-4) 0 var(--space-5);
}

.pager__range {
  margin: 0 0 var(--space-2);
  color: var(--ink-faint);
  font-size: 0.85rem;
}

.pager__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pager__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  min-height: 2.5rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

a.pager__link:hover {
  color: var(--ink);
  border-color: var(--accent);
}

.pager__link.is-current {
  color: var(--accent-strong);
  border-color: var(--accent-line-strong);
  background-color: var(--accent-dim);
  font-weight: 600;
}

.pager__link.is-disabled {
  color: var(--ink-faint);
  opacity: 0.5;
}

.pager__ellipsis {
  display: inline-flex;
  align-items: flex-end;
  min-width: 1.5rem;
  padding: 0 0.25rem;
  color: var(--ink-faint);
}

/* Slim TOP pager instance (numbers only): tighter, sits right under a section header / chip row. */
.pager--compact {
  margin-top: 0;
  margin-bottom: var(--space-4);
}

/* …but a filter block is not a heading: `.filter-group .filter-chips` strips the chips' own bottom
   margin and the group has none of its own, so a pager directly after one would sit flush against the
   chips. Restore the section rhythm at the one join where both margins are zero. */
.filter-group + .pager,
.filter-chips + .pager {
  margin-top: var(--space-4);
}

/* The same zero-against-zero join, one element along: on /bylos the article filter is followed by the
   table itself, and the chips rested on its top border. */
.filter-group + .table-bleed {
  margin-top: var(--space-4);
}

/* Funding hub: two-column shell — main content left, slim "Sources" aside right on desktop. The aside
   comes first in the DOM (so it stacks ABOVE the sections on mobile) and grid places it right on wide
   screens. */
.funding-layout {
  display: block;
}

.funding-main {
  min-width: 0;
}

/* Sources panel: a compact bordered box above the content on mobile. */
.funding-sources {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
}

.funding-sources__title {
  margin: 0 0 var(--space-2);
  font-size: 0.95rem;
  color: var(--ink);
}

.funding-sources__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each source row: the filter link grows, the external ↗ sits beside it, freshness wraps below. */
.funding-sources__list > li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  flex: 1 1 12rem;
}

.src-row {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0.3rem 0.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  text-decoration: none;
}

a.src-row:hover {
  color: var(--ink);
  border-color: var(--border-strong);
}

.src-row.is-active {
  color: var(--accent-strong);
  border-color: var(--accent-line-strong);
  background-color: var(--accent-dim);
  font-weight: 600;
}

.src-row__name {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.src-row__count {
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  color: var(--ink-faint);
}

.src-row.is-active .src-row__count {
  color: var(--accent-strong);
}

.src-ext {
  flex: 0 0 auto;
  color: var(--ink-faint);
  text-decoration: none;
  padding: 0 0.25rem;
}

.src-ext:hover {
  color: var(--accent);
}

.src-fresh {
  flex: 1 0 100%;
  padding: 0 0.5rem;
  color: var(--ink-faint);
  font-size: 0.75rem;
  font-family: var(--font-mono);
}

.badge--tiny {
  padding: 0.02rem 0.3rem;
  font-size: 0.75rem;
}

/* Mobile: the aside stacks above the sections — drop the per-source freshness line to keep it compact
   (freshness returns on desktop, where the slim column has vertical room). */
@media (max-width: 899px) {
  .src-fresh {
    display: none;
  }
}

/* Desktop: main content left, slim sources aside pinned right. */
@media (min-width: 900px) {
  .funding-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 15rem;
    gap: var(--space-6);
    align-items: start;
  }

  .funding-main {
    grid-column: 1;
    grid-row: 1;
  }

  .funding-sources {
    grid-column: 2;
    grid-row: 1;
    margin-bottom: 0;
    position: sticky;
    top: var(--space-4);
  }

  /* Stack the rows vertically in the narrow aside. */
  .funding-sources__list {
    flex-direction: column;
    gap: var(--space-1);
  }

  .funding-sources__list > li {
    flex: 1 1 auto;
    width: 100%;
  }
}

/* Funding hub: the total-in-section count beside a section heading. */
.section-count {
  font-size: 0.7em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  vertical-align: middle;
}

.auctions-table .unit {
  color: var(--ink-faint);
  font-size: 0.85em;
}

.auctions-table td {
  vertical-align: top;
}

/* Auctions table: fit every column at desktop width, no clipping */
.auctions-table { width: 100%; }

.auctions-table th.num, .auctions-table td.num { text-align: right; }
.auctions-table td.num .val {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.auctions-table .nowrap { white-space: nowrap; }

/* Type · Category share one column */
.auctions-table .col-type { white-space: nowrap; }
.auctions-table .col-type .cat { margin-left: 0.4rem; color: var(--ink-muted); }

/* Address is the only flexible column; it may wrap to two lines */
.auctions-table .col-addr { min-width: 12rem; }

/* Retail offers: product names run long, and every cell is nowrap, so an untruncated title pushes the
   six numeric columns out of the container. The title truncates to a share of the viewport (full text
   stays in the title attribute and behind the source link) so the whole table fits without scrolling. */
.offers-title {
  display: inline-block;
  max-width: min(24rem, 45vw);
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

/* Product thumbnail. The bytes come from the chain's own CDN (hotlinked, never stored here), so their
   aspect ratios are whatever each chain publishes: a fixed box plus contain shows every one whole. The
   empty variant is the same box, so a card without an image cannot shift the row it sits in. */
.offers-thumb {
  display: block;
  width: 56px;
  height: 56px;
  object-fit: contain;
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
}

.offers-thumb--empty {
  border: 1px solid var(--border);
}

.offers-table .col-thumb {
  width: 56px;
  padding-right: var(--space-2);
}

/* ----- Offers digest (the bare /offers landing) ----- */

.offers-digest__section {
  margin: var(--space-5) 0;
}

.offers-digest__title {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 0 0 var(--space-3);
}

.offers-digest__title a {
  color: var(--ink);
  text-decoration: none;
}

.offers-digest__title a:hover {
  color: var(--accent-strong);
}

/* auto-fill at 160px: two columns on a 375px phone, five or six on a desktop container. */
.offers-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--space-3);
}

.offers-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
  box-shadow: var(--shadow);
}

.offers-card__title {
  font-size: 0.9rem;
  color: var(--ink);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

a.offers-card__title:hover {
  color: var(--accent-strong);
}

.offers-card__chain {
  font-size: 0.78rem;
  color: var(--ink-muted);
}

.offers-card__prices {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: auto;
}

.offers-card__price {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink);
}

.offers-card__old {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-faint);
}

.offers-card__badge {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--accent-strong);
  background-color: var(--accent-dim);
  border-radius: var(--radius-sm);
  padding: 0 0.35em;
}

/* Staples comparison: a cell stacks the package price, then the computed unit price, then the chain's
   regular price, each quieter than the one above it. The unit price is the number the row is ranked by,
   so it stays legible rather than becoming fine print. */
.offers-staples__unit,
.offers-staples__regular {
  display: block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.offers-staples__unit {
  font-size: 0.82rem;
  color: var(--ink-muted);
}

.offers-staples__regular {
  font-size: 0.75rem;
  color: var(--ink-faint);
}

/* Cross-chain comparison: one line per product, its price chips flowing after the name so a phone stacks
   them instead of scrolling a table sideways. The gap between the cheapest and the dearest chain closes
   the row, quiet enough not to compete with the prices it is derived from. */
.offers-compare__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.offers-compare__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}

.offers-compare__body {
  flex: 1;
  min-width: 0;
}

.offers-compare__name {
  display: block;
  font-size: 0.9rem;
}

.offers-compare__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

.offers-compare__chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35em;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  padding: 0.1em 0.5em;
  border: 1px solid var(--border);
  border-radius: 999px;
}

.offers-compare__chip.is-best {
  border-color: var(--accent-line);
  background-color: var(--accent-dim);
}

.offers-compare__chain {
  color: var(--ink-muted);
}

.offers-compare__spread {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

/* The umbrella list runs to hundreds of lines, so it is collapsed behind its own heading. The h2 lives
   inside the <summary> (the element's heading-content model) so the section keeps its place in the
   document outline while the summary stays the thing you click. */
.offers-umbrella-details > summary {
  cursor: pointer;
}

.offers-umbrella-details > summary > .offers-digest__title {
  display: inline;
}

/* Percent-only offers name a product group, not a product: one line each, no card. */
.offers-umbrella {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9rem;
}

.offers-umbrella li {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--border);
}

.offers-umbrella__chain {
  color: var(--ink-muted);
  min-width: 4.5rem;
}

.offers-umbrella__title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.offers-umbrella__pct {
  font-family: var(--font-mono);
  color: var(--accent-strong);
}

.offers-digest__all {
  margin: var(--space-5) 0;
}

/* Sortable header links + active indicator */
.sort-link {
  color: var(--ink-muted);
  text-decoration: none;
  white-space: nowrap;
}
.sort-link:hover { color: var(--ink); }
.sort-link.is-active { color: var(--accent-strong); }
.sort-ind { margin-left: 0.25rem; color: var(--accent-strong); }

/* Compact link column: portal (↗) + Google Maps pin */
.auctions-table .col-link {
  text-align: center;
  width: 3.2rem;
  white-space: nowrap;
}
.ext-link {
  display: inline-block;
  color: var(--accent-strong);
  text-decoration: none;
  font-size: 1.05rem;
  line-height: 1;
}
.ext-link:hover { color: var(--ink); }

/* The body behind a number is a link to it, and the link keeps the colour of the line it sits in: a
   source note is a footnote, and a row of accent-green institution names in it would read as
   navigation and pull the eye off the number the note is about. The dotted underline is what says it
   is clickable — the only signal the muted colour leaves available. */
.source-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 0.2em;
}

.source-link:hover,
.source-link:focus-visible {
  color: var(--ink);
  text-decoration-style: solid;
}

.map-link {
  display: inline-flex;
  align-items: center;
  margin-left: 0.35rem;
  color: var(--ink-muted);
  vertical-align: middle;
}
.map-link:hover { color: var(--accent-strong); }
.map-link svg { display: block; }

.auctions-table .col-addr .addr-link {
  color: var(--ink);
  font-weight: 600;
}
.auctions-table .col-addr .addr-link:hover { color: var(--accent-strong); }

/* Location context under a "Kitur" address (county · ~distance) */
.auctions-table .loc-ctx {
  margin-top: 0.2rem;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--ink-faint);
}
.loc-ctx-note {
  color: var(--ink-faint);
  font-size: 0.85em;
}

/* ----- Auctions: two sources in one table (Turto bankas sales + NŽT state land) ----- */

/* Sale vs let. The badge names it; the left rule makes a let row unmistakable while scanning, because
   the money in that row is rent and reading it as a purchase price is the one error to prevent. */
.badge--sale {
  color: var(--ink-muted);
  border-color: var(--border-strong);
}

.badge--rent {
  color: var(--amber);
  border-color: var(--amber-line);
  background-color: var(--amber-wash);
}

.auctions-table .auction-row--rent td:first-child {
  box-shadow: inset 3px 0 0 var(--amber-rule);
}

/* Forest parcels carry their own statutory ceiling on how much one buyer may hold. */
.badge--forest {
  color: var(--good);
  border-color: var(--good-line);
  background-color: var(--good-wash);
}

/* Type cell now stacks badges + category + lease term; it can no longer be a single nowrap line. */
.auctions-table .col-type {
  white-space: normal;
  max-width: 11rem;
}
.auctions-table .col-type .badge { margin: 0 0.25rem 0.25rem 0; }
.auctions-table .col-type .rent-term {
  display: block;
  font-size: 0.8rem;
  color: var(--ink-faint);
}

/* Per-row source attribution: which portal published this lot, linked to that lot's announcement. */
.auctions-table .row-source {
  margin-top: 0.25rem;
}

/* Money we calculated rather than money the announcement printed. Left-aligned inside the right-aligned
   price column and allowed to wrap, so the label can never be separated from the figure it qualifies. */
.auctions-table .col-price .derived {
  display: block;
  margin-top: 0.25rem;
  max-width: 13rem;
  margin-left: auto;
  text-align: right;
  white-space: normal;
}
.auctions-table .col-price .derived__val {
  display: block;
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
  font-size: 0.85rem;
}
.derived__note {
  display: block;
  color: var(--ink-faint);
  font-size: 0.78rem;
  line-height: 1.25;
  font-style: italic;
}

.price-floor-note {
  margin: var(--space-2) 0 var(--space-3);
  color: var(--ink-faint);
  font-size: 0.85em;
}

/* ----- Auction detail: description excerpt + photos ----- */
.auction-desc__label {
  margin-bottom: var(--space-2);
}
.auction-desc__text {
  color: var(--ink);
  font-size: 0.92rem;
  line-height: 1.5;
  margin: 0 0 var(--space-3);
}

/* Photo thumbnails (gallery path, flag-gated): CSS-only responsive grid, no JS. */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.photo-grid__item {
  display: block;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.photo-grid__item:hover { border-color: var(--border-strong); }
.photo-grid__item { cursor: zoom-in; }
.photo-grid__item img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Fullscreen photo lightbox (auction-gallery.js). Hidden until an image is clicked. */
body.lightbox-open { overflow: hidden; }
.lightbox[hidden] { display: none; }
.lightbox {
  position: fixed;
  inset: 0;
  /* Above the sticky header (1050) and the drawer (1200): a fullscreen photo viewer is the topmost
     thing on the page while it is open, and it locks body scroll the same way the drawer does. */
  z-index: 1300;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--drawer-bg);
}
.lightbox__stage {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  max-height: 100%;
}
.lightbox__img {
  max-width: 100%;
  max-height: calc(100vh - 4 * var(--space-3));
  object-fit: contain;
  border-radius: var(--radius-sm);
}
.lightbox__counter {
  color: var(--ink-muted);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
.lightbox__close,
.lightbox__nav {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
  border-radius: var(--radius-sm);
  line-height: 1;
}
.lightbox__close:hover,
.lightbox__nav:hover { border-color: var(--accent); color: var(--accent-strong); }
.lightbox__nav {
  width: 44px;
  height: 64px;
  font-size: 2rem;
}
.lightbox__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 40px;
  height: 40px;
  font-size: 1.6rem;
}
.lightbox__nav[hidden] { display: none; }

/* ----- Legal prose (privacy policy) ----- */

.legal {
  max-width: 70ch;
}

.legal__meta {
  color: var(--ink-faint);
  font-size: 0.85rem;
  margin: 0;
}

.legal p {
  color: var(--ink-muted);
  margin: 0 0 var(--space-3);
}

.legal ul {
  color: var(--ink-muted);
  margin: 0 0 var(--space-3);
  padding-left: var(--space-5);
}

.legal li {
  margin-bottom: var(--space-1);
}

.legal .section-title {
  font-size: 1.1rem;
}

/* ----- Identity / framework classes -----
   The ASP.NET Core Identity UI pages (Login, Manage, password flows) are compiled into the package —
   their markup is not editable here, and it is written against Bootstrap's class names. Everything
   below exists to serve that markup, plus the one scaffolded page we do own (Account/Register).
   Nothing on the public pages uses these names except .text-danger (validation, /Error). */

/* Grid: only the column widths the Identity pages actually ask for. */
.row {
  display: flex;
  flex-wrap: wrap;
  margin-left: -0.75rem;
  margin-right: -0.75rem;
}

.row > * {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}

@media (min-width: 768px) {
  .col-md-3 { flex: 0 0 auto; width: 25%; }
  .col-md-4 { flex: 0 0 auto; width: 33.33333333%; }
  .col-md-6 { flex: 0 0 auto; width: 50%; }
  .col-md-9 { flex: 0 0 auto; width: 75%; }
  .col-md-12 { flex: 0 0 auto; width: 100%; }
}

@media (min-width: 992px) {
  .col-lg-3 { flex: 0 0 auto; width: 25%; }
  .col-lg-4 { flex: 0 0 auto; width: 33.33333333%; }
  .col-lg-6 { flex: 0 0 auto; width: 50%; }
  .col-lg-9 { flex: 0 0 auto; width: 75%; }
}

@media (min-width: 1200px) {
  .col-xl-6 { flex: 0 0 auto; width: 50%; }
}

/* Utilities, only the ones the Identity markup uses. */
.w-100 { width: 100% !important; }
.h-100 { height: 100% !important; }
.mb-3 { margin-bottom: 1rem !important; }
.pb-1 { padding-bottom: 0.25rem !important; }
.flex-column { flex-direction: column !important; }

.text-danger { color: var(--danger) !important; }
.text-info { color: var(--info) !important; }
.text-success { color: var(--accent-strong) !important; }
.text-muted { color: var(--ink-muted) !important; }
.text-dark { color: var(--ink) !important; }

/* Forms. Geometry is Bootstrap's (the pages are laid out against it); colour is the dark system. */
.form-label {
  margin-bottom: 0.5rem;
}

.form-control {
  display: block;
  width: 100%;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink);
  appearance: none;
  background-color: var(--ground);
  background-clip: padding-box;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
}

.form-control::placeholder {
  color: var(--ink-faint);
}

/* Floating labels: the label sits inside the control and shrinks to the top edge once the field has
   focus or content. ::after paints the ground behind the shrunken label so it does not sit on top of
   the control's own border. */
.form-floating {
  position: relative;
}

.form-floating > .form-control {
  height: calc(3.5rem + 2px);
  min-height: calc(3.5rem + 2px);
  line-height: 1.25;
  padding: 1rem 0.75rem;
}

.form-floating > .form-control::placeholder {
  color: transparent;
}

.form-floating > .form-control:focus,
.form-floating > .form-control:not(:placeholder-shown) {
  padding-top: 1.625rem;
  padding-bottom: 0.625rem;
}

.form-floating > label {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  height: 100%;
  padding: 1rem 0.75rem;
  overflow: hidden;
  text-align: start;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
  color: var(--ink-muted);
  border: 1px solid transparent;
  transform-origin: 0 0;
  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
}

.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label {
  color: var(--ink-faint);
  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

.form-floating > .form-control:focus ~ label::after,
.form-floating > .form-control:not(:placeholder-shown) ~ label::after {
  position: absolute;
  inset: 1rem 0.375rem;
  z-index: -1;
  height: 1.5em;
  content: "";
  background-color: var(--ground);
  border-radius: var(--radius-sm);
}

.form-check-input {
  flex-shrink: 0;
  width: 1em;
  height: 1em;
  margin-top: 0.25em;
  vertical-align: top;
  appearance: none;
  background-color: var(--ground);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: 1px solid var(--border-strong);
  print-color-adjust: exact;
}

.form-check-input[type="checkbox"] {
  border-radius: 0.25em;
}

.form-check-input:checked {
  background-color: var(--accent);
  border-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%230C0E0D' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E");
}

.input-group {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  width: 100%;
}

.input-group > .form-control {
  position: relative;
  flex: 1 1 auto;
  width: 1%;
  min-width: 0;
}

.input-group-text {
  display: flex;
  align-items: center;
  padding: 0.375rem 0.75rem;
  color: var(--ink-muted);
  background-color: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
}

/* Nav lists outside .site-nav: the Manage account sidebar (nav nav-pills flex-column). */
.nav {
  display: flex;
  flex-wrap: wrap;
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}

.nav-link {
  display: block;
  padding: 0.5rem 1rem;
  color: var(--ink-muted);
  text-decoration: none;
  background: none;
  border: 0;
}

.nav-link:hover {
  color: var(--ink);
}

.nav-pills .nav-link {
  border-radius: var(--radius-sm);
}

.nav-pills .nav-link.active {
  color: var(--on-accent);
  background-color: var(--accent);
}

/* Plain .table is Identity-only (our own data tables use .data-table). */
.table {
  width: 100%;
  margin-bottom: 1rem;
  color: var(--ink);
  border-collapse: collapse;
}

.table > :not(caption) > * > * {
  padding: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.alert {
  position: relative;
  padding: var(--space-3) var(--space-4);
  margin-bottom: 1rem;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
  color: var(--ink-muted);
}

.alert-danger { border-left-color: var(--danger); }
.alert-warning { border-left-color: var(--amber); }
.alert-info { border-left-color: var(--accent); }

/* The Identity status-message alert ships a dismiss button wired to Bootstrap's JS, which this site has
   not loaded since Phase A. It has been a dead control for a while; now it stops being drawn. */
.btn-close,
.close {
  display: none;
}

/* ----- Composition pie (/skaiciai/tautybes) ----- */
/* Ships hidden and is unhidden by ethnicity-pie.js: without scripting the table below carries every
   figure, so the pie is a second reading of the same numbers rather than the only one. */
.pie__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.pie-chip {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font: inherit;
  font-size: 0.82rem;
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
}

.pie-chip[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--ink);
}

.pie__body {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4);
}

.pie__svg {
  width: 200px;
  height: 200px;
  flex: 0 0 auto;
}

.pie-legend {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 15rem;
  font-size: 0.82rem;
  color: var(--ink-muted);
}

/* Focusable rows are how the pie is reachable without a mouse — the slices themselves are
   aria-hidden, so this list IS the accessible presentation of the chart. */
.pie-legend__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px 4px;
  border-radius: var(--radius-sm);
}

.pie-legend__item:hover,
.pie-legend__item:focus {
  background-color: var(--hover-wash);
  color: var(--ink);
  outline: none;
}

.pie-legend__swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex: 0 0 auto;
}

/* ----- /zemelapis: the ethnographic-region map -----
   The five shapes are inline SVG paths inside <a> elements, so they are links first and graphics
   second: focusable, followable with no scripting, and painted from the same tokens as everything
   else — a muted surface for the land, the border ink for the coastline between regions, and the
   accent tint under the pointer. Nothing here is carried by colour alone: the region's name is in the
   panel the click opens and in the plain list below the map. */

.region-map {
  margin-bottom: var(--space-4);
}

.region-map__svg {
  display: block;
  width: 100%;
  height: auto;
}

.map-region {
  fill: var(--surface-3);
  stroke: var(--border-strong);
  stroke-width: 2;
  cursor: pointer;
  transition: fill 0.2s ease, opacity 0.2s ease;
}

.map-region-link:hover .map-region,
.map-region-link:focus-visible .map-region {
  fill: var(--accent-dim);
  stroke: var(--accent);
}

/* The ring is on the LINK rather than on the path: the anchor is what takes focus, and an outline on
   the path would be drawn around the shape's bounding box in some engines and nowhere in others. */
.map-region-link:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* One region open: it keeps its full weight and the rest step back. A class rather than an inline
   style, so the stylesheet decides how far back in each theme — and so a reader who asks for reduced
   motion gets the same states without the transition. */
.region-map.is-open .map-region-link:not(.is-selected) .map-region {
  opacity: 0.45;
}

.region-map.is-open .is-selected .map-region {
  fill: var(--accent-dim);
  stroke: var(--accent);
}

/* The panel is the ordinary card with room for the close control in its corner. It ships hidden and
   region-map.js toggles the attribute; on a narrow screen it sits under the map, which is where the
   document already puts it — no positioning needed for it to read as a sheet below the graphic. */
.region-panel {
  position: relative;
  margin-bottom: var(--space-4);
}

/* THE `hidden` ATTRIBUTE HAS TO BE GIVEN BACK ITS MEANING. .panel sets `display: flex`, and an author
   rule beats the user-agent stylesheet's `[hidden] { display: none }` whatever their specificity — so
   without this line every panel ships expanded and the attribute the script toggles changes nothing a
   reader can see. Scoped to this page's panels rather than written as a global [hidden] guard: the
   same collision may exist elsewhere on the site, and fixing it site-wide is not this change's to
   make. */
.region-panel[hidden] {
  display: none;
}

.region-panel__close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-3);
  background: none;
  border: 0;
  color: var(--ink-muted);
  font-size: 1.4rem;
  line-height: 1;
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
}

.region-panel__close:hover {
  color: var(--ink);
}

.region-panel__hook {
  color: var(--ink-muted);
}

.region-links {
  list-style: none;
  margin: 0 0 var(--space-6);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}
