@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;src:url('/vendor/fonts/IBMPlexSans-Regular-Latin1.woff2') format('woff2');unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;src:url('/vendor/fonts/IBMPlexSans-Regular-Latin2.woff2') format('woff2');unicode-range:U+0100-017F}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;src:url('/vendor/fonts/IBMPlexSans-Medium-Latin1.woff2') format('woff2');unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;src:url('/vendor/fonts/IBMPlexSans-Medium-Latin2.woff2') format('woff2');unicode-range:U+0100-017F}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;src:url('/vendor/fonts/IBMPlexSans-SemiBold-Latin1.woff2') format('woff2');unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;src:url('/vendor/fonts/IBMPlexSans-SemiBold-Latin2.woff2') format('woff2');unicode-range:U+0100-017F}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/vendor/fonts/IBMPlexMono-Regular-Latin1.woff2') format('woff2');unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/vendor/fonts/IBMPlexMono-Regular-Latin2.woff2') format('woff2');unicode-range:U+0100-017F}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/vendor/fonts/IBMPlexMono-Medium-Latin1.woff2') format('woff2');unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/vendor/fonts/IBMPlexMono-Medium-Latin2.woff2') format('woff2');unicode-range:U+0100-017F}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url('/vendor/fonts/IBMPlexMono-SemiBold-Latin1.woff2') format('woff2');unicode-range:U+0000-00FF,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url('/vendor/fonts/IBMPlexMono-SemiBold-Latin2.woff2') format('woff2');unicode-range:U+0100-017F}

/* Chart series. Identical in both themes: they are marks read against a fill,
   not letterforms read against a surface. The five-slot order below was picked
   by running the categorical validator over candidate orderings — worst
   adjacent pair CVD dE 13.0, normal vision 22.7, on both the dark panel and
   white. */
:root{
  color-scheme:light;
  --ink:#f2f5f8; --panel:#ffffff; --panel-2:#e9eef4; --line:#d3dce4;
  --paper:#16222e; --muted:#5b6b7c; --signal:#2076ad; --signal-ink:#1a6493;
  --on-signal:#ffffff; --line-accent:#8ab6d4; --accent-soft:#dcebf5;
  --warn:#a41d33;
  --shadow:0 2px 8px rgba(22,34,46,.10);
  /* Choropleth: same blue hue, light->dark; the lightest step is allowed to
     recede toward the near-white page. cheap(q1) -> dear(q5). */
  --choro-1:#9ec5f4; --choro-2:#5598e7; --choro-3:#256abf; --choro-4:#184f95; --choro-5:#0d366b;
  --choro-0:#c2ccd6; --choro-stroke:rgba(22,34,46,.20);
  --v1:#3d92c8; --v2:#bb863a; --v3:#9085e9; --v4:#008300; --v5:#d55181;
  /* Vertical rhythm, in one place. Every gap between two sections, and the gap
     before the footer, is measured from these — so a sparse page (an alert
     landing, a thank-you, the 404) breathes exactly like a page with twenty
     blocks on it, and a section added later inherits the rhythm without
     anyone remembering to set it. */
  --section-gap:40px;
  --page-end:72px;

  /* The geometry, written down. Every one of these numbers was already on the
     site somewhere; what they were not was a vocabulary, so a card added last
     month picked 13px because 13px looked right beside whatever was open at
     the time, and the map picked 2px because the map was written first.
     Naming them is what stops that drift: 3px is the radius a panel and a
     control both take (circles are reserved for icon buttons and map
     markers), the spaces are the 4/8/12/16/24/32/48 ladder the layouts were
     already reaching for by eye, and --control-h is the height a button, a
     field and a nav action are supposed to share.

     Adopted rule by rule rather than by a sweep. A token means the same thing
     everywhere it is used, and replacing a hundred literals in one pass would
     have claimed that of a hundred numbers nobody had actually looked at —
     including the ones that are deliberately not on the ladder (the header's
     59px, a chart's 190px plot, the 9px donut stroke). Rules touched here get
     the tokens; the rest keep their literals until somebody has a reason to
     open them. */
  --radius:3px;
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-5:24px; --space-6:32px; --space-8:48px;
  --control-h:40px;
  /* One interaction treatment for the whole site. Anything that answers a
     pointer, a press or a focus does it by moving border, text and fill
     through the same 120ms; nothing moves, grows or lifts to say it was
     touched, and blue appears on focus, on selection and on a primary action
     rather than as decoration. Switched off under prefers-reduced-motion at
     the foot of this file. */
  --tx:border-color .12s ease,color .12s ease,background-color .12s ease;

  --sans:"IBM Plex Sans",ui-sans-serif,system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,"SF Mono",Menlo,monospace;

  /* Six glyphs, as masks rather than images: the fill comes from the element's
     own colour, so one declaration serves both themes and neither needs a
     second file. They are here, in one cached stylesheet, instead of inline in
     eleven thousand table rows. */
  --i-apt:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8'%3E%3Crect x='4.5' y='3' width='15' height='18' rx='1.2'/%3E%3Cpath d='M9 7.5h2M13 7.5h2M9 12h2M13 12h2M10.5 21v-4.2h3V21'/%3E%3C/svg%3E");
  --i-house:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linejoin='round'%3E%3Cpath d='M3 11.2L12 4l9 7.2'/%3E%3Cpath d='M5.4 10v10h13.2V10'/%3E%3Cpath d='M10 20v-5h4v5'/%3E%3C/svg%3E");
  --i-land:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5L11 5.5l9.5 3.5-7.5 3z'/%3E%3Cpath d='M3.5 8.5v7l9.5 3.5 7.5-3v-7'/%3E%3C/svg%3E");
  --i-other:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8'%3E%3Crect x='3.5' y='6' width='17' height='13' rx='1.2'/%3E%3Cpath d='M3.5 10.5h17'/%3E%3C/svg%3E");
  --i-pin:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9'%3E%3Cpath d='M12 21.2c4.4-4.6 6.6-8 6.6-10.6a6.6 6.6 0 10-13.2 0c0 2.6 2.2 6 6.6 10.6z'/%3E%3Ccircle cx='12' cy='10.4' r='2.4'/%3E%3C/svg%3E");
  --i-sort:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M8 13L2 5h12z'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: light){ :root:not([data-theme="dark"]){ color-scheme:light;
  --ink:#f2f5f8; --panel:#ffffff; --panel-2:#e9eef4; --line:#d3dce4;
  --paper:#16222e; --muted:#5b6b7c; --signal:#2076ad; --signal-ink:#1a6493;
  --on-signal:#ffffff; --line-accent:#8ab6d4; --accent-soft:#dcebf5;
  --warn:#a41d33;
  --shadow:0 2px 8px rgba(22,34,46,.10);
  /* Choropleth: same blue hue, light->dark; the lightest step is allowed to
     recede toward the near-white page. cheap(q1) -> dear(q5). */
  --choro-1:#9ec5f4; --choro-2:#5598e7; --choro-3:#256abf; --choro-4:#184f95; --choro-5:#0d366b;
  --choro-0:#c2ccd6; --choro-stroke:rgba(22,34,46,.20); } }
html[data-theme="light"]{ color-scheme:light;
  --ink:#f2f5f8; --panel:#ffffff; --panel-2:#e9eef4; --line:#d3dce4;
  --paper:#16222e; --muted:#5b6b7c; --signal:#2076ad; --signal-ink:#1a6493;
  --on-signal:#ffffff; --line-accent:#8ab6d4; --accent-soft:#dcebf5;
  --warn:#a41d33;
  --shadow:0 2px 8px rgba(22,34,46,.10);
  /* Choropleth: same blue hue, light->dark; the lightest step is allowed to
     recede toward the near-white page. cheap(q1) -> dear(q5). */
  --choro-1:#9ec5f4; --choro-2:#5598e7; --choro-3:#256abf; --choro-4:#184f95; --choro-5:#0d366b;
  --choro-0:#c2ccd6; --choro-stroke:rgba(22,34,46,.20); }

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--ink);color:var(--paper);font-family:var(--sans);
  font-size:15px;line-height:1.6;overflow-x:hidden}
a{color:var(--signal-ink);text-decoration:none}
a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--signal);outline-offset:2px}

/* No field on this site draws a scrollbar. In a box two or three lines tall
   the bar is shorter than the thumb it needs, it appears and disappears as
   somebody types, and on the platforms that draw it permanently it takes a
   character's width off every line. A textarea grows to fit instead (dsGrow
   in /alerts.js), which is why it neither scrolls nor offers a resize grip:
   the box is already the size of what is in it. Past the cap dsGrow puts
   overflow back to auto, so the text still scrolls; it is the bar that is
   hidden, never the scrolling. */
textarea,input{scrollbar-width:none}
textarea::-webkit-scrollbar,input::-webkit-scrollbar{display:none}
textarea{overflow:hidden;resize:none}

/* Room for the admin plan-preview strip, which /alerts.js adds to <html> when
   it paints one. A document that scrolls simply starts lower down; the map
   and the chat carry their own version of this rule, because their layouts
   are pinned to the viewport rather than to the flow. */
html.ds-pv-on body{padding-top:30px}
/* and the sticky header sticks below the strip rather than under it */
html.ds-pv-on .top{top:30px}
.skip{position:absolute;left:-9999px;top:0;background:var(--panel);color:var(--paper);padding:10px 14px;z-index:10}
.skip:focus{left:8px;top:8px}
.wrap{max-width:900px;margin:0 auto;padding:0 20px;width:100%}

/* Text that stands in for a picture: read aloud, never drawn. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---- the top navigation ----------------------------------------------- *
 * One 60px row, sticky, with a hairline under it and a shadow that only
 * appears once the page has actually moved (siteNav in /alerts.js adds
 * .ds-lift past 8px). Quiet on purpose: no gradients, and the only two glyphs
 * are the chat's spark and the account's head-and-shoulders.
 *
 * The middle is two disclosure menus and a plain link; the right is either
 * the invitation or, wearing .ds-in, the account pill. Both are in the HTML
 * and the stylesheet chooses, which is why the signed-in state can arrive
 * late without anything moving.
 *
 * Below 900px every one of these rules is overridden at the foot of this
 * file: the panels stop being dropdowns and the whole nav becomes a sheet.
 * ----------------------------------------------------------------------- */
.top{position:sticky;top:0;z-index:20;background:var(--panel);
  border-bottom:1px solid var(--line);transition:box-shadow .18s ease}
.top.ds-lift{box-shadow:var(--shadow)}
/* Fifty-nine and the hairline is sixty: the border is part of the header a
   reader measures, not something added under it. */
.top-in{display:flex;align-items:center;gap:20px;min-height:59px}
.brand{display:flex;align-items:center;flex:0 0 auto}
.brand img{display:block;height:40px;width:auto}
.topnav{flex:1 1 auto;display:flex;align-items:center;gap:20px;min-width:0}
/* Auto margins on both sides, so the middle group sits centred in whatever
   the lockup and the right-hand side leave it. */
.navmid{display:flex;align-items:center;gap:20px;margin:0 auto}
.navend{display:flex;align-items:center;gap:16px;flex:0 0 auto}

.navtrig,.navlink{font-size:15px;font-weight:500;line-height:1.2;color:var(--paper);
  white-space:nowrap}
.navtrig{display:inline-flex;align-items:center;gap:6px;margin:0;padding:6px 2px;
  background:none;border:0;font-family:inherit;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.navlink{padding:6px 2px}
.navtrig:hover,.navlink:hover{color:var(--signal-ink);text-decoration:none}
.navlink[aria-current=page]{color:var(--signal-ink)}
.navcar{flex:0 0 auto;opacity:.55;transition:transform .16s ease}
.navtrig[aria-expanded=true] .navcar{transform:rotate(180deg)}

.navmenu{position:relative}
/* The heading a phone reads where a desktop reads the button. Drawn only in
   the sheet, but it names its list in both: aria-labelledby takes the text of
   a display:none element, so the panels are titled the way the footer's four
   columns are, and by the same words. */
.navsec{display:none}
.navpanel{display:none;position:absolute;top:calc(100% + 11px);left:50%;transform:translateX(-50%);
  z-index:3;padding:10px;background:var(--panel);border:1px solid var(--line);border-radius:4px;
  box-shadow:var(--shadow)}
.navtrig[aria-expanded=true] ~ .navpanel{display:block}
/* The gap between the button and its panel is part of the menu's hover box:
   an invisible strip, so crossing it does not count as leaving. */
.navpanel::before{content:"";position:absolute;left:0;right:0;top:-14px;height:14px}
/* With no script the button is a button that does nothing, so the pointer and
   the keyboard open the panel instead. THEME_SCRIPT puts ds-js on <html> on
   the first parse, so wherever a script did arrive this never applies and
   Escape can really close a panel the pointer is still resting on. */
html:not(.ds-js) .navmenu:hover > .navpanel,
html:not(.ds-js) .navmenu:focus-within > .navpanel{display:block}
.navgrid{display:grid;grid-template-columns:1fr 1fr;gap:2px;margin:0;padding:0;list-style:none;
  width:560px;max-width:calc(100vw - 40px)}
.navpanel-1 .navgrid{grid-template-columns:1fr;width:240px}
/* The account panel hangs off the right edge of its pill rather than being
   centred on it: the pill is the last thing in the row, and a panel centred
   there would run off the page. */
.navme .navpanel{left:auto;right:0;transform:none}
.navgrid a,.navlogout{display:block;padding:9px 11px;border-radius:3px;color:var(--paper);
  text-align:left}
.navgrid a:hover,.navlogout:hover{background:var(--panel-2);text-decoration:none}
.navgrid a[aria-current=page]{background:var(--accent-soft)}
.navi-t{display:flex;align-items:center;gap:6px;font-size:14px;font-weight:600;line-height:1.35}
.navi-t svg{flex:0 0 auto;color:var(--signal)}
.navi-d{display:block;margin-top:2px;font-size:12.5px;line-height:1.4;color:var(--muted)}
.navpro{padding:1px 5px;border-radius:2px;background:var(--panel-2);color:var(--muted);
  font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase}
/* Quiet by weight rather than by colour: a muted sign-out reads as a disabled
   one, and this is the one control in the menu that always works. */
.navlogout{width:100%;background:none;border:0;font:inherit;font-size:14px;font-weight:500;
  color:var(--paper);cursor:pointer}
.navquit{margin-top:4px;padding-top:4px;border-top:1px solid var(--line)}

/* The right-hand side. A visitor is offered the map and a way in; a reader
   the site knows gets their plan and their own things instead. */
/* No height or padding of its own any more: the header's primary action is
   the same button as the pricing card's and the login form's, and it was the
   one that used to be four pixels shorter than all of them. */
.navcta{white-space:nowrap}
.navsign{font-size:15px;font-weight:500;color:var(--muted);white-space:nowrap}
.navsign:hover{color:var(--signal-ink);text-decoration:none}
.navme{display:none}
.top.ds-in .navcta,.top.ds-in .navsign{display:none}
.top.ds-in .navme{display:block}
.navpill{gap:8px;padding:3px 4px;border:1px solid var(--line);border-radius:999px;
  background:var(--panel)}
.navpill:hover{border-color:var(--line-accent)}
.navglyph{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;
  flex:0 0 auto;border-radius:50%;background:var(--panel-2);color:var(--paper)}
.navglyph svg{display:block}
/* The plan, in the price list's own escalation: quiet, soft accent, signal. */
.navplan{padding:2px 8px;border-radius:999px;font-size:11px;font-weight:700;letter-spacing:.03em;
  white-space:nowrap;background:var(--panel-2);color:var(--muted)}
.navplan[data-plan=standard]{background:var(--accent-soft);color:var(--signal-ink)}
.navplan[data-plan=pro]{background:var(--signal);color:var(--on-signal)}

/* Only in the sheet: the footer already carries the other language, and the
   header row has no width to spend on it. */
.navlang{display:none}
.navbtn{display:none;align-items:center;justify-content:center;width:38px;height:38px;
  margin-right:-8px;flex:0 0 auto;border-radius:8px;color:var(--paper);cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.navbtn svg path{transform-origin:center;transition:transform .16s ease,opacity .12s ease}
.navtog:focus-visible ~ .navbtn{outline:2px solid var(--signal);outline-offset:2px}
/* Motion here is decoration on a control, never the thing that says what it
   did: the caret's angle, the shadow and the bars all read fine arriving at
   once. */
@media (prefers-reduced-motion: reduce){
  .top,.navcar,.navbtn svg path{transition:none}
}
/* And the shared interaction treatment with them. One line rather than a list
   of selectors: --tx is the only thing any of them transitions, so emptying
   the token empties every rule that reads it, including the ones written
   after this one. */
@media (prefers-reduced-motion: reduce){ :root{ --tx:none } }

/* The standing invitation, at the foot of every content page. Panel rather
   than accent: it sits under the page's own conclusion and should read as an
   offer, not as an interruption. */
.chatcta{border-top:1px solid var(--line);margin-top:34px;padding:26px 0 30px}
/* The same soft-accent panel the page's other invitations wear (.cta), so the
   standing offer reads as an object on the page rather than as one more
   paragraph after the article has ended. The measure stays short inside it:
   a card the width of the page does not mean lines the width of the page. */
.chatcta-in{background:var(--accent-soft);border:1px solid var(--line-accent);border-radius:3px;
  padding:24px 26px 26px;display:grid;grid-template-columns:1fr auto;gap:20px 28px;align-items:center}
.chatcta-t{min-width:0}
.chatcta-k{display:flex;align-items:center;gap:7px;margin:0 0 6px;font-size:11.5px;font-weight:600;
  letter-spacing:.07em;text-transform:uppercase;color:var(--signal)}
.chatcta h2{margin:0 0 8px;font-size:20px}
.chatcta-p{margin:0 0 12px;color:var(--muted);font-size:14.5px;max-width:56ch}
.chatcta-q{margin:0;font-size:13px;color:var(--muted)}
/* Under the text, not beside it, once the two columns stop fitting side by
   side: a button squeezed into a narrow second column is worse than one that
   simply follows what it is offering. */
@media (max-width:720px){
  .chatcta-in{grid-template-columns:1fr;gap:16px}
  .chatcta .ctaline .button{width:100%;justify-content:center;text-align:center}
}
.chatcta-q em{font-style:normal;color:var(--paper)}

.crumbs{font-size:12.5px;color:var(--muted);margin:18px 0 10px;line-height:1.9}
.crumbs .sep{margin:0 7px;opacity:.6}
.crumbs a{color:var(--muted)}
/* main.wrap, not main: every content page's <main> also carries .wrap, whose
   own padding:0 20px shorthand was resetting this to nothing — which is why
   the share row sat flush against the footer's top edge. Same specificity as
   .wrap and later in the file, so the horizontal padding survives and the
   bottom of the page gets the gap it was always meant to have. */
main.wrap{padding-bottom:var(--page-end)}

h1{font-size:clamp(25px,5.4vw,34px);line-height:1.18;letter-spacing:-.015em;margin:.1em 0 .35em;font-weight:600}
h2{font-size:clamp(18px,3.4vw,21px);line-height:1.3;margin:0 0 14px;font-weight:600;letter-spacing:-.01em}
h3{font-size:15px;margin:30px 0 10px;font-weight:600}
section{margin:var(--section-gap) 0;padding-top:26px;border-top:1px solid var(--line);scroll-margin-top:64px}
/* Nothing may sit flush against the footer. This is the last element's floor
   whatever the page is made of. */
section:last-of-type{margin-bottom:var(--page-end)}
[id]{scroll-margin-top:64px}
section:first-of-type{border-top:none;padding-top:0}
p{margin:0 0 14px}
.kicker{font-size:14px;color:var(--muted);margin:-6px 0 16px}
.lead{color:var(--paper);opacity:.92}
.note{font-size:12.5px;color:var(--muted);line-height:1.65}

/* ---- the data-freshness line ------------------------------------------- *
 * freshLine() in gen-pages.mjs. Two readings — the register, and the day it
 * has been read to — under a place page's h1 and over the homepage's band of
 * counts.
 *
 * The register's own register: uppercase mono at eleven pixels with .09em of
 * tracking is what this site already sets a technical label in (.card-l, the
 * map's filter headings, the new-build dossier line), and using it here is
 * what makes the line read as an instrument reading rather than as a
 * sentence somebody wrote.
 *
 * Hairlines rather than middots between the readings, the same way the
 * new-build dossier line holds its four apart: a rule is quieter than a
 * character, and it sits at no baseline so it cannot look like punctuation
 * that belongs to either side. A line that wraps on a narrow phone starts its
 * second row with one, which is the price of not measuring text in CSS; it is
 * a hairline in the line colour and reads as a tick, not as missing content.
 * ------------------------------------------------------------------------ */
.fresh{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);
  margin:0 0 var(--space-4);font-family:var(--mono);font-size:11px;font-weight:500;line-height:1.6;
  letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
  font-variant-numeric:tabular-nums}
.fresh>*+*{padding-left:var(--space-2);border-left:1px solid var(--line)}
.thin{color:var(--muted);font-weight:400;font-size:16px}
main ul:not([class]),main ol:not([class]){margin:0 0 14px;padding-left:22px}
main ul:not([class]) li,main ol:not([class]) li{margin:0 0 7px}

/* ---- stat cards ------------------------------------------------------- */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:10px;margin:0 0 16px}
/* Six headline numbers auto-fit to five and one, which reads as an accident.
   Three to a row makes it two even rows, and each card gets width enough for
   its label to sit on one line. */
.cards[data-eu-cards]{grid-template-columns:repeat(3,1fr)}
@media (max-width:720px){ .cards[data-eu-cards]{grid-template-columns:repeat(2,1fr)} }
@media (max-width:430px){ .cards[data-eu-cards]{grid-template-columns:1fr} }

/* ---- the five headline measures on a place page ------------------------ *
 * summaryBlock()'s own grid (see gen-pages.mjs), and nothing else: apartments,
 * houses, land, rent, yield. Five fixed columns rather than the shared
 * auto-fit, which happened to land on five at the current page width and would
 * silently become four the day the measure changed — and four measures beside
 * a fifth on its own row is not a comparison, it is an accident.
 *
 * The floor and the flex column are what make them one table rather than five
 * tiles. The labels run to one line or to two, the captions to two or three,
 * and without a floor every value sat at a different height and no two could
 * be read against each other. With it, the comparison chips all sit on the
 * same baseline, because margin-top:auto pushes them there from a common
 * bottom.
 *
 * The floor comes off on a phone: one card per row has nothing to line up
 * with, and 164px of it is a card that is mostly empty.
 * ----------------------------------------------------------------------- */
.cards.metrics{grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--space-3);margin:20px 0 var(--space-4)}
.cards.metrics .card{min-height:164px;padding:var(--space-4);display:flex;flex-direction:column}
.cards.metrics .card-b{margin-top:auto;align-self:flex-start}
@media (max-width:720px){ .cards.metrics{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:430px){ .cards.metrics{grid-template-columns:1fr}
  .cards.metrics .card{min-height:0} }

/* The OPPN tile (actsTile() in gen-pages.mjs), sixth in the row and the only
   one with a sentence and a list rather than a single number: full width
   whatever the column count above settles on, so the extra content has room
   and the five plain figures above keep their own even columns. Hidden
   until ACTS_TILE_SCRIPT fills it — see the attribute in the markup. */
.card.acts-card{grid-column:1/-1;min-height:0}
.card.acts-card .acts-count{font-family:var(--mono);font-size:14px;font-weight:600;
  letter-spacing:-.01em;margin:6px 0 8px}
.card.acts-card .chips:not(:empty){margin-bottom:8px}
/* .cards.metrics .card sets its own display:flex above, an author rule that
   would otherwise outrank the UA stylesheet's [hidden]{display:none} — this
   is the one selector on the page specific enough to win that back. */
.cards.metrics .card.acts-card[hidden]{display:none}

/* ---- a place page's own rhythm and measure ----------------------------- *
 * <main class="wrap area">: the municipality and settlement pages, and only
 * those. They are the longest documents on the site — twenty sections of
 * analysis under one h1 — and they are the ones a reader scans rather than
 * reads end to end, so the two things that decide whether a scan works are
 * where a section starts and how long its lines are.
 *
 * The rhythm moves from the shared 40 + 26 (margin above, padding below the
 * rule) to a symmetrical 28 + 28. The gap between two sections shrinks from
 * 66px to 56, which is the point — but more than that, the hairline now sits
 * exactly halfway between the end of one section and the start of the next,
 * so it reads as a divider belonging to neither rather than as a lid on the
 * one below it. margin-block:0 is what makes the padding the whole of the
 * rhythm; without it the two would add.
 *
 * The floor at the foot of the page is restated for the same reason: the
 * shared rule hangs --page-end off the last section's margin, which this has
 * just set to zero, and main.wrap's own padding-bottom already carries it.
 *
 * 78ch is the measure. A 15px line across an 860px column runs to about 110
 * characters, which is half again what an eye can track back from, and it is
 * why the analytical paragraphs on these pages read as a grey field. The row
 * of buttons is exempt: .ctaline is a flex row, not a paragraph, and capping
 * it would strand a second button under the first.
 * ------------------------------------------------------------------------ */
.area > section{margin-block:0}
.area > section:not(.cta):not(.newsletter){padding-block:28px}
.area > section:not(.cta):not(.newsletter):first-of-type{padding-top:0}
.area > section:last-of-type{margin-bottom:0}
.area > section > p:not(.ctaline){max-width:78ch;line-height:1.65}
.area > section > h2{margin:0 0 10px;font-size:20px}
/* The standard panel: a hairline, a 3px corner, 20px of room, and no shadow.
   No shadow is the whole point — a stat card is a region of the page, not an
   object floating above it, and the moment one of them lifts every reader
   starts looking for what it is lifting over. Stated rather than merely
   omitted, because .hsearch and .chatcta-in sit close enough to this class
   for somebody to reasonably assume it inherits their elevation. */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:20px;
  box-shadow:none;display:flex;flex-direction:column}
.card-l{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);font-weight:500}
.card-v{font-family:var(--mono);font-size:23px;font-weight:600;letter-spacing:-.02em;margin:6px 0 3px;
  font-variant-numeric:tabular-nums;line-height:1.15;white-space:nowrap}
.card-u{font-size:12px;font-weight:500;color:var(--muted);margin-left:4px;letter-spacing:0}
.card-h{font-size:11.5px;color:var(--muted);line-height:1.45}
/* A figure that had to reach past the standard window. The value itself is
   printed like any other, because it is a real median of real transactions;
   only the caption says so, and the mark carries the reason. */
.card.widened .card-h{color:var(--muted)}
.card-i{display:inline-block;color:var(--signal-ink);font-weight:600;cursor:help}
.card-b{display:flex;flex-wrap:wrap;gap:5px;margin-top:auto;padding-top:8px}
/* A comparison delta beside a value. Mono and tabular so the two badges on
   one card, and the badges on five cards in a row, line up as figures. */
.pill{font-size:10.5px;font-family:var(--mono);color:var(--muted);background:var(--panel-2);
  border-radius:2px;padding:2px 6px;white-space:nowrap;font-variant-numeric:tabular-nums}

/* ---- tables ----------------------------------------------------------- */
.tw{overflow-x:auto;margin:0 0 6px;-webkit-overflow-scrolling:touch}
/* A table that scrolls sideways has to look like one. On a phone the Donos
   table simply stopped mid-column with nothing to say there was more, so the
   reader read three of five columns and believed that was the table. The cue
   is an inset shadow on the edge there is still something behind, put there
   by wideTables() in /alerts.js (which measures the real overflow) rather
   than by a guess in CSS, and taken off again at the end of the scroll.
   Phone widths only: on a desktop the table fits. */
@media (max-width:480px){
  .tw.tw-r{box-shadow:inset -20px 0 15px -13px rgba(0,0,0,.38)}
  .tw.tw-l{box-shadow:inset 20px 0 15px -13px rgba(0,0,0,.38)}
  .tw.tw-l.tw-r{box-shadow:inset 20px 0 15px -13px rgba(0,0,0,.38),
    inset -20px 0 15px -13px rgba(0,0,0,.38)}
}
table{border-collapse:collapse;width:100%;font-size:13.5px;min-width:min(100%,330px)}
th{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:500;
  text-align:left;padding:0 12px 7px 0;white-space:nowrap;border-bottom:1px solid var(--line)}
td{padding:8px 12px 8px 0;border-bottom:1px solid var(--line);white-space:nowrap}
th.n,td.n{text-align:right}
th:last-child,td:last-child{padding-right:0}
td.n{font-family:var(--mono);font-variant-numeric:tabular-nums}
tr:last-child td{border-bottom:none}
.deals td:nth-child(3){white-space:normal;min-width:110px}
.cats td:first-child{white-space:normal;min-width:118px}
.rank-table td:nth-child(2){white-space:normal}
.rank{font-family:var(--mono);color:var(--muted);font-size:12px}
/* The two tables on the privacy page (sub-processors, retention) hold
   sentences rather than figures. Every cell wraps, the columns keep a floor
   so a phone does not shred them into single words, and the text sits at the
   top of the row so a long purpose does not push its neighbour off centre. */
.legal-t th,.legal-t td{white-space:normal}
.legal-t td{vertical-align:top;min-width:96px}

/* ---- the listings ----------------------------------------------------- *
 * A row opens that record on the map. It is not an <a> — see recordRows()
 * in /alerts.js for why — so everything a link gives for free is spelled
 * out here: the cursor, the hover, and a focus ring that a keyboard reader
 * can actually see. */
.rowlink{cursor:pointer}
tr.rowlink:hover td{background:var(--panel)}
tr.rowlink:focus-visible{outline:2px solid var(--signal);outline-offset:-2px}
/* The price per square metre is the number the page is about. */
.deals td.m2{color:var(--signal-ink);font-weight:600}
/* The address, with the settlement under it. */
.deals .sub{display:block;font-size:11.5px;color:var(--muted);font-weight:400}
/* First seen in this import — the same test the weekly alert mail applies. */
.novo{display:inline-block;margin-left:8px;padding:1px 6px;border-radius:2px;background:var(--signal);
  color:var(--on-signal);font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  vertical-align:1px}
/* One 14px glyph per row, drawn from the page's own ink through a mask, so
   the icons cost one cached rule rather than an inline <svg> on each of the
   eleven thousand rows. */
.ti,.pin{display:inline-block;width:14px;height:14px;vertical-align:-2px;background:currentColor;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain}
.ti{margin-right:8px;opacity:.5}
.ti-apt{-webkit-mask-image:var(--i-apt);mask-image:var(--i-apt)}
.ti-house{-webkit-mask-image:var(--i-house);mask-image:var(--i-house)}
.ti-land{-webkit-mask-image:var(--i-land);mask-image:var(--i-land)}
.ti-other{-webkit-mask-image:var(--i-other);mask-image:var(--i-other)}
.pin{-webkit-mask-image:var(--i-pin);mask-image:var(--i-pin);opacity:.35;color:var(--signal-ink)}
td.pincell{width:1%;padding-right:0;text-align:right}
tr.rowlink:hover .pin,tr.rowlink:focus-visible .pin{opacity:1}

/* ---- sortable headers -------------------------------------------------- *
 * The button inside the <th> is built by /alerts.js and never present in the
 * file itself, so a reader without JavaScript sees a plain heading and the
 * server's own order. */
.sortbtn{display:inline-flex;align-items:center;gap:5px;padding:0;border:0;background:none;color:inherit;
  font:inherit;letter-spacing:inherit;text-transform:inherit;cursor:pointer}
th.n .sortbtn{flex-direction:row-reverse}
.sortbtn:hover{color:var(--paper)}
.sortmark{width:8px;height:8px;background:currentColor;opacity:.3;
  -webkit-mask:var(--i-sort) no-repeat center/contain;mask:var(--i-sort) no-repeat center/contain}
th[aria-sort="ascending"] .sortmark{opacity:1;transform:rotate(180deg)}
th[aria-sort="descending"] .sortmark{opacity:1}
th[aria-sort="ascending"],th[aria-sort="descending"]{color:var(--paper)}
/* The rank means "rank by apartment price" and stops meaning it the moment
   the table is ordered by something else. */
.rank-table.resorted td:first-child{opacity:.4}

details.dt,details.faq{border-top:1px solid var(--line);padding:0}
details.dt{margin-top:14px}
details.dt>summary,details.faq>summary{cursor:pointer;padding:11px 0;font-size:13.5px;font-weight:500;
  list-style:none;display:flex;align-items:center;gap:9px}
details.faq>summary{font-size:15px}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"+";font-family:var(--mono);color:var(--muted);font-size:15px;line-height:1}
details[open]>summary::before{content:"−"}
details.faq>p{margin:0 0 16px;padding-left:20px;color:var(--paper);opacity:.9;font-size:14.5px}
details.faq:last-of-type{border-bottom:1px solid var(--line)}

/* ---- charts ----------------------------------------------------------- */
.chart{margin:0 0 22px}
figcaption{font-size:12px;color:var(--muted);margin-top:9px;line-height:1.5}
.plotwrap{position:relative;padding-left:46px;padding-right:74px}
.plot{position:relative;height:190px;height:var(--h,190px)}
.plot svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.plot .g{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.plot .s{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke}
.plot .dot{stroke-width:6}
.s1{stroke:var(--v1)} .s2{stroke:var(--v2)} .s3{stroke:var(--v3)}
.t1{color:var(--v1)} .t2{color:var(--v2)} .t3{color:var(--v3)}
.yl{position:absolute;left:-46px;width:40px;text-align:right;transform:translateY(-50%);
  font-family:var(--mono);font-size:10.5px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.dl{position:absolute;transform:translateY(-50%);margin-left:8px;font-size:11px;font-weight:600;white-space:nowrap}
.xaxis{position:relative;height:15px;margin-top:5px}
.xaxis span{position:absolute;transform:translateX(-50%);font-family:var(--mono);font-size:10.5px;color:var(--muted)}
.bars{display:flex;align-items:flex-end;gap:2px;height:110px;height:var(--h,110px);margin-bottom:5px}
.bars i{flex:1 1 0;min-width:0;background:var(--v1);border-radius:2px 2px 0 0;min-height:1px;position:relative}
.blabels{display:flex;gap:2px}
.blabels span{flex:1 1 0;min-width:0;text-align:center;font-family:var(--mono);font-size:10px;
  color:var(--muted);white-space:nowrap;overflow:visible}

.donutbox{display:flex;gap:22px;align-items:center;flex-wrap:wrap;margin:0 0 20px}
.donut{width:132px;height:132px;flex:0 0 auto}
.donut .a{fill:none;stroke-width:19}
.a1{stroke:var(--v1)} .a2{stroke:var(--v2)} .a3{stroke:var(--v3)} .a4{stroke:var(--v4)} .a5{stroke:var(--v5)}
.legend{list-style:none;margin:0;padding:0;flex:1 1 260px;min-width:230px;font-size:13px}
.legend li{display:flex;align-items:center;gap:9px;padding:4px 0;border-bottom:1px solid var(--line)}
.legend li:last-child{border-bottom:none}
.sw{width:10px;height:10px;border-radius:2px;flex:0 0 auto}
.s1.sw{background:var(--v1)} .s2.sw{background:var(--v2)} .s3.sw{background:var(--v3)}
.s4.sw{background:var(--v4)} .s5.sw{background:var(--v5)}
.lg-l{flex:1 1 auto}
.lg-v,.lg-n{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:12px}
.lg-v{color:var(--paper)} .lg-n{color:var(--muted);min-width:52px;text-align:right}

/* ---- chips, media, cta ------------------------------------------------ */
/* The anchor is the place name and only the place name: a link whose text
   reads "Bežigrad4 275 €/m²" tells a crawler nothing about where it goes. */
.chips{list-style:none;display:flex;flex-wrap:wrap;gap:7px;padding:0;margin:0}
.chips li{display:inline-flex;align-items:baseline;gap:8px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--radius);padding:6px 10px;font-size:13px;
  transition:var(--tx)}
.chips li:hover{border-color:var(--line-accent);background:var(--panel-2)}
.chips a{color:var(--paper);text-decoration:none}
.chips a:hover{text-decoration:underline}
.chip-v{font-family:var(--mono);font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}

.media{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.media figure{margin:0}
.svbox{position:relative;aspect-ratio:4/3;border:1px solid var(--line);border-radius:3px;
  overflow:hidden;background:var(--panel-2);display:flex;align-items:center;justify-content:center}
.svbox img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:saturate(.5) brightness(.55)}
.svbox .svgo{position:relative;z-index:1;border:0;cursor:pointer;font-family:inherit}
.svbox iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.aerial .tiles{display:grid;grid-template-columns:1fr 1fr;aspect-ratio:4/3;overflow:hidden;
  border:1px solid var(--line);border-radius:3px;background:var(--panel-2)}
.aerial img{width:100%;height:100%;object-fit:cover;display:block}

/* ---- the live page (/obcina/<slug>/v-zivo/) --------------------------- *
 * The cameras are the substance, so they get the room; everything else is a
 * slot the inline script fills, and is dressed as the site's cards already
 * are. Nothing here is loud, because the page is already moving. */
.cams{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin:0 0 6px}
.cams figure{margin:0}
.cams img{display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;
  border:1px solid var(--line);border-radius:3px;background:var(--panel-2)}
.cams figcaption{font-size:11.5px;color:var(--muted);line-height:1.45;margin-top:6px}
/* Twelve hours never fit a phone, and wrapping them into three rows of four
   reads as a table. One row that scrolls keeps the shape of a forecast. */
.livehours{list-style:none;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(58px,1fr);
  gap:6px;padding:0;margin:0 0 14px;overflow-x:auto;-webkit-overflow-scrolling:touch}
.livehours li{background:var(--panel);border:1px solid var(--line);border-radius:3px;
  padding:8px 6px;text-align:center}
.lh-t{display:block;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.lh-s{display:block;font-size:16px;line-height:1.5;min-height:1.5em}
.lh-v{display:block;font-family:var(--mono);font-size:14px;font-weight:600;
  font-variant-numeric:tabular-nums}
.livelist{list-style:none;padding:0;margin:0 0 14px}
.livelist li{background:var(--panel);border:1px solid var(--line);border-radius:3px;
  padding:10px 12px;margin:0 0 7px;font-size:13.5px;line-height:1.55}
.lv-t{color:var(--muted)}
.livesun,.livewind{font-variant-numeric:tabular-nums}

.cta{background:var(--accent-soft);border:1px solid var(--line-accent);border-radius:3px;padding:20px}
/* The page-opener rule (section:first-of-type, 0-1-1) strips border-top and
   padding-top from the first section on a page, and .cta at 0-1-0 cannot win
   them back — so a .cta that opens a page (the /orodja/ hub) rendered with
   three borders and its heading flush against the top edge. */
section.cta:first-of-type{border-top:1px solid var(--line-accent);padding-top:20px}
.cta h2{margin-bottom:10px}
.ctaline{display:flex;flex-wrap:wrap;gap:10px;margin:0}

/* The municipality map CTA: a locator inset beside the invitation. */
/* The municipality profile ("v številkah"): photograph beside the lead and
   the key cards, the Wikipedia lead as a quotation, and tables whose first
   column is prose. */
.profile-hero{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:22px;align-items:start;margin:0 0 22px}
.profile-photo{margin:0}
.profile-photo img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;border-radius:3px;border:1px solid var(--line)}
.profile-photo figcaption{font-size:12px;color:var(--muted);margin-top:6px}
.profile-loc{padding:12px;background:var(--panel);border:1px solid var(--line);border-radius:3px}
.profile-intro .cards{grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
.wiki{margin:0 0 18px;padding:14px 18px;border-left:3px solid var(--signal);background:var(--panel);border-radius:0 3px 3px 0}
.wiki p{margin:0 0 8px}
.wiki footer{margin:0}
table.profile td:first-child{min-width:180px}
.about-grid{display:grid;grid-template-columns:150px minmax(0,1fr);gap:18px;align-items:start}
.about-grid .wiki{margin:0}
.profile-locator{padding:8px;background:var(--panel);border:1px solid var(--line);border-radius:3px}
@media (max-width:560px){.about-grid{grid-template-columns:1fr}.profile-locator{width:150px}}
.profile-link{margin:0 0 22px}
.chartbox{margin:18px 0 6px;scroll-margin-top:70px}
.chartbox h3{margin:0 0 6px;font-size:14px}
.chartbox .chart{margin-bottom:4px}
.chart-share{margin:0 0 14px;font-size:12px}
.chart-share a{color:var(--muted)}
.chartbox:target{outline:2px solid var(--signal);outline-offset:8px;border-radius:3px}
.sp-ranks{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px;margin:0 0 8px}
.sp-rank{background:var(--panel);border:1px solid var(--line);border-radius:3px;padding:12px 14px}
.sp-rank h3{margin:0 0 8px;font-size:13px}
.sp-rank ol{margin:0;padding-left:20px;font-size:13.5px}
.sp-rank li{margin:0 0 3px}
.sp-rank-v{font-family:var(--mono);color:var(--muted);margin-left:4px}
@media (max-width:720px){.profile-hero{grid-template-columns:1fr}}
.mapcta{display:flex;gap:22px;align-items:center}
.mapcta-body{flex:1 1 auto;min-width:0}
.mapcta-body h2{margin-top:0}
.mapcta-body p{margin:0 0 14px;color:var(--paper);opacity:.92}
.mapcta-art{flex:0 0 auto;width:190px;max-width:38%}
.loc-map{display:block;width:100%;height:auto}
.loc-map .loc-bg{fill:var(--panel-2);stroke:var(--line-accent);stroke-width:.8;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.loc-map .loc-hi{fill:var(--signal);stroke:var(--on-signal);stroke-width:1.1;
  stroke-linejoin:round;vector-effect:non-scaling-stroke;paint-order:stroke fill}
@media (max-width:560px){ .mapcta{flex-direction:column-reverse;align-items:stretch;gap:14px}
  .mapcta-art{width:150px;max-width:60%;margin:0 auto} }
/* ---- the one button ---------------------------------------------------- *
 * Header, homepage query, pricing, login, Google, forms: every one of them
 * used to pick its own height and its own type size, and a reader crossing
 * two of them in one scroll saw two different products. One scale now — 40px
 * tall, 14/20 semibold, 3px — and the two places that genuinely need another
 * (the phone's authentication controls at 44px, the map's dense tools at
 * 36px) say so where they are, rather than everybody inventing a third.
 *
 * inline-flex rather than inline-block, so 9px of padding above a 20px line
 * inside a 40px box centres the label instead of leaving it high in a box a
 * min-height stretched underneath it. It also makes the half-dozen
 * justify-content:center overrides already written against this class mean
 * what their authors thought they meant.
 *
 * The transparent border is what makes an <a class="button"> and a
 * <button class="button"> the same 40px outside AND the same 20px of label
 * inside: the element that carries a real border would otherwise be two
 * pixels taller, or two pixels tighter, depending which way it was fixed. */
.button{display:inline-flex;align-items:center;justify-content:center;
  background:var(--signal);color:var(--on-signal);font-weight:600;font-size:14px;line-height:20px;
  min-height:var(--control-h);padding:9px var(--space-4);border:1px solid transparent;
  border-radius:var(--radius);text-decoration:none;transition:var(--tx)}
.button:hover{text-decoration:none;opacity:.9}
.button.ghost{background:transparent;color:var(--signal-ink);border:1px solid var(--line-accent)}
button.button{font-family:inherit;border:1px solid var(--signal);cursor:pointer}

/* ---- the account hub (/racun/, /en/account/) ------------------------- *
 * Painted client-side by accountPage() in /alerts.js. The chrome is the site's
 * own; these rules dress the mount it fills. */
.account-app{margin-top:8px}
.account-boot{min-height:2em}
.account-app section{margin:26px 0 0;padding-top:20px;border-top:1px solid var(--line)}
.account-app section:first-child{margin-top:0;padding-top:0;border-top:none}
.account-app h2{font-size:15px;margin:0 0 6px}
.acct-sub{color:var(--muted);font-size:13px;margin:0 0 14px}
/* Full-page sign-in: one narrow column, centred, never a floating dialog.
 *
 * Two fields and a button, and it used to fill a phone screen and a half. The
 * fields were the reason — a full-width input with 15px type and no stated
 * height ran to whatever the platform felt like, which on a phone is roughly
 * twice what a 44px target needs — and the fix is to state the height rather
 * than to squeeze the padding: 44px is the platform's own comfortable target,
 * and it is the same 44 the tabs and the two buttons take, so the whole form
 * is one control repeated rather than five sizes stacked.
 *
 * 520px, not 400. A column narrower than the measure of the page it sits on
 * reads as a dialog that forgot to be a dialog; 520 is wide enough to be a
 * page and still short enough that the label, the field and the button are
 * one glance. The padding is what frames it as one: 48 above, 64 below. */
.acct-auth{max-width:520px;margin:0 auto;padding-block:var(--space-8) 64px}
.acct-auth .acct-tabs{display:flex;gap:0;margin:0 0 18px;border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden}
/* No radius of its own: the pair sits inside a 3px box that clips them, and a
   corner stated twice is a corner that goes wrong the day one of them moves. */
.acct-tab{flex:1 1 0;min-height:44px;padding:10px 8px;font:inherit;font-size:16px;font-weight:600;
  text-align:center;background:var(--panel);color:var(--muted);border:0;cursor:pointer;
  transition:var(--tx)}
.acct-tab[aria-selected=true]{background:var(--signal);color:var(--on-signal)}
.acct-field{margin:0 0 20px}
/* The label register the rest of the site uses for metadata — mono, twelve
   pixels, uppercase, .08em — rather than a smaller copy of the running face.
   These were the loosest labels on the site and they sat two inches from the
   tightest ones. */
.acct-field label{display:block;font:500 12px/1.3 var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);margin:0 0 6px}
.acct-field input{width:100%;box-sizing:border-box;height:44px;font:inherit;font-size:16px;
  padding:10px var(--space-3);color:var(--paper);background:var(--panel-2);
  border:1px solid var(--line);border-radius:var(--radius);transition:var(--tx)}
.acct-field input:focus{outline:2px solid var(--signal);outline-offset:1px}
.acct-app .button,.account-app .button{margin-top:2px}
/* flex, not block: .button is inline-flex and centres its own label, and
   display:block would take that away and leave the text sitting high in the
   44px box. */
.acct-full{display:flex;width:100%;box-sizing:border-box;min-height:44px;font-size:16px;
  text-align:center}
/* The lead over the form and the "or" rule under the Google button: the same
   24px of silence on both, so the three parts of the screen — choose, sign in
   with Google, sign in with an address — are three steps and not a paragraph,
   a gap, a button, a bigger gap. */
.acct-auth .acct-sub{margin:var(--space-5) 0}
.acct-or{display:flex;align-items:center;gap:10px;margin:var(--space-5) 0;color:var(--muted);
  font-size:11.5px;text-transform:uppercase;letter-spacing:.08em}
.acct-or:before,.acct-or:after{content:"";flex:1;height:1px;background:var(--line)}
.acct-google{display:flex;align-items:center;justify-content:center;gap:9px}
.acct-links{display:flex;flex-wrap:wrap;gap:14px;margin:14px 0 0;font-size:13px}
.acct-links button{background:none;border:0;padding:0;font:inherit;font-size:13px;
  color:var(--signal-ink);text-decoration:underline;cursor:pointer}
.acct-inline{background:none;border:0;padding:0;font:inherit;font-size:12.5px;
  color:var(--signal-ink);text-decoration:underline;cursor:pointer;margin-left:6px}
.acct-msg{margin:12px 0 0;font-size:13px;line-height:1.5}
.acct-msg.err{color:var(--warn)}
.acct-msg.ok{color:var(--signal-ink);font-weight:600}
.acct-err{margin:12px 0 0;padding:9px 11px;border-radius:3px;font-size:13px;
  background:rgba(193,75,82,.13);border:1px solid rgba(193,75,82,.4)}
/* Signed-in: the account facts. */
.acct-facts{list-style:none;margin:0;padding:0;font-size:14px}
.acct-facts li{display:flex;flex-wrap:wrap;gap:8px;justify-content:space-between;padding:9px 0;
  border-bottom:1px solid var(--line)}
.acct-facts li:last-child{border-bottom:none}
.acct-facts .k{color:var(--muted)}
.acct-facts .v{font-weight:500;text-align:right}
.acct-badge{display:inline-block;padding:1px 7px;border-radius:2px;font-size:11px;font-weight:700;
  letter-spacing:.03em;text-transform:uppercase;vertical-align:1px}
.acct-badge.ok{background:var(--signal);color:var(--on-signal)}
.acct-badge.no{background:var(--panel-2);color:var(--muted);border:1px solid var(--line)}
/* The alerts list. A paused alert is visibly muted. */
.acct-alerts{list-style:none;margin:0;padding:0}
.acct-alerts li{border-top:1px solid var(--line);padding:13px 0;display:flex;gap:12px;
  align-items:flex-start;justify-content:space-between;flex-wrap:wrap}
.acct-alerts li:first-child{border-top:none}
.acct-alerts .a-name{font-weight:600;font-size:14px}
.acct-alerts .a-desc{color:var(--muted);font-size:12.5px;margin-top:2px}
.acct-alerts li.paused .a-name,.acct-alerts li.paused .a-desc{opacity:.5}
.acct-alerts .a-ctrls{display:flex;gap:12px;align-items:center;flex:0 0 auto}
.acct-alerts .a-ctrls button{background:none;border:0;padding:0;font:inherit;font-size:12.5px;
  color:var(--signal-ink);text-decoration:underline;cursor:pointer}
.acct-alerts .a-ctrls button.a-del{color:var(--muted)}
/* The one control on a downgraded row. It sits where "Pause" sits on an
   active one, because it is the same kind of thing: the switch that turns
   this alert back on. */
.acct-alerts .a-ctrls .a-reactivate{font-size:12.5px;color:var(--signal-ink);text-decoration:underline}
.acct-empty{color:var(--muted);font-size:14px;margin:0}
.acct-sessions{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px}
/* Advanced, deliberately de-emphasised: collapsed, muted, at the very bottom. */
.acct-adv{margin-top:28px;border-top:1px solid var(--line);padding-top:6px}
.acct-adv>summary{cursor:pointer;list-style:none;padding:10px 0;font-size:12.5px;color:var(--muted);
  display:flex;align-items:center;gap:8px}
.acct-adv>summary::-webkit-details-marker{display:none}
.acct-adv>summary::before{content:"+";font-family:var(--mono);color:var(--muted)}
.acct-adv[open]>summary::before{content:"−"}
.acct-adv .acct-danger{background:none;border:0;padding:0;font:inherit;font-size:13px;
  color:var(--warn);text-decoration:underline;cursor:pointer}
.acct-adv .note{margin:6px 0 14px}

/* ---- the plan card on the account hub -------------------------------- *
 * Painted by accountPage() in /alerts.js from /api/auth/me. One panel, so a
 * reader can see what they are on and what runs out when, without reading the
 * price list to work it out. */
.acct-plan{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 12px;margin:0 0 10px}
.acct-plan-name{font-size:19px;font-weight:600;letter-spacing:-.01em}
.acct-plan-tag{padding:2px 8px;border-radius:2px;background:var(--signal);color:var(--on-signal);
  font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase}
.acct-plan-when{color:var(--muted);font-size:13px}
.acct-credits{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 14px;padding:0;list-style:none}
.acct-credits li{padding:4px 10px;border:1px solid var(--line);border-radius:2px;background:var(--panel-2);
  font-size:12.5px;color:var(--muted)}
.acct-credits li b{color:var(--paper);font-family:var(--mono);font-weight:600;
  font-variant-numeric:tabular-nums}
.acct-plan-btns{display:flex;flex-wrap:wrap;gap:10px}

/* "Poglej kot": the admin-only tier switch. A segmented control rather than a
   dropdown, because all four choices are worth reading at once and the one
   that is on has to be visible without opening anything. */
.acct-pv{margin:22px 0 0;padding:16px 0 0;border-top:1px solid var(--line)}
.acct-pv h3{margin:0 0 9px;font-size:11.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.acct-pv-sw{display:inline-flex;flex-wrap:wrap;border:1px solid var(--line);border-radius:3px;
  overflow:hidden;background:var(--panel-2)}
.acct-pv-sw button{appearance:none;background:none;border:none;border-right:1px solid var(--line);
  color:var(--muted);font:inherit;font-size:13px;padding:7px 14px;cursor:pointer}
.acct-pv-sw button:last-child{border-right:none}
.acct-pv-sw button:hover:not([disabled]){color:var(--paper)}
.acct-pv-sw button[aria-pressed="true"]{background:var(--signal);color:var(--on-signal);font-weight:600}
.acct-pv-sw button[disabled]{opacity:.55;cursor:default}
.acct-pv .note{margin:9px 0 0}

/* The return from Stripe, read out of ?billing= and then swept from the URL. */
.acct-toast{margin:0 0 16px;padding:11px 14px;border-radius:3px;font-size:13.5px;
  background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--signal)}
.acct-toast.no{border-left-color:var(--warn)}

/* ---- the price list (/cenik/, /en/pricing/) --------------------------- *
 * The monthly / yearly switch is a checkbox and two labels, exactly like the
 * navigation menu, so every price on the page is readable and switchable with
 * JavaScript off. The selector .plantog:checked ~ … reaches the cards because
 * the checkbox and the cards are siblings inside .p-plans; that is why the
 * markup nests the way it does. */
.p-plans{margin-top:6px}
.p-toggle{display:inline-flex;margin:18px 0 20px;border:1px solid var(--line);border-radius:3px;
  overflow:hidden;background:var(--panel)}
.p-toggle label{display:flex;align-items:center;gap:7px;padding:9px 16px;font-size:13px;font-weight:600;
  color:var(--muted);cursor:pointer;user-select:none}
.pt-save{padding:1px 6px;border-radius:2px;background:var(--panel-2);color:var(--signal-ink);
  font-size:10.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase}
.plantog:not(:checked) ~ .p-toggle .pt-a,
.plantog:checked ~ .p-toggle .pt-b{background:var(--signal);color:var(--on-signal)}
.plantog:checked ~ .p-toggle .pt-b .pt-save{background:rgba(0,0,0,.18);color:inherit}
.plantog:focus-visible ~ .p-toggle{outline:2px solid var(--signal);outline-offset:2px}
/* One of the two prices is drawn; the other is not there at all, so a screen
   reader is never read two prices for one plan. */
.plantog:not(:checked) ~ .p-cards .p-yr{display:none}
.plantog:checked ~ .p-cards .p-mo{display:none}

.p-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-3);margin:0 0 6px}
/* A floor rather than three heights. The three plans carry three, four and
   three highlights, and .p-cta's margin-top:auto only lines the buttons up
   INSIDE a card — it cannot make three cards the same height, so the row used
   to step down from left to right and the recommended plan in the middle was
   the one that looked like an afterthought. */
.p-card{display:flex;flex-direction:column;min-height:420px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--radius);padding:var(--space-5) 20px}
/* The recommendation, as a line rather than as a wash. A second panel colour
   under a whole card says "this one is different"; two pixels of the accent
   around it says "this one is the one we would pick", which is the sentence
   actually meant — and it leaves --panel-2 free to go on meaning "inset" the
   way it does everywhere else on the site. */
.p-card.p-best{border:2px solid var(--signal);background:var(--panel)}
/* The label that names the recommendation. Mono, because it is metadata about
   the card and not a word in it. */
.p-flag{margin:0 0 var(--space-2);font:600 11px/1 var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--signal)}
.p-name{font-family:var(--mono);font-size:12px;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);margin:0 0 10px}
.p-price{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
.p-amt{font-family:var(--mono);font-size:29px;font-weight:600;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums}
.p-per{font-size:12.5px;color:var(--muted)}
.p-billed{margin:4px 0 0;font-size:11.5px;color:var(--muted)}
.p-blurb{margin:12px 0 0;font-size:13.5px;color:var(--muted);line-height:1.5}
/* A grid with a real gap rather than padding on each row: the tick sits at the
   top of its line, and 5px of padding above and below every item made the
   space between two highlights depend on whether either of them had wrapped. */
.p-list{display:grid;gap:10px;margin:20px 0 var(--space-5);padding:0;list-style:none;font-size:13.5px}
.p-list li{padding:0 0 0 20px;position:relative}
.p-list li::before{content:"✓";position:absolute;left:0;color:var(--signal-ink);font-weight:700}
/* Pushed to the foot of the card so three cards of different heights still
   line their buttons up. */
.p-cta{margin-top:auto;text-align:center}
.p-cta[aria-disabled=true]{opacity:.55;pointer-events:none}
/* The one line under the button: what it costs and that it can be undone.
   Quiet on purpose — it is read after the decision is nearly made, and a
   reassurance that shouts reads as a warning. */
.p-reassure{margin:8px 0 0;font-size:11.5px;line-height:1.45;color:var(--muted);text-align:center}
.p-soon{margin-top:12px}

.p-once{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px;
  background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--signal);
  border-radius:3px;padding:18px 20px}
.p-once>div:first-child{flex:1 1 320px;min-width:0}
.p-once .p-blurb{margin-top:6px}
.p-once-buy{display:flex;align-items:center;gap:16px}
.p-once-buy .p-cta{margin-top:0}

/* The comparison. The first column is prose and must wrap; every other cell is
   short enough to keep the default nowrap, and the whole table scrolls inside
   .tw on a phone rather than pushing the page sideways. */
.matrix td:first-child,.matrix th:first-child{white-space:normal;min-width:190px}
.matrix th:not(:first-child),.matrix td:not(:first-child){text-align:center;padding-right:0;
  padding-left:12px}
.mx-y{color:var(--signal-ink);font-weight:700}
.mx-n{color:var(--muted)}

@media (max-width:760px){
  .p-cards{grid-template-columns:1fr}
  .p-once{flex-direction:column;align-items:flex-start}
  .p-once-buy{width:100%;justify-content:space-between}
}

/* ---- the alert form -------------------------------------------------- *
 * A draft, not a subscription: the radios and the button collect what the
 * reader wants watched, and /alerts.js takes it from there. Three radios
 * because the free tier carries one alert. */
.alertform{margin:14px 0 10px}
.alertform fieldset{border:0;margin:0;padding:0}
.alertform legend{padding:0;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);margin-bottom:8px}
.alertopt{display:flex;align-items:center;gap:9px;padding:7px 0;font-size:14px;cursor:pointer}
.alertopt input{accent-color:var(--signal);width:16px;height:16px;margin:0}
.alertform .button{margin-top:14px}
/* Off-screen rather than display:none — a bot that reads the computed style
   skips a hidden field and fills in one that only looks visible. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ---- the monthly digest ---------------------------------------------- *
 * Deliberately unlike the alert form it sits under: a panel with a rule
 * down its edge rather than the bare page, one field rather than three
 * radios. A reader glancing at the two should see two offers, not one
 * offer typeset twice. */
.newsletter{background:var(--panel);border:1px solid var(--line);
  border-left:3px solid var(--signal);border-radius:3px;padding:20px}
.newsletter h2{margin-bottom:10px}
.newsletter .note{margin:12px 0 0}
.nlform{margin:14px 0 0}
.nlrow{display:flex;flex-wrap:wrap;gap:10px;align-items:stretch}
.nlmail{flex:1 1 220px;min-width:0;font-family:inherit;font-size:15px;line-height:1.25;
  padding:10px 12px;color:var(--paper);background:var(--panel-2);
  border:1px solid var(--line);border-radius:3px}
.nlmail::placeholder{color:var(--muted)}
.nlrow .button{flex:0 0 auto;border:1px solid var(--signal)}
/* Reserved rather than inserted: the row must not jump when the answer lands. */
.nlmsg{margin:10px 0 0;font-size:13px;min-height:1.25em;color:var(--muted)}
.nlmsg.ok{color:var(--signal-ink);font-weight:600}
.nlmsg.err{color:var(--warn)}
.nlreveal{margin:14px 0 0;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.nlreveal .note{margin:0}

/* ---- the contact form -------------------------------------------------- *
 * One field per line rather than the newsletter's single row: a subject and
 * a message do not fit beside a button the way one email address does, and a
 * form that reflows five times as it narrows reads worse than one that never
 * tries to be a row. Reuses .button and .hp (the honeypot) as they stand. */
.ctform{margin:16px 0}
.ctform .field{margin:0 0 14px}
.ctform label{display:block;font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);margin:0 0 6px}
.ctform input[type=text],.ctform input[type=email],.ctform input[type=url],.ctform select,.ctform textarea{
  width:100%;box-sizing:border-box;font-family:inherit;font-size:15px;line-height:1.4;
  padding:10px 12px;color:var(--paper);background:var(--panel-2);
  border:1px solid var(--line);border-radius:3px}
.ctform input::placeholder,.ctform textarea::placeholder{color:var(--muted)}
.ctform textarea{min-height:120px}
.ctform .hint{font-size:13px;color:var(--muted);margin:6px 0 0}
.ctform .consent{font-size:13px;color:var(--muted);margin:0 0 14px}
.ctform .consent a{color:var(--signal-ink)}
/* Reserved rather than inserted: the form must not jump when the answer lands. */
.ctmsg{margin:12px 0 0;font-size:13px;min-height:1.25em;color:var(--muted)}
.ctmsg.ok{color:var(--signal-ink);font-weight:600}
.ctmsg.err{color:var(--warn)}

.jump{display:flex;flex-wrap:wrap;gap:4px;font-family:var(--mono);font-size:13px}
.jump a{padding:3px 8px;background:var(--panel);border:1px solid var(--line);border-radius:2px}
.alpha{margin:22px 0}
.alpha h3{margin:0 0 8px;color:var(--muted);font-family:var(--mono);font-size:13px}
.cols{list-style:none;margin:0;padding:0;columns:3;column-gap:18px;font-size:13.5px}
.cols li{break-inside:avoid;padding:2px 0}

/* ---- the homepage ------------------------------------------------------ *
 * The hero carries the lockup at reading size and the header keeps its own
 * small one: the sticky bar is navigation and the hero is the page, and the
 * two never share a screen for long. */
/* section.hero, not .hero. The hero IS the first section on the homepage, and
   the shared section:first-of-type rule that strips the rule and the padding
   off a page opener is (0,1,1) — so a bare .hero at (0,1,0) lost padding-top
   to it and had been silently rendering at zero for as long as both rules
   have existed. Matching on the element as well makes the two equal and lets
   the later one, this one, actually say what it says. */
section.hero{text-align:center;padding-block:44px var(--space-6);border-top:none}
.hero-mark{display:block;margin:0 auto 14px;height:104px;width:auto;max-width:100%}
/* 40px flat rather than a clamp that topped out at 44. The proposition is
   already the largest thing on the page at 40, and the four extra pixels were
   spent pushing the sentence that explains it further down: a headline and its
   explanation are one object, and -.025em with a 1.1 line and a 12px gap is
   what makes them read as one. */
.hero h1{margin:0 0 var(--space-3);font-size:40px;letter-spacing:-.025em;line-height:1.1}
/* 680px is a measure, not a container: the hero is centred text, and a
   centred line the full width of a 900px page is one nobody's eye can return
   from. 1.55 because this is the one paragraph on the site read before the
   reader has decided to read anything. */
.hero .lead{max-width:680px;margin:0 auto var(--space-5);font-size:17px;line-height:1.55;
  color:var(--muted)}
.hero .ctaline{justify-content:center}

/* ---- the homepage's section rhythm ------------------------------------- *
 * Every section after the hero, and only on the homepage: .hero is the first
 * child of <main> there and nowhere else, so the sibling combinator is the
 * page selector this file otherwise has no way to write. (The landing pages'
 * own opener is .ln-hero, a different class, and is not matched.)
 *
 * 48 + 28 with the hairline between them, rather than the shared 40 + 26: the
 * homepage is a stack of eleven unrelated offers and the break between two of
 * them is the only thing telling a reader they have finished one. 48 is the
 * one place on the site that spends the top of the spacing ladder, which is
 * what "major section" was supposed to mean. */
.hero ~ section{margin-top:var(--space-8)}
/* .cta and .newsletter excluded, and they are the only two: a section that
   paints its own panel already has a top edge, and giving it the page's rule
   as well draws a second line one pixel outside its own — in the wrong colour,
   because this selector outranks the class that chose the accent. Two chained
   :not() calls, one class each, rather than the newer form that takes a list
   of them: a browser that does not know the list form treats the selector as
   invalid and drops the whole rule, and with it every divider on the page. */
.hero ~ section:not(.cta):not(.newsletter){padding-top:28px;border-top:1px solid var(--line)}


/* ---- the four Pro tool landing pages ---------------------------------- *
 * /porocilo/, /kreator/, /mcp/ and /casovni-trak/ each carry a landing page
 * above the tool itself. These rules are only ever loaded with the shared
 * stylesheet, so everything here is prefixed: "ln-" for the landing blocks,
 * "smp-" for the hand-drawn listing sample. The market report's own sample
 * brings REPORT_CSS with it, inlined by the page, and is scoped under .report
 * there; the timeline's own live demo brings TIMELINE_CSS the same way,
 * prefixed "td-". */

/* The hero. Left-aligned rather than the homepage's centre: a landing page is
   read as a sales letter and a centred paragraph of forty words is read as a
   poster. */
.ln-hero{border-top:none;padding-top:16px}
.ln-hero h1{max-width:20ch;margin:0 0 .35em}
.ln-promise{max-width:62ch;font-size:16.5px;margin:0 0 20px}
.ln-cta{margin:0 0 18px}
/* Only one of the three primary buttons is shown at a time. The hidden
   attribute's own user-agent rule is display:none, and .button's
   display:inline-block beats it on specificity, so the rule is restated here
   at a weight that wins. It has to cover ALL THREE and not only the two that
   ship hidden: when /alerts.js reveals the Pro button it hides the signed-out
   one, and a rule that only knew about the two would have left both standing.
*/
.ln-cta .button[hidden]{display:none}
.ln-proof{list-style:none;display:flex;flex-wrap:wrap;gap:8px 18px;margin:0;padding:0}
.ln-proof li{font-size:12.5px;color:var(--muted);display:flex;align-items:center;gap:7px}
.ln-proof li::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--signal);flex:0 0 auto}

/* Four claims, each led by a figure. The figure is the thing the eye lands on,
   so it is set in the mono face at card size and the sentence under it is
   ordinary prose. */
/* Two by two, not auto-fit: there are always four of these, and auto-fit
   turns four into three and one, which reads as one claim that did not fit
   rather than as a fourth claim. */
.ln-bens{list-style:none;display:grid;grid-template-columns:1fr;gap:12px;margin:0;padding:0}
@media (min-width:700px){ .ln-bens{grid-template-columns:1fr 1fr} }
.ln-bens li{background:var(--panel);border:1px solid var(--line);border-radius:3px;padding:16px 16px 14px}
.ln-ben-n{font-family:var(--mono);font-size:28px;font-weight:600;letter-spacing:-.02em;
  color:var(--signal-ink);margin:0;line-height:1.1;font-variant-numeric:tabular-nums}
.ln-ben-u{font-family:var(--sans);font-size:12px;font-weight:500;color:var(--muted);
  margin-left:6px;letter-spacing:0}
.ln-bens h3{margin:8px 0 6px;font-size:15px}
.ln-bens p{font-size:13.5px;line-height:1.6;margin:0;color:var(--paper);opacity:.9}

/* The worked example, in a frame that says it is one. */
.ln-sample{margin:0;position:relative}
.ln-ribbon{position:absolute;top:-9px;left:14px;z-index:2;font-size:10.5px;font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;color:var(--on-signal);background:var(--signal);
  padding:3px 9px;border-radius:2px}
.ln-frame{border:1px solid var(--line-accent);border-radius:3px;background:var(--panel);
  max-height:min(78vh,760px);overflow:auto;overscroll-behavior:contain;padding:22px 18px 18px;
  -webkit-overflow-scrolling:touch}
.ln-frame:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
/* The scale is a transform on a wrapper rather than a font-size, so the
   document inside keeps its own proportions and its own line breaks; the
   negative margin gives the freed width back to the frame. */
.ln-scale{transform:scale(var(--ln-s,1));transform-origin:top left;
  width:calc(100% / var(--ln-s,1));margin-bottom:calc((var(--ln-s,1) - 1) * 100%)}
@media (max-width:640px){
  .ln-scale{transform:none;width:100%;margin-bottom:0}
  .ln-frame{padding:18px 12px 12px;max-height:min(70vh,640px)}
  .ln-cta .button{width:100%;justify-content:center;text-align:center;box-sizing:border-box}
}
.ln-sample figcaption{margin-top:10px}
/* The embedded report is a light document whatever the page around it is: it
   is a facsimile of a printed page, and a printed page is white. */
.ln-frame .report{background:transparent}
/* Its headings were pushed down two levels so the page keeps one outline (see
   demoteHeadings), and REPORT_CSS still styles the h1, h2 and h3 it wrote. The
   three levels the demoted copy actually uses are restated here at exactly the
   sizes that block gives them, so the facsimile still reads as the document it
   is a facsimile of. */
.ln-frame .report h3{font-size:1.6rem;line-height:1.25;margin:.2rem 0 .3rem;font-weight:600}
.ln-frame .report h4{font-size:1.15rem;margin:0 0 .6rem;font-weight:600}
.ln-frame .report h5{font-size:1rem;margin:1rem 0 .4rem;font-weight:600}

/* Who it is for. */
.ln-who{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
  gap:12px;margin:0;padding:0}
.ln-who li{border-top:2px solid var(--line-accent);padding-top:12px}
.ln-who h3{margin:0 0 6px;font-size:14.5px}
.ln-who p{font-size:13.5px;line-height:1.6;margin:0;color:var(--paper);opacity:.9}

/* The price block. Not the price list's cards: this is a summary with one
   recommended row, and the full matrix is one link away. */
.ln-prices{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px;margin:0 0 14px}
.ln-price{background:var(--panel);border:1px solid var(--line);border-radius:3px;padding:15px 16px 13px;
  display:flex;flex-direction:column}
.ln-price.best{border-color:var(--signal);box-shadow:inset 0 0 0 1px var(--signal)}
.ln-price h3{margin:0 0 8px;font-size:13px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.ln-amt{font-family:var(--mono);font-size:26px;font-weight:600;letter-spacing:-.02em;margin:0;
  line-height:1.1;font-variant-numeric:tabular-nums}
.ln-per{font-family:var(--sans);font-size:12px;font-weight:500;color:var(--muted);margin-left:6px;letter-spacing:0}
.ln-second{font-size:12px;color:var(--muted);margin:4px 0 0}
.ln-what{font-size:13px;line-height:1.55;margin:10px 0 12px;color:var(--paper);opacity:.9}
.ln-go{margin:auto 0 0;font-size:13.5px}
.ln-reassure{font-size:13.5px;color:var(--paper);opacity:.92;margin:0 0 8px}

/* The MCP transcript. A terminal by typography rather than by colour: the
   labels are small caps, the calls and the answers are mono, and the whole
   thing scrolls sideways inside its own box rather than pushing the page. */
.ln-term{font-size:13px}
.ln-term-b{padding:0 0 16px;margin:0 0 16px;border-bottom:1px solid var(--line)}
.ln-term-b:last-child{border-bottom:none;padding-bottom:0;margin-bottom:0}
.ln-term-l{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
  margin:0 0 4px;font-weight:600}
.ln-term-ask{margin:0 0 12px;font-size:14.5px}
.ln-term-ask::before{content:"› ";color:var(--signal-ink);font-family:var(--mono)}
.ln-term-c,.ln-term-o{font-family:var(--mono);font-size:12.5px;line-height:1.6;margin:0 0 12px;
  padding:10px 12px;border-radius:3px;overflow-x:auto;white-space:pre;background:var(--panel-2);
  border:1px solid var(--line)}
.ln-term-c{color:var(--signal-ink)}
.ln-term-o{color:var(--muted)}
.ln-term-say{margin:0;font-size:14px}
.ln-term-say::before{content:"⤷ ";color:var(--signal-ink)}

/* ---- the hand-drawn listing sample (/kreator/) ------------------------ *
 * A facsimile of the page a published listing renders as (listingDocument in
 * worker/listings.mjs). Not that page's own stylesheet, which sets body,
 * h1 and .card and would fight the site's: the same layout, restated
 * under one prefix so it can live inside a page that already has all three. */
.smp-listing{max-width:38rem;margin:0 auto;font-size:14.5px}
.smp-brand{display:flex;align-items:center;gap:11px;padding:0 0 12px;
  border-bottom:3px solid var(--signal);margin:0 0 16px}
.smp-mark{width:42px;height:42px;border-radius:3px;background:var(--signal);flex:0 0 auto;
  display:block;position:relative}
.smp-mark::after{content:"";position:absolute;inset:11px;border:2px solid var(--on-signal);
  border-radius:2px}
.smp-who{font-weight:600;line-height:1.3}
.smp-who small{display:block;font-weight:400;color:var(--muted);font-size:12px}
.smp-title{margin:0 0 2px;font-size:19px;line-height:1.25}
.smp-addr{color:var(--muted);margin:0 0 10px;font-size:13px}
.smp-price{font-size:22px;font-weight:700;color:var(--signal-ink);margin:0 0 16px;
  font-family:var(--mono);letter-spacing:-.02em}
.smp-price small{display:block;font-size:12px;font-weight:400;color:var(--muted);
  font-family:var(--sans);letter-spacing:0}
/* One hero and two thumbnails beside it, the shape a listing gallery takes
   everywhere. A full-width hero is what the published page uses and is wrong
   here: inside a frame a reader has not scrolled yet, it is the only thing
   they would see. */
.smp-gallery{display:grid;grid-template-columns:2fr 1fr;grid-template-rows:auto auto;
  gap:8px;margin:0 0 16px}
.smp-shot{border-radius:3px;overflow:hidden;background:var(--panel-2);aspect-ratio:4/3}
.smp-shot:first-child{grid-row:1 / span 2;aspect-ratio:auto}
.smp-photo{display:block;width:100%;height:100%}
.smp-card{background:var(--panel);border:1px solid var(--line);border-radius:3px;
  padding:13px 15px 11px;margin:0 0 10px}
.smp-card h4{margin:0 0 8px;font-size:13px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.smp-card p{margin:0 0 9px;line-height:1.6}
.smp-card p:last-child{margin-bottom:0}
.smp-short{font-weight:600}
.smp-hl{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(13rem,1fr));gap:5px}
.smp-hl li{padding-left:15px;position:relative;line-height:1.5}
.smp-hl li::before{content:"";position:absolute;left:0;top:.62em;width:6px;height:6px;
  border-radius:50%;background:var(--signal)}
.smp-facts{width:100%;border-collapse:collapse}
.smp-facts th{text-align:left;font-weight:400;color:var(--muted);padding:4px 0;width:48%}
.smp-facts td{text-align:right;padding:4px 0}
.smp-reach{color:var(--muted);font-size:13px}
.smp-tags{color:var(--muted);font-size:13px;margin:0;overflow-wrap:anywhere}
@media (max-width:520px){ .smp-gallery{grid-template-columns:1fr 1fr}
  .smp-shot:first-child{grid-row:auto;grid-column:1/-1;aspect-ratio:4/3} }

/* ---- the homepage ------------------------------------------------------ *
 * Eight blocks, in one vocabulary. Everything below is prefixed by the block
 * it belongs to, because the homepage is the one page on the site whose
 * markup nothing else reuses, and an unprefixed .card here would be a rule
 * that reaches into forty other pages.
 *
 * The rhythm is 64px on a phone and 96px on a desktop, against the 40/48 the
 * rest of the site keeps. It is the widest gap anywhere here and it is
 * deliberate: eight unrelated offers in a column need the break between two of
 * them to be unmistakable, and a reader scrolling a homepage is scanning, not
 * reading. The hairline over each one does the same job for anybody who cannot
 * see the space.
 * ----------------------------------------------------------------------- */

/* The hero. Taller than the shared one — this is the only page where the top
   of the screen has to carry a proposition, a field and a line of provenance
   without any of them touching. The h1 is capped at a measure rather than the
   page: at 40px the proposition runs the full 860 and reads as a banner. */
section.home-hero{padding-block:56px var(--space-6)}
.home-hero h1{max-width:19ch;margin-inline:auto;text-wrap:balance}
.home-hero .lead{margin-bottom:var(--space-5)}

/* The one field. Shaped like the chat's composer, because it is the same act:
   whatever is typed here decides which of two applications opens. */
.hsearch{display:flex;gap:var(--space-2);align-items:center;max-width:640px;margin:0 auto;
  min-height:52px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:5px;box-shadow:var(--shadow);text-align:left;transition:var(--tx)}
.hsearch:focus-within{border-color:var(--signal)}
.hsearch-in{flex:1;min-width:0;border:0;background:transparent;color:var(--paper);
  font:inherit;font-size:16px;padding:10px var(--space-3);outline:none}
.hsearch-in::placeholder{color:var(--muted);opacity:1}
/* Safari draws its own clear button inside a type=search, in its own grey, at
   its own size. The field already has a visible submit beside it. */
.hsearch-in::-webkit-search-cancel-button{-webkit-appearance:none}
.hsearch .button{flex:0 0 auto}
/* The phone keeps the row rather than stacking into two full-width bars: the
   field grows to the platform's comfortable 48 and stays at 16px so iOS does
   not zoom the page on focus, and the button keeps a floor wide enough for
   the longest word it carries. */
@media (max-width:520px){
  .hsearch{gap:5px}
  .hsearch-in{min-height:48px;padding:12px 14px;font-size:16px}
  .hsearch .button{width:auto;min-width:104px;padding-inline:var(--space-3)}
}

/* Three quiet ways on, for a reader who did not come with a question. Pills
   rather than buttons: a button beside the field would compete with it. */
.hchips{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-2);
  margin:var(--space-4) 0 0}
.hchip{display:inline-flex;align-items:center;gap:6px;padding:6px 13px;font-size:13.5px;
  font-weight:500;color:var(--paper);background:var(--panel);border:1px solid var(--line);
  border-radius:999px;transition:var(--tx)}
.hchip:hover{border-color:var(--signal);color:var(--signal-ink);text-decoration:none}
.hchip svg{flex:0 0 auto;color:var(--signal)}
/* Set in mono, like every other stamp on this site that names a source and a
   date rather than saying something. */
.trustline{margin:var(--space-4) 0 0;font-family:var(--mono);font-size:11.5px;
  letter-spacing:.01em;color:var(--muted)}

/* The same field again, slim, under the header once the hero has gone.
   position:fixed rather than sticky: it is outside the flow entirely, so it
   can appear and disappear without moving a pixel of the page behind it. Under
   the header's own z-index, so it slides beneath rather than over it. */
.hsticky{position:fixed;left:0;right:0;top:60px;z-index:19;padding:var(--space-2) 0;
  background:var(--panel);border-bottom:1px solid var(--line);box-shadow:var(--shadow)}
.hsticky[hidden]{display:none}
/* Under the admin plan-preview strip, the same 30px everything else shifts. */
html.ds-pv-on .hsticky{top:90px}
.hsearch.mini{min-height:40px;box-shadow:none;padding:3px}
.hsearch.mini .hsearch-in{min-height:0;font-size:15px;padding:7px var(--space-3)}
@media (max-width:520px){
  .hsearch.mini .hsearch-in{min-height:34px;font-size:16px;padding:6px 10px}
  .hsearch.mini .button{min-width:0;padding-inline:14px}
}

/* The homepage's own section rhythm, replacing the shared 48 + 28. Written
   against .home-hero rather than .hero so the two rules are the same weight
   and the later one — this one — is the one that applies. */
.home-hero ~ section{margin-top:64px}
.home-hero ~ section:not(.cta):not(.newsletter){padding-top:32px;border-top:1px solid var(--line)}
@media (min-width:900px){
  .home-hero ~ section{margin-top:96px}
  .home-hero ~ section:not(.cta):not(.newsletter){padding-top:40px}
  /* The section right after the hero is the one exception: the hero already
     ends in a full-width line (the trust stamp), so the reader has just
     finished reading when the rule arrives, and the standard 96 + 40 reads as
     a blank screen between two things that are still part of one thought.
     Trimmed, together with the hero's own bottom padding just below, to 64px
     of total air between the trust line and the next heading. Every section
     after this first one keeps the full 96 + 40 rhythm above. */
  section.home-hero{padding-bottom:var(--space-4)}
  .home-hero + section{margin-top:var(--space-6)}
  .home-hero + section:not(.cta):not(.newsletter){padding-top:var(--space-4)}
}

/* ---- 2. the five questions -------------------------------------------- */
.asks{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
  gap:var(--space-3);padding:0;margin:var(--space-5) 0 0}
.askcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--space-4) var(--space-4) var(--space-3);display:flex;flex-direction:column}
.askcard-i{display:flex;align-items:center;justify-content:center;width:36px;height:36px;
  flex:0 0 auto;border-radius:var(--radius);background:var(--panel-2);color:var(--signal-ink);
  margin-bottom:var(--space-3)}
.askcard h3{margin:0 0 7px;font-size:15px}
.askcard p{margin:0 0 10px;font-size:13.5px;line-height:1.55;color:var(--paper);opacity:.88}
/* The one number each card is allowed. Mono, because it is a count and not a
   sentence, and because the live half arrives on its own line underneath. */
.askcard-n{margin:0 0 var(--space-3);font-family:var(--mono);font-size:11.5px;line-height:1.5;
  color:var(--muted);opacity:1}
.askcard-live{display:block}
.askcard-live[hidden]{display:none}
.askcard-go{display:flex;flex-wrap:wrap;gap:2px 14px;margin:auto 0 0;font-size:13px;
  font-weight:500;opacity:1}
.askcard-go a::after{content:" →";font-family:var(--mono)}
.askcard-more{color:var(--muted);font-weight:400}
.askcard-more::after{content:none}
/* Five cards, and auto-fit gives three columns from 900px up — which leaves a
   hole in the second row where a sixth card would go. Six tracks instead: the
   first three cards take two each, the last two take three each, and the
   second row is full rather than half empty. */
@media (min-width:900px){
  .asks{grid-template-columns:repeat(6,1fr)}
  .askcard{grid-column:span 2}
  .askcard:nth-child(4),.askcard:nth-child(5){grid-column:span 3}
}

/* ---- 3. the map, as a picture ----------------------------------------- */
/* The frame carries its own intrinsic ratio (the <img> below has width and
   height, so the box never resizes when the picture arrives) but sits right
   below the fold, and a lazy-loaded image is guaranteed to still be a flat
   rectangle the instant the reader scrolls this far. A diagonal two-tone
   wash rather than a flat fill: a placeholder, not a hole in the page. It is
   fully covered the moment the picture paints, so nothing here ever animates
   or competes with it. */
.mapshow-frame{display:block;position:relative;margin:var(--space-5) 0 0;
  background:linear-gradient(135deg,var(--panel-2) 0 42%,var(--panel) 50%,var(--panel-2) 58% 100%);
  border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;transition:var(--tx)}
.mapshow-frame:hover{border-color:var(--signal)}
.mapshow-frame video{display:block;width:100%;height:auto;pointer-events:none;background:transparent}
.mapshow-open{position:absolute;inset:0;z-index:1;display:block;text-decoration:none}
.mapshow-go{position:absolute;right:12px;bottom:12px;display:inline-flex;align-items:center;
  padding:7px 14px;font-size:13px;font-weight:600;color:var(--on-signal);background:var(--signal);
  border-radius:var(--radius)}
/* The pause toggle: the opposite corner from "open the map", above the
   overlay link in stacking order so its own small hit area never triggers
   the bigger one underneath. It is a real <button>, not a link, because it
   does not go anywhere — it only starts and stops the recording. */
.mapshow-toggle{position:absolute;left:12px;bottom:12px;z-index:2;display:inline-flex;
  align-items:center;padding:7px 12px;font:inherit;font-size:13px;font-weight:600;
  color:var(--paper);background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius);cursor:pointer;transition:var(--tx)}
.mapshow-toggle:hover{border-color:var(--signal);color:var(--signal-ink)}
.mapshow-toggle:focus-visible{outline:2px solid var(--signal-ink);outline-offset:2px}
.mapchips{list-style:none;display:flex;flex-wrap:wrap;gap:var(--space-2);padding:0;
  margin:var(--space-3) 0 0}
.mapchips a{display:inline-flex;align-items:center;padding:5px 12px;font-size:13px;
  color:var(--paper);background:var(--panel);border:1px solid var(--line);border-radius:999px;
  transition:var(--tx)}
.mapchips a:hover{border-color:var(--signal);color:var(--signal-ink);text-decoration:none}

/* ---- 4. the four readers ---------------------------------------------- */
/* Two by two rather than a row of four. Four across at this page width gives
   each card 206px, which turns every one of the twelve steps into three lines
   and leaves the three short cards stretched to the tall one's height with a
   hand's width of nothing under them. Two across fits a step on one line. */
.personas{list-style:none;display:grid;grid-template-columns:1fr;gap:var(--space-3);
  padding:0;margin:var(--space-5) 0 0}
@media (min-width:520px){ .personas{grid-template-columns:repeat(2,1fr)} }
.persona{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--space-4)}
.persona h3{margin:0 0 var(--space-2);font-size:15px}
.persona-p{margin:0 0 var(--space-3);font-size:13px;line-height:1.5;color:var(--muted)}
.psteps{list-style:none;display:grid;gap:9px;margin:0;padding:0}
.psteps li{display:flex;align-items:flex-start;gap:9px;font-size:13.5px;line-height:1.45}
.pstep-n{flex:0 0 auto;width:18px;height:18px;display:inline-flex;align-items:center;
  justify-content:center;font-family:var(--mono);font-size:10.5px;line-height:1;color:var(--muted);
  border:1px solid var(--line);border-radius:999px}
.persona-more{display:flex;flex-wrap:wrap;gap:4px 12px;margin:var(--space-3) 0 0;font-size:12.5px}
.persona-more a{color:var(--muted)}
.persona-more a:hover{color:var(--signal-ink)}

/* ---- 5. the new-build strip -------------------------------------------
   The skeletons are the cards, minus their content: same grid, same box, same
   4:3 picture well, so the row that arrives from /api/projects lands in the
   space the row that was drawn at build time already held. */
.ngrow{list-style:none;display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-3);
  padding:0;margin:var(--space-5) 0 var(--space-4)}
@media (min-width:560px){ .ngrow{grid-template-columns:repeat(3,1fr)} }
.ngcard{display:flex;flex-direction:column;gap:6px;padding-bottom:10px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;color:inherit;
  text-decoration:none;transition:var(--tx)}
a.ngcard:hover{border-color:var(--signal);text-decoration:none}
.ngcard-img{display:block;aspect-ratio:4/3;background:var(--panel-2);overflow:hidden}
.ngcard-img img{display:block;width:100%;height:100%;object-fit:cover}
.ngcard-t{display:block;padding:0 10px;font-size:13px;font-weight:600;line-height:1.3}
.ngcard-m{display:block;padding:0 10px;font-size:11.5px;line-height:1.35;color:var(--muted)}
.ngcard.skel .ngcard-t{height:13px;margin:2px 10px 0;padding:0;background:var(--panel-2);
  border-radius:2px}
.ngcard.skel .ngcard-m{height:11px;width:65%;margin:4px 10px 0;padding:0;background:var(--panel-2);
  border-radius:2px}

/* ---- 6. the market in numbers ------------------------------------------
   Five tiles, two-up on a phone and five across once there is room for five.
   Every one of them is a link to the page the figure was computed on, which is
   what .card.fact has always been. */
/* auto-fit rather than five fixed columns, and this is the one grid on the
   page where that is the right answer: the fifth tile is the live one and is
   drawn hidden, so a fixed five-column track list leaves a tile-shaped hole on
   the right whenever the act register does not answer. auto-fit collapses the
   empty track and the four that are left spread to fill the row.
   140 is the floor because .card-v never wraps and the longest value the row
   carries is a €/m² figure at 18px mono, which needs about 100. */
.cards.homenums{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--space-3);
  margin:var(--space-5) 0 var(--space-3)}
.cards.homenums .card{min-width:0;padding:var(--space-4)}
.cards.homenums .card-v{font-size:18px}

/* A stat card that is a link: same box, and it says so on hover. */
.card.fact{text-decoration:none;color:inherit;transition:var(--tx)}
.card.fact[hidden]{display:none}
.card.fact:hover{border-color:var(--line-accent);background:var(--panel-2);text-decoration:none}
.card.fact .card-l,.card.fact .card-v,.card.fact .card-h{display:block}
.card.fact .card-u{display:inline}
.card.fact .card-h{margin-top:auto;padding-top:6px}

/* ---- the pricing page's own tool cards ---------------------------------
   homeTools(): the four Pro tools, on /cenik/ alone now that the homepage's
   own tools section reads TOOLS instead (see .toolgrid below). */
.home-tools{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:var(--space-3);margin:var(--space-5) 0 var(--space-4);padding:0}
.home-tools li{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:15px 16px 13px;display:flex;flex-direction:column}
.home-tools h3{margin:0 0 7px;font-size:15px}
.home-tools p{font-size:13.5px;color:var(--paper);opacity:.9;margin:0 0 10px;line-height:1.55}
.home-tool-p{margin:auto 0 0;font-size:12px;color:var(--muted);opacity:1;
  border-top:1px solid var(--line);padding-top:9px}

/* ---- the tool registry's own card: /orodja/ and the homepage's flagship
   section (toolCard() in gen-pages.mjs). A whole-card link rather than a
   linked heading over a paragraph, the way .card.fact above is: the name (and
   its badge, where TOOLS gives it one) and the question the tool answers. */
.toolgrid{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  grid-auto-rows:1fr;gap:var(--space-3);margin:var(--space-5) 0 var(--space-4);padding:0}
/* The grid stretches the li, not the anchor inside it: without this a
   one-line card sits shorter than its two-line neighbour in the same row. */
.toolgrid li{display:flex}
.toolcard{flex:1;display:flex;flex-direction:column;gap:6px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--radius);padding:15px 16px 14px;
  color:inherit;text-decoration:none;transition:var(--tx)}
.toolcard:hover{border-color:var(--line-accent);background:var(--panel-2);text-decoration:none}
.toolcard-t{display:flex;align-items:center;gap:6px;font-size:15px;font-weight:600;line-height:1.3}
.toolcard-p{font-size:13.5px;color:var(--paper);opacity:.9;margin:0;line-height:1.55}
.toolbadge{display:inline-flex;align-items:center;gap:3px;padding:1px 5px;border-radius:2px;
  background:var(--panel-2);color:var(--muted);font-size:10px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase}
.toolbadge svg{width:10px;height:10px;flex:0 0 auto}

/* ---- homepage choropleth ---------------------------------------------- */
.choro-lead{color:var(--paper);opacity:.92;margin:0 0 16px}
.choro-fig{margin:0;position:relative}
.choro-map{display:block;width:100%;height:auto;max-height:74vh}
.choro-map .ch{fill:var(--choro-0);stroke:var(--choro-stroke);stroke-width:.6;
  stroke-linejoin:round;vector-effect:non-scaling-stroke;transition:fill .12s ease}
.choro-map .ch.q1{fill:var(--choro-1)} .choro-map .ch.q2{fill:var(--choro-2)}
.choro-map .ch.q3{fill:var(--choro-3)} .choro-map .ch.q4{fill:var(--choro-4)}
.choro-map .ch.q5{fill:var(--choro-5)}
.choro-map a{cursor:pointer;outline:none}
.choro-map a:hover .ch,.choro-map a:focus-visible .ch{stroke:var(--signal);stroke-width:2;
  filter:brightness(1.06)}
.choro-map .ch-hl{fill:none;stroke:var(--signal);stroke-width:2;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;pointer-events:none}
.choro-map a:focus-visible{outline:none}
@media (prefers-reduced-motion:reduce){ .choro-map .ch{transition:none} }

.choro-legend{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;margin:14px 0 4px}
.ch-ramp{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);font-family:var(--mono)}
.ch-steps{display:flex}
.ch-sw{display:inline-block;width:22px;height:12px;border:1px solid var(--choro-stroke)}
.ch-steps .ch-sw:not(:first-child){border-left:0}
.ch-sw.q0{fill:var(--choro-0);background:var(--choro-0)} .ch-sw.q1{background:var(--choro-1)}
.ch-sw.q2{background:var(--choro-2)} .ch-sw.q3{background:var(--choro-3)}
.ch-sw.q4{background:var(--choro-4)} .ch-sw.q5{background:var(--choro-5)}
.ch-nodata{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted)}
.ch-nodata .ch-sw{width:14px}

.choro-tip{position:absolute;transform:translate(-50%,-100%);pointer-events:none;z-index:3;
  background:var(--panel);color:var(--paper);border:1px solid var(--line-accent);border-radius:3px;
  padding:5px 9px;font-size:12.5px;line-height:1.3;white-space:nowrap;box-shadow:var(--shadow);
  max-width:min(70vw,260px);overflow:hidden;text-overflow:ellipsis}
.choro-tip[hidden]{display:none}

/* ---- dearest / cheapest ranking panels --------------------------------- */
.rank-panes{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.rank-pane{margin:0;border:1px solid var(--line);border-radius:3px;background:var(--panel);overflow:hidden}
.rank-h{margin-top:0;padding:12px 14px;border-bottom:1px solid var(--line);background:var(--panel-2)}
.rank-h h3{margin:0;font-size:15px}
.rank-h p{margin:2px 0 0;font-size:12px;color:var(--muted)}
.rank-list{list-style:none;margin:0;padding:6px 14px 12px}
.rank-list li{display:grid;grid-template-columns:18px minmax(72px,1fr) minmax(0,1.5fr) auto;
  align-items:center;gap:4px 10px;padding:5px 0;font-size:13px}
.rk-n{font-family:var(--mono);font-size:11px;color:var(--muted);text-align:right;
  font-variant-numeric:tabular-nums}
.rank-list .rk-m{color:var(--paper);text-decoration:none;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.rank-list .rk-m:hover{text-decoration:underline}
.rk-bar{display:block;height:9px;border-radius:2px;background:var(--panel-2);overflow:hidden}
.rank-pane .rk-bar{background:var(--accent-soft)}
.rk-bar i{display:block;height:100%;border-radius:0 2px 2px 0}
.rank-list.dear .rk-bar i{background:var(--choro-5)}
.rank-list.cheap .rk-bar i{background:var(--choro-2)}
.rk-v{font-family:var(--mono);font-size:12px;color:var(--paper);text-align:right;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.rk-d{grid-column:3 / -1;font-family:var(--mono);font-size:11px;color:var(--muted);
  text-align:right;font-variant-numeric:tabular-nums;margin-top:-3px}
.rank-panes.one{grid-template-columns:1fr;max-width:560px}
.rank-list li.rk-home .rk-m{font-weight:600}
.rank-list li.rk-home .rk-v{font-weight:600}
.rank-list li.rk-home::before{content:"";position:absolute;left:-14px;width:3px;height:18px;
  background:var(--signal);border-radius:2px}
.rank-list li{position:relative}
.eu-table td:first-child,.eu-sources td:first-child{white-space:nowrap}
.eu-table tr.eu-home td{background:var(--accent-soft)}
.eu-table tr.eu-home td:first-child{font-weight:600}
.eu-table tr.eu-group td{color:var(--muted);font-style:italic}
.eu-sources code{font-family:var(--mono);font-size:12px}

@media (max-width:720px){
  .rank-panes{grid-template-columns:1fr}
  .rank-list li{grid-template-columns:18px minmax(60px,1fr) minmax(0,1.1fr) auto}
}

/* ---- the MCP page ------------------------------------------------------ */
.mcp-code{font-family:var(--mono);font-size:12.5px;line-height:1.55;background:var(--panel);
  border:1px solid var(--line);border-radius:3px;padding:12px 14px;margin:0 0 16px;
  overflow-x:auto;white-space:pre}
.mcp-code code{font:inherit;color:inherit}
.mcp-tools{list-style:none;margin:0 0 16px;padding:0}
.mcp-tools li{padding:8px 0;border-bottom:1px solid var(--line);display:flex;flex-wrap:wrap;gap:4px 10px;
  align-items:baseline}
.mcp-tools code{font-family:var(--mono);font-size:13px;font-weight:600;white-space:nowrap}
.mcp-tools span{color:var(--muted);flex:1 1 16rem;min-width:0}
.mcp-ex{margin:0 0 16px;padding-left:22px}
.mcp-ex li{margin:0 0 8px;font-style:italic;color:var(--muted)}

/* ---- the Donos section's place table, and the gate over it ------------ *
 * The masked rows are bars and nothing else. No blur, and deliberately: a
 * blur is a CSS property that anybody can switch off in a devtools panel, so
 * a masked figure would be a figure that is published and merely inconvenient
 * to read. These rows hold no number at all. What they carry is the SHAPE of
 * the list, so a municipality with forty settlements does not look like one
 * with three, and the sentence under them carries the count. */
/* "dn" for donos, and not "yl": .yl is the y-axis label a chart hangs off its
   own plot, position:absolute at left:-46px, and a second .yl rule would have
   put this whole block forty pixels off the left edge of the page. It did,
   once. */
.dn{margin:18px 0 0}
.dn h3{font-size:15px;margin:0 0 4px}
.dn .tw{margin-top:10px}
.dn-t td:first-child{white-space:normal}
.dn-mask td{padding-top:11px;padding-bottom:11px}
.dn-bar{display:block;height:8px;border-radius:2px;
  background:linear-gradient(90deg,var(--line) 0%,var(--panel-2) 60%,var(--line) 100%);opacity:.8}
.dn-mask td:first-child .dn-bar{width:78%}
.dn-mask td:nth-child(2) .dn-bar{width:44%}
.dn-mask td:nth-child(3) .dn-bar{width:56%}
.dn-mask td:nth-child(4) .dn-bar{width:50%}
.dn-mask td:nth-child(5) .dn-bar{width:38%}
.dn-gate{margin:12px 0 0}
.dn-count{margin:0 0 10px;font-size:13px;color:var(--muted)}
.dn-up:empty{display:none}

/* ---- /primerjava/ ------------------------------------------------------ *
 * A picker, a table and a link. The table is the page, so it is the thing
 * that gets the room: the picker is one field and one line of count, and the
 * upgrade card only ever appears under it, never over the numbers. */
.cmp{margin:22px 0 0}
.cmp-pick{position:relative;max-width:460px;margin:0 0 20px}
.cmp-lab{display:block;font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--muted);font-weight:500;margin:0 0 6px}
.cmp-q{width:100%;font:inherit;font-size:15px;padding:9px 11px;border:1px solid var(--line);
  border-radius:3px;background:var(--panel);color:var(--paper)}
.cmp-q:focus-visible{outline:2px solid var(--signal);outline-offset:1px}
.cmp-q[aria-disabled=true]{opacity:.6}
.cmp-opts{position:absolute;z-index:6;left:0;right:0;margin:2px 0 0;padding:0;list-style:none;
  background:var(--panel);border:1px solid var(--line);border-radius:3px;max-height:290px;overflow:auto;
  box-shadow:0 6px 20px rgba(0,0,0,.16)}
.cmp-opt{display:flex;align-items:baseline;justify-content:space-between;gap:10px;width:100%;
  background:none;border:none;border-bottom:1px solid var(--line);font:inherit;text-align:left;
  padding:9px 11px;cursor:pointer;color:var(--paper)}
.cmp-opts li:last-child .cmp-opt{border-bottom:none}
.cmp-opt:hover{background:var(--panel-2)}
.cmp-opt[aria-disabled=true]{cursor:not-allowed;color:var(--muted)}
.cmp-optn{font-size:14.5px}
.cmp-optk{font-size:11.5px;color:var(--muted);white-space:nowrap}
.cmp-count{margin:8px 0 0;font-size:12.5px;color:var(--muted)}
.cmp-empty{margin:0;font-size:14px;color:var(--muted)}
/* Row headings on the left, one column per place. The first column stays
   readable at any width; the value cells are mono so four of them line up as
   numbers rather than as text that happens to be numeric. */
.cmp-t th[scope=row]{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:500;
  white-space:normal;padding-right:16px;vertical-align:top}
.cmp-t th[scope=col]{font-size:13.5px;text-transform:none;letter-spacing:0;
  color:var(--paper);font-weight:600;white-space:normal;padding-right:16px;vertical-align:bottom}
.cmp-name{display:inline-flex;align-items:baseline;gap:5px}
.cmp-t td{font-family:var(--mono);font-size:13px;vertical-align:top;white-space:nowrap}
.cmp-par{display:block;font-size:11px;color:var(--muted);font-weight:400}
.cmp-stat{display:block;font-size:11px;font-weight:400;margin-top:2px}
.cmp-n{display:block;font-family:var(--sans);font-size:11px;color:var(--muted);white-space:nowrap}
.cmp-dash{color:var(--muted)}
.cmp-x{background:none;border:none;color:var(--muted);
  font-size:17px;line-height:1;padding:0 2px;cursor:pointer}
.cmp-x:hover{color:var(--paper)}
.cmp-x:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
.cmp-spark{display:block;color:var(--signal-ink)}
.cmp-spark svg{display:block;width:96px;height:26px}
.cmp-sparkt{display:block;font-family:var(--sans);font-size:11px;color:var(--muted);margin-top:3px}
.cmp-share{margin:14px 0 0}
@media (max-width:560px){
  .cmp-t th[scope=row]{font-size:12px}
  .cmp-t td{font-size:12.5px}
}

/* ---- standing pages --------------------------------------------------- */
.formula{font-family:var(--mono);font-size:13.5px;background:var(--panel);border:1px solid var(--line);
  border-radius:3px;padding:12px 14px;overflow-x:auto;white-space:nowrap}
.cite{font-family:var(--mono);font-size:12.5px;background:var(--panel-2);padding:2px 6px;border-radius:2px}
.sources{margin:0 0 14px;padding-left:22px;font-size:14px}
.sources li{margin:0 0 12px;line-height:1.55}
.notfound section{border-top:none;padding-top:0;margin:34px 0}
.notfound section+section{border-top:1px solid var(--line);padding-top:32px;margin-top:44px}
.notfound h1{font-size:clamp(22px,4.6vw,29px)}
.notfound h2{margin-top:26px}

/* ---- share ------------------------------------------------------------ */
.share{display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin:38px 0 0;padding-top:20px;
  border-top:1px solid var(--line)}
.share-l{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);
  font-weight:500;margin-right:3px}
.sh{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 9px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);color:var(--muted);
  font-size:12.5px;font-family:inherit;line-height:1;cursor:pointer;text-decoration:none;
  transition:var(--tx)}
.sh:hover{text-decoration:none;color:var(--paper);border-color:var(--line-accent);background:var(--panel-2)}
.sh svg{width:15px;height:15px;fill:currentColor;flex:0 0 auto;display:block}
.sh[hidden]{display:none}
.sh-t{white-space:nowrap}
.sh-fb:hover{color:#1877f2;border-color:#1877f2}
.sh-x:hover{color:var(--paper);border-color:var(--paper)}
.sh-li:hover{color:#0a66c2;border-color:#0a66c2}
.sh-wa:hover{color:#1da851;border-color:#1da851}
.sh-vb:hover{color:#7360f2;border-color:#7360f2}

/* The standing way into the chat, floating bottom-right on every content page.
   Three pixels and the shared shadow, not a pill: a full-radius control is the
   shape a third-party widget takes — the support bubble, the cookie badge —
   and this one is ours. It is the same control, and now the same shape, as
   the map's own #aiFab. Circles stay reserved for icon buttons and map
   markers, which this is neither: it carries a word. */
.aifab{position:fixed;right:16px;bottom:calc(16px + env(safe-area-inset-bottom,0px));z-index:640;
  display:inline-flex;align-items:center;gap:8px;min-height:var(--control-h);padding:9px 14px;
  border-radius:var(--radius);
  border:1px solid var(--signal);background:var(--signal);color:var(--on-signal);text-decoration:none;
  font-size:13.5px;font-weight:600;box-shadow:var(--shadow)}
.aifab:hover{filter:brightness(1.06);color:var(--on-signal)}
.aifab:focus-visible{outline:2px solid var(--signal-ink);outline-offset:3px}
html.ds-navopen .aifab{display:none}
/* Out of the way of a table that scrolls sideways: on a phone the pill sits
   exactly where such a table keeps its last column and its scroll thumb, and
   content scrolls UNDER a fixed element, so no amount of page padding moves
   it off. visibility rather than opacity alone, so it leaves the tab order
   while it is gone. See wideTables() in /alerts.js. */
.aifab{transition:opacity .18s ease,transform .18s ease,visibility .18s}
.aifab.aifab-away,.aifab.fab-hidden{opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none}
@media (prefers-reduced-motion:reduce){.aifab{transition:none}}
@media (max-width:560px){.aifab{padding:10px 13px;font-size:13px}}
@media print{.aifab{display:none}}
.foot{border-top:1px solid var(--line);background:var(--panel);padding:32px 0 40px;font-size:12.5px;
  color:var(--muted);line-height:1.7}
.foot a{color:var(--muted);text-decoration:underline}
.foot .stamp{margin:0;opacity:.75}

/* Four columns on a desktop, two on a tablet, one per row on a phone. One
   grid and two media queries do all three; the markup never changes, so a
   column that grows a link grows it in every layout at once. minmax(0,1fr)
   rather than 1fr because a long link label in a grid track that cannot
   shrink below its content is what pushes a footer wider than the page. */
.footcols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:24px 28px;
  margin:0 0 28px;align-items:start}
.footcol h2{margin:0 0 10px;font-size:11.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--paper)}
.footcol ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px;font-size:13px}
.footcol li{margin:0}
.footnav a{color:var(--signal-ink);text-decoration:none}
.footnav a:hover{text-decoration:underline}
/* The footer sits on --panel, where the global 2px outline is thin against a
   link that is already coloured. Spelled out here so a keyboard reader can
   see which of twenty links they are on. */
.footnav a:focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:2px}
.footsrc{margin:16px 0 0;font-size:12px;line-height:1.65}
.footsrc a{color:var(--muted)}

/* The bottom bar: the mark, then the three lines of small print. Stacked
   under each other once there is no room to sit them side by side. */
.footbar{display:flex;gap:22px;align-items:flex-start;border-top:1px solid var(--line);padding-top:20px}
.footbar .brand{flex:0 0 auto;margin:0}
.footbar-t{flex:1 1 auto;min-width:0}
.footbar-t p{margin:0 0 7px}
.footbar-t p:last-child{margin:0}
.footco{color:var(--paper);font-weight:600}
/* The row of marks, last in the bar. A 36px target around a 17px drawing, so
   the two icons are as pressable as the twenty worded links above them, and
   in the same muted ink until the pointer is on one. */
.footsoc{list-style:none;margin:0;padding:0;display:flex;gap:6px;
  flex:0 0 auto;align-items:center;align-self:center}
.footsoc li{margin:0}
.footsoc a{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;border-radius:var(--radius);color:var(--muted);
  text-decoration:none;transition:color .12s,background .12s}
.footsoc a:hover{color:var(--paper);background:var(--panel-2)}
.footsoc a:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
.footsoc svg{display:block}
@media (max-width:900px){ .footcols{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:560px){
  .footcols{grid-template-columns:1fr;gap:22px}
  .footbar{flex-direction:column;gap:14px}
  /* Stacked: the row starts at the left edge like everything above it, and
     loses the inset the 36px target adds so it lines up with the text. */
  .footsoc{align-self:flex-start;margin-left:-9px}
}

/* ---- which logo ------------------------------------------------------- *
 * Last in the file so these win over .brand img and .hero-mark, and written
 * as img.logo-* so they win on specificity too.
 *
 * Two axes have to be covered and they do not always agree. With JavaScript,
 * THEME_SCRIPT has already stamped data-theme on <html> before this sheet
 * paints, and that attribute is the reader's answer whether it came from
 * localStorage or from the OS — so it decides. Without JavaScript there is no
 * attribute at all, and the media query below is the only thing that knows
 * anything; the :not([data-theme="light"]) guard keeps it from overriding a forced
 * light theme on a dark machine, which is the whole bug this replaced. */
/* Light-only pages: always the dark-ink logo. */
img.logo-d{display:none}
img.logo-l{display:block}

/* ---- the navigation as a sheet (<= 900px) ------------------------------ *
 * The same markup, read down instead of across. The two dropdown panels stop
 * being dropdowns and become the sections a phone menu is made of; the
 * primary button moves to the top, where a thumb reaches it first, and the
 * other language to the bottom. Order is set here rather than in the HTML
 * because the desktop row wants the opposite order and there is only one
 * document.
 *
 * The checkbox is what opens it, so it opens with no script at all. Anything
 * a script adds on top (the scroll lock, the focus ring around the open
 * sheet, Escape) is an improvement on a menu that already works.
 * ----------------------------------------------------------------------- */
@media (max-width:900px){
  /* The sheet is out of the flow, so the row is the lockup and this. */
  .navbtn{display:inline-flex;margin-left:auto}
  /* The offset for a page with no script: the header is 60px and there is no
     admin preview strip, because the strip is painted by the script that is
     not here. Where there IS a script, siteNav measures the header and sets
     this in style.top, which is the only way to be right about a sticky
     element whose own offset moves. */
  .navtog ~ .topnav{position:fixed;left:0;right:0;top:60px;bottom:0;z-index:4;display:none;
    flex-direction:column;align-items:stretch;gap:0;overflow-y:auto;overscroll-behavior:contain;
    background:var(--panel);border-top:1px solid var(--line);
    padding:16px 20px calc(28px + env(safe-area-inset-bottom))}
  /* Under the admin plan-preview strip, which pushes the header down by 30px. */
  html.ds-pv-on .navtog ~ .topnav{top:90px}
  .navtog:checked ~ .topnav{display:flex}
  /* The 404 has no toggle and no menus, only two links: it keeps the row it
     has at every width, and merely lets it wrap. */
  .topnav{flex-wrap:wrap;gap:14px;justify-content:flex-end}
  /* The sheet itself reads down: one column, every section full width. A
     wrapping row, which is what the 404 wants, would lay the account section
     beside the data section the moment there is room for two. */
  .navtog ~ .topnav{flex-direction:column;flex-wrap:nowrap;align-items:stretch;justify-content:flex-start;gap:0}
  .navtog ~ .topnav > *{width:100%}
  .navmid{flex-wrap:wrap;gap:14px}
  /* The two wrappers stop being boxes, so their children can be ordered
     against each other rather than only inside their own group. */
  .navmid,.navend{display:contents}
  .navtrig{display:none}
  .navmenu{position:static}
  .navsec{display:flex;align-items:center;gap:8px;margin:20px 0 4px;font-size:11.5px;
    font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
  .navpanel{display:block;position:static;transform:none;padding:0;background:none;
    border:0;border-radius:0;box-shadow:none}
  .navgrid,.navpanel-1 .navgrid{grid-template-columns:1fr;width:auto;max-width:none;gap:0}
  .navgrid a,.navlogout{padding:13px 0;border-bottom:1px solid var(--line);border-radius:0}
  .navgrid a:hover,.navlogout:hover{background:none}
  .navgrid a[aria-current=page]{background:none;color:var(--signal-ink)}
  .navi-t{font-size:15.5px}
  /* The descriptions are what a desktop panel has room for and a phone list
     does not: fourteen of them turn a menu into a page. */
  .navi-d{display:none}
  .navquit{margin:0;padding:0;border-top:0}
  /* Full width in the sheet, and still the shared button: flex rather than
     block so the label stays centred in the box rather than sitting on top
     of it. 44px, the touch minimum, on the one control a thumb reaches for
     first. */
  .navcta{order:1;display:flex;width:100%;min-height:44px;text-align:center;font-size:15px}
  /* The map is offered whoever is reading: signed in or not, it is still the
     first thing this site does. */
  .top.ds-in .navcta{display:block}
  .navsign{order:2;padding:13px 0;border-bottom:1px solid var(--line);
    font-size:15.5px;font-weight:600;color:var(--paper)}
  .navmenu.nav-data{order:3}
  .navmenu.nav-tools{order:4}
  .navlink{order:5;padding:13px 0;border-bottom:1px solid var(--line);
    font-size:15.5px;font-weight:600}
  .navme{order:6}
  .top.ds-in .navme{display:block}
  .navlang{order:7;display:block;margin-top:24px;font-size:14px;color:var(--signal-ink)}
  /* Open, the bars become a cross, so the control says what it will do next. */
  /* Each bar turns about its own centre: without transform-box the origin
     is the SVG's corner and the cross comes out lopsided. */
  .navbtn .nb-1,.navbtn .nb-2,.navbtn .nb-3{transform-box:fill-box;transform-origin:center}
  .navtog:checked ~ .navbtn .nb-1{transform:translateY(5px) rotate(45deg)}
  .navtog:checked ~ .navbtn .nb-2{opacity:0}
  .navtog:checked ~ .navbtn .nb-3{transform:translateY(-5px) rotate(-45deg)}
}
/* Set by siteNav in /alerts.js while the sheet is open, so the page behind it
   cannot be scrolled by a gesture meant for the menu.

   It has a side effect worth knowing about. body carries overflow-x:hidden,
   which normally propagates to the viewport and leaves the body itself
   visible; the moment <html> takes an overflow of its own that propagation
   stops, the body becomes a scroll container in its own right, and the sticky
   header starts sticking inside THAT rather than inside the viewport. Under
   the admin preview strip it therefore drops by the strip's own height the
   instant the menu opens. Which is why siteNav measures the header and places
   the sheet against it rather than trusting the offset below. */
html.ds-navopen,html.ds-navopen body{overflow:hidden}

@media (max-width:640px){
  /* The same rhythm, one notch tighter: a phone screen is mostly gap
     otherwise, and the rule is the token, not a per-page patch. */
  :root{ --section-gap:32px; --page-end:48px }
  body{font-size:14.5px}
  .plotwrap{padding-left:38px;padding-right:60px}
  .yl{left:-38px;width:33px;font-size:10px}
  .dl{font-size:10px;margin-left:6px}
  .media{grid-template-columns:1fr}
  .cols{columns:2}
  .cta{padding:16px}
  .newsletter{padding:16px}
  .nlrow .button{flex:1 1 100%;text-align:center}
  .donutbox{gap:16px}
  .formula{white-space:normal}
  /* 20px of standard panel padding on a card that is half a phone wide is
     most of the card. The compact step, everywhere, on the one screen where
     a panel's padding competes with what is inside it. */
  .card{padding:var(--space-4)}
  /* The hero, at phone density. 36 / 24 of vertical room rather than 14 and
     whatever the last element left: the proposition is still the first thing,
     it simply stops taking a screen and a half to say so. No horizontal
     padding of its own — main.wrap already carries 20px a side, and stating
     it a second time here is what would leave a 40px margin and a headline
     broken across four lines on a 360px screen.
     36px against the desktop's 40 because a phone reads closer, and 1.08
     because a three-line headline at 1.1 has a gap in it that a one-line
     headline does not. The lead goes UP, to 18: on a phone it is the only
     paragraph on screen and there is no column beside it to keep it small
     for. */
  section.hero{padding-block:36px var(--space-5)}
  .hero-mark{height:78px;margin-bottom:10px}
  .hero h1{font-size:36px;line-height:1.08}
  .hero .lead{font-size:18px;line-height:1.55;margin-bottom:18px}
  .hero .ctaline .button{flex:1 1 100%;text-align:center}
  /* 40 rather than 48 between the homepage's sections: the phone's own notch
     down the spacing ladder, matching --section-gap's 40-to-32 step above.
     The rebuilt homepage keeps its own 64 even here — it is eight unrelated
     offers rather than eleven related ones, and the break between two of them
     is the only thing telling a reader they have finished one. */
  .hero ~ section{margin-top:40px}
  .home-hero ~ section{margin-top:64px}
  /* The proposition is three lines at 40px on a 360 screen, which is a wall.
     36 with the shared phone step, and the measure cap comes off: the page is
     already only one column wide. Except this h1 runs longer than the
     generic hero's, so even 36 wraps a fourth line on a 390px phone — one
     more step down, to 32, gets it back to three. And the hero itself loses
     a little of its own top air to match: 56 was sized against the desktop's
     taller field, not a phone's. */
  section.home-hero{padding-top:44px}
  .home-hero h1{max-width:none;font-size:32px;line-height:1.15}
  .mapshow-go{right:8px;bottom:8px;padding:6px 11px;font-size:12px}
  .mapshow-toggle{left:8px;bottom:8px;padding:6px 11px;font-size:12px}
  /* And the place pages' 28 + 28 becomes 24 + 24, for the same reason. */
  .area > section:not(.cta):not(.newsletter){padding-block:var(--space-5)}
}
@media (max-width:400px){ .cols{columns:1} }
