/* The shared theme (Material 3): the tokens, the topbar, the tabs, the status
   dot, the footer. It is linked on every page; the specific styles live in the
   pages themselves.

   THE DEFAULT IS LIGHT (15.08.2026, the owner). The tokens below are still the
   DARK ones - the palette was born dark and rewriting :root would have touched
   every page that overrides html.light. Instead the class stands in the MARKUP
   of every page (<html lang="en" class="light">), and the early inline script
   in the head takes it off only for a deliberate theme=dark in the cookie. So a
   reader without any choice, and a reader with no script at all, gets light. */
:root{
  /* a deep background plus contrasting layers: richer rather than washed out */
  --bg:#0e0e10;          /* surface */
  /* THE PLATE OF THE NAVIGATION lies BELOW a card (23.08.2026). On the tone of
     a card it read as a slab louder than the quiet words on it; removed
     altogether, the row stopped being a GROUP - the active tab at the END of it
     hung alone, while the same tab at the START looked fine only because it
     happened to begin the row. The plate is what says "these belong together",
     so it stays - a half step off the ground instead of a full one. */
  --panel-lo:#151618;    /* surface-nav: the pills and the pager */
  --panel:#1c1d1f;       /* surface-container: the cards, the table */
  --panel-hi:#2a2c2f;    /* surface-container-high: the highlighted blocks */
  --panel-top:#383b3f;   /* surface-container-highest: the selected segment of a
                            capsule lying on --panel-hi (a card, a navigation
                            sheet) */
  --hover:rgba(255,255,255,.05);
  --line:rgba(255,255,255,.08);
  --line2:rgba(255,255,255,.06);
  --text:#eceded; --text2:#bdc1c6; --dim:#9aa0a6; --faint:#75777a;
  --num:#dee0e1;   /* the data figures: nearly white, half a tone quieter than the
                      text */
  /* the exchange semantics - a damped pair in the tone of the F&G gauge ramp: an
     emerald richer than the mint --heat-cold, and a red equal to --heat-hot; one
     lightness, no shouting */
  --up:#2ecc71; --down:#e0544c; --warn:#ff9f0a; --accent:#5aa2ff;
  /* ВСЕ УПРАВЛЯЮЩИЕ ЭЛЕМЕНТЫ ОДНОЙ ВЫСОТЫ (закон проекта, владелец
     02.09.2026): капсула, поле, мелкая кнопка, кнопка копии. Величина названа
     один раз здесь, чтобы новый контрол не заводил свою из собственных
     отступов - именно так в одном ряду оказывались 25, 27 и 29.
     Угловые кнопки шапки (44x44) под закон не попадают: это не ряд
     управления, а слот тач-цели, и его размер задан пальцем. */
  --ctl:28px;
  /* БОКОВОЙ ОТСТУП СОДЕРЖИМОГО - ОДИН НА ВСЕХ. Его задавали по месту: карточка
     24, строка здоровья 24, панель таблицы 24, а на телефоне каждый уезжал к
     своим 16 отдельным правилом - и панель поиска стояла не там, где строки
     под ней. Величина названа один раз и меняется в одном месте. */
  --pad:24px;
  /* THE KINDS OF AN OPINION HAVE NO COLOUR (the owner, 25.08.2026: "drop the
     colours of the kinds altogether, let them be white or black"). Five tones
     lived here for two days, each the grey of the page turned a few degrees
     towards its own hue. The argument against them is the one already made for
     the market filter on 23.08: a tone says a category, and these are not
     categories - an insight is not more important than a watch, and five
     coloured labels in one column invited a ranking that does not exist. The
     kind is a word now, in the colour of the text. */
  /* the ramp of the NUPL/DVOL zones - the gamut of a Fear & Greed gauge: green
     (calm) -> lime -> yellow -> orange -> red (alarming). Each scale has its own
     direction: the NUPL runs from a red capitulation to a green euphoria while the
     DVOL gets redder the higher it goes. The triplets for the fills of the charts
     live in index.html */
  --heat-cold:#57ca8a; --heat-cool:#97d24d; --heat-mid:#f2d54e;
  --heat-warm:#e9973f; --heat-hot:#e0544c;
  --head:#fff;           /* the section headings: a tone brighter than the text */
  /* the shadows: in the light a hard black shadow looks dirty - hence tokens */
  --shadow-pop:0 14px 36px rgba(0,0,0,.5);      /* the menus, the popovers */
  --shadow-stick:0 4px 8px -2px rgba(0,0,0,.4); /* the stuck headers */
  /* the lift of a small control above a plate (the pill of a switcher): ONLY a
     soft halo in every direction, with no offset and no light rim. A shadow falling
     downwards "glues" an element while a rim on top reads as a stripe - here the
     control is simply set a little apart from the plate, at the level of a
     feeling */
  --lift:0 0 5px rgba(0,0,0,.12);
  --mono:"Ubuntu Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --ui:Ubuntu,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  /* ── THE READING COLUMN OF THE FEEDS (the owner, 24.08.2026) ─────────────
     Tape and News set an entry in the same two voices - 700/18 over 400/16 -
     and a feed is read by the LENGTH OF ITS LINE, so the measure belongs to
     both feeds or to neither. It belonged to each separately: Tape at 800 after
     the count was made on the stand, News at 760 picked beside it while its own
     comment promised "the same reading column". One decision written twice
     drifts, and this one had.
     THE NUMBER IS A COUNT OF CHARACTERS, not of pixels: 800 gives just under a
     hundred to the line of the body, against 89 at 720, 82 at 660 and about 105
     at the 900 that made the feed heavy. It is a CEILING rather than a starting
     point - a hundred characters already stands where the fatigue begins - so
     whoever moves it next has room downwards and none upwards.
     Geometry, not colour: no theme redefines it. */
  --read-col:800px;
}
/* ── the light theme (html.light, the toggle lives in the topbar): the background
     is white and the plates are a warm milky tone half a step deeper; the
     semantics and the ramp keep the same spirit but darker - the contrast of a light
     surface ── */
html{color-scheme:dark}
html.light{
  color-scheme:light;
  /* ── THE SURFACE IS WHITE, AND THE LADDER MOVED UP A STEP (the owner,
     16.08.2026: "both should be white") ─────────────────────────────────────
     The background was a warm milky #f7f6f3 while the landing was pure white,
     and crossing from the site into the app read as leaving one product for
     another. The whole ladder simply shifted: what was the background is now
     the first panel, so every surface keeps a neighbour it was designed
     against and only the ground under them turned white. */
  --bg:#ffffff;          /* surface: white, the same white as the site */
  /* on paper there is nothing to quiet: the ground is white and the card almost
     white, so a step between them is invisible and the pill simply dissolved.
     The plate was only ever loud in the dark */
  --panel-lo:#f7f6f3;
  --panel:#f7f6f3;       /* the cards: the warm milky tone this ladder began on */
  --panel-hi:#efeeeb;    /* the highlighted blocks: deeper */
  --panel-top:#e3e1dc;   /* one more step, of the same size as panel -> panel-hi */
  --hover:rgba(0,0,0,.06);
  --line:rgba(0,0,0,.13);
  --line2:rgba(0,0,0,.08);
  /* the greys are darker than an "inversion" of the dark ones: in the light the
     secondary text washes out faster, so the whole scale is pressed towards black */
  --text:#101012; --text2:#29292d; --dim:#3b3b41; --faint:#5b5a54;
  --num:#1a1a1c;
  --up:#17924e; --down:#bd3f36; --warn:#a86e00; --accent:#2f6bd8;
  /* the same four tones on paper: darker, by the rule the heat ramp already
     follows - a quiet label must still be legible on white */
  /* the heat ramp in the light: darker and richer - the zone captions and the
     NUPL/DVOL figures must ring on a white ground rather than wash out */
  --heat-cold:#0d7c42; --heat-cool:#587f0a; --heat-mid:#8c7300;
  --heat-warm:#9d5808; --heat-hot:#a8281f;
  --head:#050506;
  --shadow-pop:0 14px 36px rgba(0,0,0,.16);
  --shadow-stick:0 4px 8px -2px rgba(0,0,0,.12);
  --lift:0 0 4px rgba(0,0,0,.05);
}
/* A change of theme is instant. The class hangs for exactly the time of the swap
   of the palette (nav.js removes it after two frames): without it every element with
   a transition of its own would crawl from the old colours into the new ones out of
   step, and the theme would "blur" instead of switching. The !important is there
   because we suppress the declarations of the pages, whose specificity is higher */
html.no-anim, html.no-anim *, html.no-anim *::before, html.no-anim *::after{
  transition:none !important; animation:none !important}
/* the roles that need a tone darker than the shared --dim in the light: the name of
   a page and the subheadings of the sections are nearly headings */
html.light h1.mark{color:var(--head)}
html.light .b-logo{color:var(--head)}
html.light .tagline{color:var(--head)}
html.light .sec-note{color:var(--text2)}
*{box-sizing:border-box}
/* a stable scrollbar gutter: pages of different lengths do not shift the content
   sideways */
html{-webkit-font-smoothing:antialiased;scrollbar-gutter:stable}
/* A column flex over the full height of the window plus main{flex:1} below: the
   footer is pressed to the bottom of the screen on short pages and stays under the
   content on long ones. Without it a page with little content broke off in the
   middle with the footer hanging right under it. The rule is shared - login.html and
   admin.html used to declare exactly this at their end and now simply inherit it. */
body{position:relative;   /* the anchor of the absolutely placed global menu */
     margin:0;color:var(--text);font:14px/1.5 var(--ui);background:var(--bg);
     min-height:100vh;display:flex;flex-direction:column}
/* .page-clip is the wrapper of Home (it cuts the sideways spread of the halo of a
   card): it is the one that grows while main inside stays an ordinary block */
body > main{flex:1 0 auto}
body > footer{flex:none}
/* IMPORTANT: the header, the tabs, main and the footer all carry `margin:0 auto`
   (the centring at max-width:1180px), and an auto margin on the cross axis DISABLES
   the stretch - without an explicit width they would shrink to their content. We set
   100% and the centring keeps being done by max-width plus auto. */
body > .topbar,body > .tabs-wrap,body > main,
body > footer{width:100%}
::selection{background:rgba(138,180,248,.30)}
/* the focus: the blue UA ring is out of tune - a mouse click leaves no ring while
   keyboard navigation gets a quiet one of its own */
:focus{outline:none}
:focus-visible{outline:2px solid var(--faint);outline-offset:2px}
.up{color:var(--up)} .down{color:var(--down)} .zero{color:var(--dim)}

/* ── [hidden] IS STRONGER THAN ANY LAYOUT ──────────────────────────────────
   The browser hides an element with the attribute by a rule of the lowest
   weight (html{display:none}), so ANY selector of ours with a display beats it -
   and the element stays on screen while the code is sure it is gone. The
   project met this four times and patched it four times point by point
   (.data-menu[hidden], .nav-sheet[hidden], #awa_grp[hidden], a.sum-copy[hidden]);
   the fifth case (the empty plates of the Macro section, which
   `.card:has(.nquiet) > *:has(.nquiet)` was stretching into a flex column) is
   where the patches stop and the law begins. */
[hidden]{display:none !important}

/* ── THE GLOBAL MENU OF THE PORTAL (built by nav.js, one place for every page) ──
     The project stopped being one site about ETH: ETH is a SECTION, MCP is another,
     BTC will be the third. Sections live on the vertical axis, the pages of a section
     on the horizontal one - two axes, two places, the model a reader already knows
     from Stripe or Linear.

     The menu is PART OF THE PAGE rather than a panel beside it: no border, no
     backdrop, no column running down to the floor, and it SCROLLS AWAY with the page
     like everything else (absolute, not fixed - a menu nailed to the glass while the
     page moves under it is exactly what makes two surfaces out of one).
     It stands NEXT TO THE CONTENT -
     the left offset is computed from the same centring the content uses, so the right
     edge of the menu meets the left edge of main exactly (132 + 1180 = 1312; below
     that width the menu simply sits at the edge and the content still starts right
     after it). The column is as narrow as the words in it: two short names need no
     more, and it reads as one body with the page rather than as a panel. When the
     names get longer, the width goes up with them. It ends where its items end, and the footer runs under it across the
     whole page - one sheet, not two.

     Minimal by design: no fills, no frames, no capsules. The active section is the
     pure --head, the rest are --faint; hover moves the tone only. Type is large (17px
     600) - it is the first thing on the page and it should read as a title, in the
     grammar of Tape and MCP. */
.gnav{position:absolute;top:0;left:max(0px,calc(50% - 656px));width:132px;z-index:40;
      display:flex;flex-direction:column;padding:20px 26px 0}
/* the brand mark moved here out of the topbar; it is the way back to the portal */
.gnav .b-home{align-self:flex-start}
/* та же пара, что в шапке и в подвале: ширина знака меньше коробки, а коробка
   держит прежний рост - на широком экране виден ИМЕННО ЭТОТ знак (копия в
   шапке спрятана), и правка ширины без него ничего бы не изменила */
.gnav .b-logo{width:33px;height:34px}
/* the mark is the brand and the sections are the navigation - between them stands
   real air, not a hairline gap: a gap equal to the step would turn the mark into a
   fourth item, and it is a link to the home page. Everything BELOW is measured from
   the first section (see the rules of the topbar) */
/* THE COLUMN READS BY WEIGHT, NOT BY PIXELS ALONE (07.08.2026). Four sections set
   in one weight and one tone read as a solid block however much air stands between
   them - the eye has nothing to catch. So the current section keeps 600 and the
   --head tone while the rest step back to 500: the hierarchy costs no space at all.
   The air was widened along with it - a step of 48px is 2.8 of the type size (it
   was 42 = 2.5), and the break before the kitchen keeps its CONTRAST: 88px is 1.8
   steps, the same ratio the dot had before. Widening the step alone would have
   flattened that ratio to 1.4 and the dot would have stopped dividing anything. */
.gnav-list{display:flex;flex-direction:column;gap:14px;margin-top:26px}
/* SAME LETTERING, BIGGER SIZE (the owner, 23.08.2026). The menu speaks the word
   of everything else that is pressed - lower case, 600, the same tracking - but
   keeps a size of its own: it is the top of the hierarchy, and one step above
   the controls of a page is what says so. 14.5 also keeps it below the headings
   of the content (18/700), which 17 used to argue with. */
.gnav-item{font:600 14.5px var(--ui);color:var(--faint);text-decoration:none;
           padding:7px 0;letter-spacing:.04em;text-transform:lowercase;
           transition:color .15s}
.gnav-item:hover{color:var(--text)}
.gnav-item.active{color:var(--head);font-weight:700}
/* ── THE KITCHEN STANDS APART. Admin is not a fifth market, it is another kind
     of place, and in a plain list it read as one more section of the portal.
     The break is air plus a dot on the axis of the sections - a rule across the
     column would be a border where a breath is enough, and a hairline is not a
     language this site speaks anywhere.
     The dot is a NODE OF ITS OWN (nav.js) rather than a pseudo element of the
     link: inside the link it became part of it and a click on the dot opened
     Admin ── */
/* the dot is EXACTLY the grey of the words it stands between: a paler one read
   as a stray speck rather than as a mark of the same hand (04.08.2026) */
.gnav-sep{width:6px;height:6px;border-radius:50%;background:var(--faint);
          margin:10px 0 10px 1px;flex:none;pointer-events:none}
/* the build of the service that served the page, echoed under the door of the
   kitchen (nav.js builds it, and only where the kitchen itself is). A caption
   rather than a tag: the mono chip in the footer is a mark on the sheet, this is
   a line of the menu - so it takes the face of the menu and none of its weight */
/* the step is measured BY THE LETTERS, not by the boxes: the gap of the list is
   cut for a 17px line, and an 11px caption carries far less field of its own -
   under the common gap it would drift away from the section it belongs to. The
   negative margin gives back exactly that difference (34 + 14 - 6 = 42 against the
   48 of the list). The burger sheet is not touched: it overrides the margin to 0 */
.nav-ver{display:block;font:400 11px/1.2 var(--ui);color:var(--faint);
         margin-top:-6px}
/* The service icons (the status dot, the theme, the sign-out) stay in the CORNER OF
   THE TOPBAR on every width. They used to move under the sections of the menu on the
   desktop, and the right half of the header was left with nothing in it: 961px of
   emptiness beside a 187px subheading (03.08.2026). The menu keeps the vertical axis
   of the SECTIONS; the service row keeps the corner. */
@media (min-width:1001px){
  /* the width is reserved by the CSS rather than by the deferred nav.js, otherwise the
     content jumps on load. The menu is built where the pill of pages is, so the
     condition here is the same: login and the admin of the collector stay outside the
     portal and keep the whole width */
  body:has(.tabs-wrap){padding-left:132px}
  /* the mark lives in the menu now - in the topbar it would be a second one (on Home
     the mark is not a link and stands as a bare .b-logo) */
  body:has(.tabs-wrap) .topbar .b-home,
  body:has(.tabs-wrap) .topbar .brand > .b-logo{display:none}
  /* the height of the header is now set by the 44px button of the corner row, not
     by the line of the subheading - so the padding is measured to keep the OLD AXIS:
     the middle of the row on the middle of the ring in the menu (37px). 15 + 44/2 =
     37. The header ends up shorter than it was with the bare tagline, and the whole
     page rises by 13px */
  body:has(.tabs-wrap) .topbar{padding-top:15px;padding-bottom:0}
  /* ...and the CONTENT of the page opens AT THE FIRST SECTION of the menu. Two cases,
     two rules:
       - a page WITH THE PILL stands symmetrically to it: the middle of the pill on the
         middle of ETH (the two capsules differ in height, so it is the middles that
         must agree, not the edges);
       - a page OF PLAIN TEXT (the MCP shopfront, no pill) starts with the TOP EDGE of
         the first section: a line of text has no capsule to centre. */
  body:has(.tabs-wrap) .tabs-wrap{margin-top:11px}
  /* 0 + 11px of the padding of main: the X-LINE of the heading stands on the top of
     ETH - the top of the "e" in "decision" against the top of the letters of the
     section. The numbers were re-measured after the corner row raised the header. The lowercase carries
     the mass of a line and it is what the eye levels by; the capital A is taller by
     its nature and rises above the line - that is the letter, not the layout.
     The baselines of both are measured IN THE DOM (an empty inline-block on the
     baseline), not from the metrics of a canvas: canvas reports the metrics of the
     face, while the browser lays the line out by others (hhea/OS2), and the two
     differed by 7px here - the heading stood visibly high while the arithmetic said
     it was level. */
  body:has(.tabs-wrap.sole) .tabs-wrap{margin-top:0}
  /* ...THE PAGE OF TEXT IS THE ONE EXCEPTION TO THAT LEVELLING. Its heading is not a
     line inside the sheet but the OPENING of the sheet, and standing it on the top of
     ETH left it 25px under the tagline of the header - close enough to read as the
     second line of the header rather than the first line of the page. The heading is
     given its own layer instead: 25px of padding put ~40px between the two, a step
     larger than the leading of either. The alignment with the section is traded away
     knowingly - only this page (the MCP shopfront) carries .sole */
  body:has(.tabs-wrap.sole) main{padding-top:25px}
  body:has(.tabs-wrap.sole) main > :first-child{margin-top:0}
  /* a section of ONE page (the MCP shopfront) shows no pill: the pages of ANOTHER
     section under its heading are a false trail */
  .tabs-wrap.sole .tabs{display:none}
  /* the footer closes the SHEET - the menu plus the content, not the window: it
     steps back over the width of the menu and ends where main ends (132 + 1180 =
     1312). Across the whole window it dragged its signature out of the composition
     and off to the right. The margin is clamped: below 1312 the sheet is the whole
     screen, and the step back is exactly the width of the menu */
  body:has(.tabs-wrap) footer{
    width:calc(100% + 132px); max-width:1312px; margin-right:0;
    margin-left:max(-132px, calc((100% - 1180px) / 2 - 132px));
  }
}
@media (max-width:1000px){
  /* the sidebar folds away entirely: the sections go as the first group of the
     burger sheet (see .ns-global), and the mark with the icons returns to the
     topbar - one gesture for the whole navigation instead of a second drawer */
  .gnav{display:none}
}

/* МОБИЛЬНОЕ МЕНЮ: колонка разделов складывается в лист под кнопкой.
   На узком экране второго уровня нет - кухня раскрывается ПЛОСКО:
   разделы, затем страницы вкладки, затем содержимое её листа. */
.nav-head,.nav-cur,.nav-burger,.nav-sheet{display:none}
@media (max-width:1000px){
  .nav-head{display:inline-flex;align-items:center;gap:4px;min-width:0;
            background:var(--panel-lo);border-radius:14px;padding:5px}
  .nav-cur{display:inline-flex;align-items:center;height:33px;
           background:var(--panel-hi);border-radius:10px;padding:0 16px;
           font:600 11.5px/1.2 var(--ui);letter-spacing:.04em;
           text-transform:lowercase;color:var(--text)}
  .nav-burger{display:inline-flex;align-items:center;justify-content:center;
              width:43px;height:43px;border:0;cursor:pointer;border-radius:14px;
              background:var(--panel-lo);color:var(--dim);
              transition:background .15s,color .15s}
  .nav-burger[aria-expanded="true"]{background:var(--panel-hi);color:var(--text)}
  .nav-sheet{--dm-row:46px;
             display:flex;flex-direction:column;gap:6px;
             position:absolute;top:calc(100% + 8px);right:26px;
             /* the sheet of the burger is a touch wider than before: the two
                columns of the contours breathe and the rows of the pages are not
                cramped. The padding is symmetric - at the top here stand the items
                themselves (not a caps label), and an addition at the bottom would
                skew the sheet the other way */
             width:max-content;min-width:min(360px, calc(100vw - 52px));
             max-width:calc(100vw - 52px);
             z-index:40;background:var(--panel-hi);
             border-radius:18px;padding:8px;
             max-height:calc(100vh - 140px);
             max-height:calc(100dvh - 140px);   /* the address bar of mobiles */
             overflow-y:auto;
             box-shadow:var(--shadow-pop);
             transform-origin:top right;animation:navpop .16s ease}
  .nav-sheet .ns-pages{display:grid;grid-template-columns:1fr;gap:2px}
  .nav-public .nav-sheet{min-width:min(300px, calc(100vw - 52px))}
  .nav-sheet .ns-cols{columns:2;column-gap:6px}
  .nav-sheet .dm-g{break-inside:avoid}
  .nav-sheet .ns-sheet{break-inside:avoid;padding-top:6px}
  .nav-sheet .ns-sheet + .ns-sheet{margin-top:10px;padding-top:12px;
                                   border-top:1px solid var(--line2)}
  .nav-sheet .ns-cap{column-span:all;display:block;margin:0 0 4px;
                     color:var(--text2)}
  .nav-sheet .tab{display:flex;align-items:center;height:var(--dm-row);
                  padding:0 16px;border-radius:13px;
                  font:500 16px/1.2 var(--ui)}
  .nav-sheet .tab.active{background:var(--panel-top);color:var(--text)}
  .nav-sheet .cap{display:flex;align-items:flex-end;height:var(--dm-row);
                  padding:0 14px 9px;font:600 11px/1 var(--ui);
                  letter-spacing:.04em;text-transform:uppercase;
                  color:var(--faint);white-space:nowrap}
  .nav-sheet .ns-global{display:grid;grid-template-columns:1fr 1fr;gap:2px 6px;
                        padding-bottom:6px;margin-bottom:2px;
                        border-bottom:1px solid var(--line2)}
  .nav-sheet .ns-global:last-child{padding-bottom:0;margin-bottom:0;border-bottom:none}
  .nav-sheet .ns-global .cap{grid-column:1/-1}
  .nav-sheet .nav-ver{grid-column:1/-1;padding:0 14px 2px;margin-top:0}
  .nav-sheet{right:12px;max-width:calc(100vw - 24px)}   /* в лад с полями */
  .tab,.nav-burger{transition:none}
  .nav-sheet{animation:none}
  .nav-sheet .ns-pages{grid-auto-flow:row;grid-template-columns:1fr;
                       grid-template-rows:none}
  .nav-sheet .ns-cols{columns:1}
}

/* ── the topbar: the ring mark on the left with the subheading of the page next to
     it across a calm gap (on one axis with the ring), and a mirrored corner of icons
     on the right (status / theme / sign-out). The ring is an inline SVG using
     currentColor and follows the theme. There is no visible wordmark - the name of
     the brand is carried by h1.sr-only ── */
.topbar{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
        max-width:1180px;margin:0 auto;padding:24px 26px 6px}
/* THE ROW OF THE TOPBAR KEEPS ITS HEIGHT (06.08.2026). nav.js is deferred, so
   the theme button (44x44) lands AFTER the first paint: the bar grew from 62 to
   74 and everything below it moved. On a long page nobody notices; on the door,
   where the card is centred in the free space, the form jumped six pixels down
   right after the redirect from a sign-out. The brand reserves the height of the
   button instead - the same law the status dot already follows (its slot is
   created at load, not on the first setPill). */
.brand{display:flex;align-items:center;gap:14px;min-width:0;min-height:44px}
/* the mark in the header is the way back to Home (on Home itself and on the service
   pages it is simply a mark, with no link) */
/* МАРКА ЗАДАЁТСЯ ШИРИНОЙ, А КОРОБКА ДЕРЖИТ ВЫСОТУ (владелец, 02.09.2026).
   svg вписывается в коробку сам и стоит по её середине, поэтому строка шапки
   не поднимается и не опускается ни на пиксель, какой бы марка ни была.
   ШИРИНА НАЗНАЧЕНА, ВЫСОТА БУКВЫ ИЗ НЕЁ СЛЕДУЕТ: марка 132x74, значит при
   33 буква выходит 18.50 высотой, при 21 - 11.77. Пара держится вместе:
   подвальная буква ровно 0.64 от шапочной, как и была. Меняется марка -
   пересчитать обе, иначе буквы разъедутся по росту между шапкой и
   подвалом. */
.b-home{display:inline-flex;color:inherit;text-decoration:none}
.b-home:hover .b-logo{color:var(--head)}
/* СООСНОСТЬ СЧИТАЕТСЯ ПО ЧЕРНИЛАМ, А НЕ ПО КОРОБКАМ (владелец, 02.09.2026), и
   двигать при этом надо ЗНАК, а не текст: текст стоит на одной строке с часами
   и капсулой угла, и поднятый к марке, он уезжает вверх от всего ряда.
   СЕЙЧАС ДВИГАТЬ НЕЧЕГО. Рядом с маркой стоит ИМЯ страницы, набранное
   прописными: его чернила лежат на 37.27 против 37.00 у марки - четверть
   пикселя, и сдвиг только испортил бы. Он был нужен, пока соседом была
   строчная подпись с выносными (её чернила уезжают на 38).
   Появится рядом другой сосед - перемерить: canvas TextMetrics даёт
   actualBoundingBoxAscent/Descent, то есть настоящие верх и низ знаков. */
.b-logo{flex:none;width:33px;height:32px;color:var(--text);
        transition:color .15s}
/* the subheading of a page in the topbar: the size and the weight of .sec-note
   (13.5px/400 - "levels · value areas · VWAP · all venues") but in the pure --head
   colour (white in the dark, black in the light) */
/* ИМЯ СТРАНИЦЫ И ЕЁ ПОЛСТРОКИ - ТА ЖЕ ПАРА, ЧТО В ЗАГОЛОВКЕ СЕКЦИИ: имя
   набрано весом, объяснение стоит рядом тише. Пара живёт своей коробкой, чтобы
   воздух между именем и подписью был свой, а не общий шаг .brand. */
.page-id{display:flex;align-items:baseline;gap:10px;min-width:0;flex-wrap:wrap}
.page{font:600 13.5px var(--ui);color:var(--head);white-space:nowrap}
.tagline{font:400 13.5px var(--ui);color:var(--dim)}
/* ── the status dot (created by ui.js): the norm is silence and the dot appears
   only on a problem. A 44x44 slot in the grid of the corner icons is always
   reserved - the corner never jumps; amber means a degradation (stale) and red
   means a break (off); the reason lives in the tooltip of the dot (on hover or a
   click) ── */
.st-wrap{position:relative;width:44px;height:44px;display:inline-flex}
.topbar .st-wrap{order:6;margin-left:auto} /* the dot opens the row of corner icons */
.st-dot{width:44px;height:44px;border:0;cursor:pointer;border-radius:14px;
        background:transparent;padding:0;display:grid;place-items:center;
        transition:background .15s}
.st-dot:hover{background:var(--hover)}
/* the norm: not only the button goes out but the hover of the whole slot too -
   otherwise an empty phantom tooltip pops up from an invisible dot (a mouseenter on
   the wrapper) */
.st-wrap:not(.on){pointer-events:none}
.st-wrap:not(.on) .st-dot{visibility:hidden}
.st-i{width:10px;height:10px;border-radius:50%;background:var(--warn);
      position:relative}
.st-wrap.off .st-i{background:var(--down)}
/* a soft expanding ring - the live pulse of a problem */
.st-i::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:inherit;animation:st-ping 2.4s cubic-bezier(0,0,.2,1) infinite}
@keyframes st-ping{0%{transform:scale(1);opacity:.5}
  70%,100%{transform:scale(2.9);opacity:0}}
@media (prefers-reduced-motion:reduce){.st-i::after{animation:none}}
/* the tooltip: a tonal card under the dot, aligned to the right edge */
/* the tooltip of the dot hangs from the RIGHT edge of its slot: in the corner of the
   topbar that is the only way it fits on the screen */
.st-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:40;
  min-width:230px;max-width:300px;background:var(--panel-hi);
  border-radius:12px;padding:12px 14px;box-shadow:var(--shadow-pop);
  text-align:left;cursor:default}
.st-t{font:600 12.5px/1.35 var(--ui);color:var(--warn)}
.st-wrap.off .st-t{color:var(--down)}
.st-n{margin-top:3px;font:12px/1.45 var(--ui);color:var(--text2)}
/* the details of the status use a SINGLE 2-column grid (an auto key plus a 1fr
   value): the keys go into one left column and the values into the right one with a
   shared right edge - the rows do NOT jump (with a per-row space-between the left
   edge of the values was ragged). One grid layout for every row: .st-row is
   transparent */
.st-rows{margin-top:9px;display:grid;grid-template-columns:auto 1fr;
         gap:3px 14px;align-items:baseline;
         font:11.5px/1.5 var(--ui);font-variant-numeric:tabular-nums;
         color:var(--dim)}
/* ONE FACE FOR THE WHOLE CARD (04.08.2026). The values used to be set in mono, so
   four lines carried two families and three sizes. What mono was there for is the
   ages holding their width, and tabular-nums gives exactly that - the same trade the
   clock made next door. The values here are WORDS anyway ("live", "reconnecting",
   "unavailable"), and the canon of the tables keeps mono for digits. The key and the
   value are told apart by colour and weight, which is all the difference they need */
.st-row{display:contents}
.st-row b{font:500 11.5px/1.5 var(--ui);color:var(--text2);text-align:right}
@media (max-width:1000px){
  /* we let the brand shrink (a long tagline wraps) - the status, theme and
     sign-out icons always stay on the top line and never move down */
  .brand{flex:1 1 0;min-width:0}
  /* ── THE ROW BELONGS TO THE HEADING AGAIN (04.08.2026) ─────────────────
     A phone had the clock, the initials, the role badge and the theme in the
     corner, and some forty pixels left for the name of the page - so the name
     was dropped. The corner gives the room back instead: the CLOCK GOES
     (the time is not why anyone opens a page on a phone, and the market hours
     are a desk matter), and the NAME of the signed-in user becomes the icon of
     the action it always was - the way out. What is left is the heading, and
     it wraps to a second line under the mark, aligned with it. */
  /* the selectors carry the topbar on purpose: .clock and .who-* are declared
     BELOW this block, and at equal specificity the last rule would win */
  .topbar .clock{display:none}
  /* НА ТЕЛЕФОНЕ ОСТАЁТСЯ ИМЯ, А ПОЛСТРОКИ ОБЪЯСНЕНИЯ УХОДЯТ. Подпись писалась
     сюда, пока она БЫЛА именем страницы; теперь имя стоит отдельно и своим
     весом, а объяснение на 375 пикселях занимало три строки и растягивало
     шапку втрое. На вопрос "где я" отвечает имя, и оно остаётся.
     Селектор несёт .topbar намеренно: .tagline объявлен выше, и при равном
     весе победило бы последнее правило. */
  .topbar .tagline{display:none}
  .topbar .page{font-size:14px}
  .brand{align-items:center}
  .topbar .who-ini,.topbar .who-role{display:none}
  .topbar .who-out{display:block}
  /* ...AND IT IS THE SAME BUTTON AS THE OTHERS (the owner, 04.08.2026). On a
     desktop the way out is a NAME - a word needs no plate. Reduced to a bare
     icon on a phone it stood in the row of 44x44 slots as a smaller, plateless
     stranger: same row, three different shapes. Here it takes the slot of the
     theme button exactly - the size, the radius and the lit background of a
     press - so the corner reads as one set of controls. */
  .topbar .who-btn{width:44px;height:44px;padding:0;margin-right:0;
                   border-radius:14px;justify-content:center}
  .topbar .who-btn:hover,.topbar .who-btn:active{background:var(--hover)}
  .topbar .who-btn:hover .who-out,
  .topbar .who-btn:active .who-out{color:var(--text2)}
}

/* ── The tooltip (data-tip): ONE hint for the whole project. The native title was
     removed everywhere (it followed the theme of the OS rather than of the site and
     popped up immediately) - every UI hint is drawn with the panel tokens.
     On 30.07.2026 the hint moved from an ::after to ONE FLOATING NODE (UI.tip in
     ui.js; the node is a direct child of the body, position:fixed). The pseudo
     element was bound to its own element and therefore:
       - crawled off the edge of the screen on the outermost right, left and top
         elements;
       - was clipped by any ancestor with overflow:hidden (which we cured
         point-by-point, and "a card without overflow" stood as a separate note);
       - inherited the tokens of the CARD (on the light island of Home it came out
         white on white, which we cured by an exception rule);
       - did not render on SVG at all - the sparklines of streams kept the native
         title.
     The floating node removes all four: it lives in the coordinates of the screen,
     knows its boundaries and takes the tokens of the document. The positioning and
     the delay live in ui.js, here lives only the appearance ── */
.ui-tip{position:fixed;left:0;top:0;z-index:9999;max-width:min(250px,calc(100vw - 16px));
  white-space:normal;text-align:left;background:var(--panel-hi);color:var(--text);
  font:500 11.5px/1.45 var(--ui);letter-spacing:0;text-transform:none;
  border-radius:8px;padding:8px 11px;box-shadow:0 6px 18px rgba(0,0,0,.18);
  pointer-events:none;opacity:0;transition:opacity .12s ease}
.ui-tip.on{opacity:1}

/* ── the theme switcher (created by nav.js on every page): a quiet icon in the
     topbar showing the theme a click will give you ── */
.theme-btn{margin-left:auto;width:44px;height:44px;border:0;cursor:pointer;
           border-radius:14px;background:transparent;color:var(--dim);
           display:inline-flex;align-items:center;justify-content:center;
           transition:background .15s,color .15s}
.theme-btn:hover{background:var(--hover);color:var(--text2)}
/* the order in the corner: the status dot (order 6) opens the row and carries the
   auto margin to the right; on the pages without ui.js (there is no slot for the
   dot) the margin stays with the theme */
.topbar:has(.st-wrap) .theme-btn{margin-left:0}
/* ── the corner icons (the status dot, the theme, the sign-out) live in ONE box
     created by ui.js. On mobile it stands where it always did - in the right corner
     of the topbar; on the desktop nav.js moves the same box under the sections of the
     global menu - the icons are properties of the portal rather than of a page ── */
.nav-icons{display:flex;align-items:center;margin-left:auto}
/* WHO IS SIGNED IN, AND THE WAY OUT - one control instead of two. The initials
   plus the role of an admin; the click signs out and the tooltip says so (the
   full name lives there too). Quiet by default and lit on hover, in the grammar
   of the other corner buttons: it is a service action, not a call to press */
/* no plate on hover: the initials lighting up say "this is a control" quietly
   enough, and a grey pill around a name reads as a second badge next to the
   role one */
/* the gap is TIGHTER than a row of tabs: the initials and the role are one
   thing said in two parts ("VA admin"), and six pixels made them read as two
   neighbours (the owner, 06.08.2026) */
/* THE WIDTH IS THE CONTENT'S. It was pinned for one day (10.08.2026), while the
   capsule arrived from /api/me after the frame was drawn and pushed the clock
   91 px sideways; now it comes with the page in the who cookie and there is
   nothing left to hold still. */
/* знак на двери: тот же рост, что в шапке - дверь это тоже страница портала
   (и та же пара размеров: 25 в ширину, коробка в 32) */
.topbar .brand-full{width:33px;height:32px;color:var(--head)}
.who-btn{display:inline-flex;align-items:center;gap:4px;border:0;cursor:pointer;
         background:transparent;padding:6px 8px;margin-right:2px;
         border-radius:12px;transition:color .15s}
/* ── TWO CAPSULES OF ONE PAIR (the owner, 06.08.2026). Who and in what role is
   ONE fact, and it used to be said in two typographies: bare initials in one
   size next to a badge in another. Now both are the same caps - one size, one
   weight, one tracking - and what tells them apart is the STEP OF THE SURFACE:
   the initials rest on --panel (one step above the header), the role on
   --panel-hi (one more). The name is the quieter of the two: the role is what
   you check, the initials only say whose it is. */
.who-ini,.who-role{font:600 9.5px var(--ui);letter-spacing:.08em;
                   text-transform:uppercase;border-radius:6px;padding:2px 5px}
.who-ini{color:var(--dim);background:var(--panel)}
.who-btn:hover .who-ini{color:var(--text2)}
/* the way out as an icon - the phone form of the same button (see the mobile
   block below); on a desktop the name says it and the icon stays off */
.who-out{display:none;color:var(--faint);transition:color .15s}
.who-btn:hover .who-out{color:var(--text2)}
.who-role{color:var(--text2);background:var(--panel-hi)}
.who-btn:focus:not(:focus-visible){outline:none}
/* КОЛЬЦО ФОКУСА - ДЛЯ КЛАВИАТУРЫ, А НЕ ДЛЯ МЫШИ. После нажатия оно оставалось
   на вкладке и читалось как выделение, которого никто не делал: :focus-visible
   отличает одно от другого, и с клавиатуры кольцо на месте. */
.tab:focus:not(:focus-visible),
.tfswitch button:focus:not(:focus-visible),
.theme-btn:focus:not(:focus-visible){outline:none}

/* ── THE CLOCK (created by ui.js): the UTC time and the session of the hour.
     ONE face for the whole row - the ui one, at the size of the initials next to
     it: the time and the session read as a single quiet line rather than as a
     mono gadget glued to a word. What mono was there for is the digits holding
     their width, and tabular-nums gives exactly that (Ubuntu already has it, a
     fallback face on another OS may not) - the row must not twitch once a
     second. The nearest opening lives in the tooltip ── */
/* the air on the LEFT is the same 12px as on the right: the slot of the dot is
   44px wide and its plate lights up on hover, and with no margin the plate ended
   flush against the first digit (04.08.2026). The margin belongs to the clock
   rather than to the slot: the clock is a hover target of its own (the session
   tooltip), and padding would grow that target into the plate */
.clock{display:inline-flex;align-items:baseline;gap:5px;margin:0 12px 0 12px;
       white-space:nowrap;cursor:default;
       font:500 11.5px/1 var(--ui);color:var(--faint)}
.cl-t{font-variant-numeric:tabular-nums}
.cl-s::before{content:"·";margin-right:5px}
/* the order of the corner: the status dot OPENS the row, then the clock, the
   theme, and WHO YOU ARE at the very edge - the name is the one thing there
   that is about the reader rather than about the data, and it holds the corner.
   The dot goes first BECAUSE its 44px slot is reserved even while it is silent
   (the norm): inside the row that empty slot tore a hole between the clock and
   the name, at the head of the row it is simply air before the text */
.nav-icons .st-wrap{order:4;margin-left:0}
.nav-icons .clock{order:5}
.nav-icons .theme-btn{order:6;margin-left:0}
.nav-icons .who-btn{order:7;margin-right:0}
.nav-icons .out-btn{order:8}
.theme-btn .i-moon{display:none}
html.light .theme-btn .i-moon{display:block}
html.light .theme-btn .i-sun{display:none}

/* ── the tabs (a pill container with a tonal active one). Two levels: the pill
     holds the reading pages (Home, Prompt) and the toggles, while the data contours
     live one level below, in a tonal sheet under the "Data" tab ── */
.tabs-wrap{position:relative;max-width:1180px;margin:14px auto 0;padding:0 26px}
.tabs{display:inline-flex;gap:4px;background:var(--panel-lo);border-radius:14px;
      padding:5px}
/* THE WORD OF A TAB IS THE WORD OF A FILTER (the owner, 23.08.2026): one
   typography for everything the portal offers to press - lowercase, 600/11.5,
   the same tracking the kinds of the tape and the weights of the newswire wear.
   WHAT STAYS DIFFERENT IS THE PLATE. A tab takes the reader to another page and
   a filter narrows the page he is on, so the two must not be told apart by the
   words alone: the plate says "this one leaves", and that is the whole of the
   difference now. The sheets keep their own size (.data-menu .tab, .nav-sheet
   .tab): they are opened with a finger, and a small font forced aiming. */
.tab{padding:7px 14px;border-radius:10px;color:var(--dim);text-decoration:none;
     font:600 11.5px/1.2 var(--ui);letter-spacing:.04em;text-transform:lowercase;
     white-space:nowrap;transition:background .15s,color .15s}
.tab:hover{color:var(--text2);background:var(--hover)}
.tab.active{background:var(--panel-hi);color:var(--text)}
/* the sheet of the contours keeps the grammar of the burger sheet: a raised tonal
   surface anchored to the left edge of the "Contours" tab (nav.js sets the left) */
/* There came to be more than a dozen contours, and a single column ran off below
   the fold like a beard. The layout is TWO columns of groups: a .dm-g (a caps label
   plus its own items) is a grid cell, so a group cannot be torn between the columns
   and a new group takes its place by itself, with no numbers to edit here. In the
   burger (.nav-sheet) the same wrappers stay blocks - the sheet there is vertical */
/* Вкладка с листом - это КНОПКА, и у кнопки есть своя рамка от браузера:
   без сброса вокруг неё стоит серое кольцо, которого никто не рисовал. */
.tab-data{border:0;cursor:pointer;background:transparent;
          display:inline-flex;align-items:center;gap:7px}
.tab-data .chev{transition:transform .15s}
.tab-data[aria-expanded="true"] .chev{transform:rotate(180deg)}

.data-menu{--dm-row:42px;                 /* one step of the vertical rhythm */
           position:absolute;z-index:40;width:392px;margin-top:8px;
           background:var(--panel-hi);
           /* the padding at the bottom is larger: at the top the caps label of a
              group tops the air up (its text is pressed to the bottom of its line),
              and with an equal 6px the sheet looked flattened at the bottom - 14px
              level it with the 27px at the top */
           border-radius:16px;padding:6px 6px 14px;box-shadow:var(--shadow-pop);
           /* ОДНА КОЛОНКА: две заводят под три страницы дыру рядом со
              списком. Портал держит там больше дюжины контуров, у нас их
              три - когда станет больше, вернуть columns:2 */
           width:250px;
           transform-origin:top left;animation:navpop .16s ease}
/* a multicol rather than a grid: the columns BALANCE their heights by themselves,
   so a lone group leaves no hole next to a long one. The break-inside is mandatory -
   without it a column tears a group between its caps label and its items.
   There are deliberately NO margins between the groups: the caps label gives the air
   itself (a line of the same height as an item), and both columns stay on ONE grid -
   the items on the left and on the right stand on shared lines and nothing jumps */
.data-menu .dm-g{break-inside:avoid}
.data-menu .tab{display:flex;align-items:center;height:var(--dm-row);
                padding:0 16px;border-radius:11px;
                font:500 14.5px/1.2 var(--ui)}
/* the sheet lies on --panel-hi, so by the shared law of elevation the selected item
   goes one step higher */
.data-menu .tab.active{background:var(--panel-top);color:var(--text)}
/* the caps captions of the classes of the contours (data / analysis) take EXACTLY
   one line of the rhythm with the text pressed to the bottom - a group gets air
   above it and the grid is not knocked off */
.data-menu .cap{display:flex;align-items:flex-end;height:var(--dm-row);
                padding:0 16px 9px;font:600 10.5px/1 var(--ui);
                letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}

/* ПЕРЕЛИСТЫВАЛКА КОНТУРОВ (строит nav.js на страницах листа): капсула в
   грамматике пили, прижатая к правому краю той же строки; листает ПО КРУГУ в
   порядке листа. Только на просторном экране - на узком рядом с пилей ей всё
   равно нет места.
   ПЛАШКИ ЗДЕСЬ НЕТ: плашка говорит "это одно целое", а держать нечего -
   перелистывалка показывает ОДИН контур с двумя стрелками, а не выбор из
   нескольких. Пиля рядом носит плашку ровно по обратной причине. */
.contour-pager{display:none}
@media (min-width:1100px){
  .contour-pager{position:absolute;right:26px;top:50%;transform:translateY(-50%);
                 display:flex;align-items:center}
  .cp-arrow{display:inline-flex;align-items:center;justify-content:center;
            padding:8px 11px;border-radius:10px;color:var(--dim);
            transition:background .15s,color .15s}
  .cp-arrow:hover{color:var(--text2);background:var(--hover)}
  /* ОДНА ТИПОГРАФИКА СО СТРОКОЙ РЯДОМ: своим кеглем перелистывалка читалась бы
     третьим голосом на строке, где уже есть пиля. Группа отличается ТОНОМ -
     то же слово, тише. */
  .cp-cap{padding:0 4px 0 13px;font:600 11.5px var(--ui);
          letter-spacing:.04em;text-transform:lowercase;color:var(--faint)}
  .cp-label{display:inline-flex;align-items:baseline;gap:8px;padding:0 10px;
            font:600 11.5px/1.2 var(--ui);letter-spacing:.04em;
            text-transform:lowercase;color:var(--text);white-space:nowrap}
  /* СТОПКА ИМЁН В ОДНОЙ КЛЕТКЕ: невидимые задают ширину, поэтому зона стрелок
     закреплена самым длинным именем и не прыгает при листании. Счётчик - та же
     стопка с призраком самой широкой формы ("10/10"), иначе левая стрелка
     дёргается между однозначной и двузначной позицией. */
  .cp-name,.cp-count{display:inline-grid;text-align:center}
  .cp-name>span,.cp-count>span{grid-area:1/1;white-space:nowrap}
  .cp-name>.ghost,.cp-count>.ghost{visibility:hidden}
  .cp-count{font:500 11.5px var(--ui);color:var(--text);
            font-variant-numeric:tabular-nums}
}

/* ── the base card ── */
.card{position:relative;background:var(--panel);border-radius:16px;
       padding:22px var(--pad)}

/* ── the segmented switcher (the horizons of an opinion on Home, the timeframes on
     the charts, the topics of News, the filters of the feeds and the page sizes).

     THE LAW OF ELEVATION, shared with the navigation pill (.tabs above): a capsule
     is a tray one step above its own surface, and the selected segment is one step
     above that. The active one is NEVER equal to --bg.

     The capsule used to be nailed to the pair --panel-hi / --bg while the navigation
     was nailed to --panel / --panel-hi, and neither expressed the DIRECTION of the
     elevation. It came out that in the dark theme a selected tab was lighter than
     its track while a selected segment was darker (a hole down to the background of
     the page), and in the light both flipped in different directions. On Tape two
     capsules stand 20px apart one under another and that discord was read
     point-blank: the track of the filter was brighter than the active tab of the
     navigation.
     Now on a bare background the switcher takes exactly the palette of the
     navigation, and inside a card both steps go up. The exceptions are below: the
     capsules on canvases (the charts plus the ETH outlook) and the Mono toggle
     (above - it is the only one that goes BELOW its surface) ── */
.tfswitch{display:inline-flex;gap:2px;background:var(--panel);border-radius:10px;
          padding:3px;box-shadow:var(--lift)}
/* a switch that the script builds is hidden until it exists: display of its own
   beats the attribute, so the attribute is said again here */
.tfswitch[hidden]{display:none}
/* ...AND AN EMPTIED ONE IS NOT EMPTY ON SCREEN (the owner, 27.08.2026: "the
   switch itself is still there, you can see it by the dot in the corner"). A
   pill draws its own plate, so a script that clears the buttons - one profile
   left, one horizon, nothing to choose between - left a grey dot standing where
   a control used to be. Every switch of the portal is covered by ONE line here
   rather than by a `hidden` in each script: a page that forgets the attribute
   is exactly how the dot came back twice. */
.tfswitch:empty{display:none}
/* THE CAPSULE SPEAKS IN LOWER CASE (the owner, 23.08.2026: "small letters
   everywhere"). The regime a switch names is not a title: "combined", "raw",
   "all", "opus 5" are values of one control, and a capital letter in one of
   them turned the row into a list of proper nouns. It is set HERE rather than
   in the labels, because the labels are shared - a profile is "Market" in the
   heading of its own page and a button of a capsule at the same time - and a
   registry rewritten for the capsule would rename it everywhere. */
.tfswitch button{border:0;cursor:pointer;background:transparent;color:var(--dim);
                 font:600 11.5px var(--ui);letter-spacing:.04em;
                 padding:0 12px;height:calc(var(--ctl) - 6px);
                 border-radius:8px;text-transform:lowercase;
                 transition:background .15s,color .15s}
/* ЧУЖОЕ ИМЯ НЕ ПЕРЕПИСЫВАЕТСЯ ДАЖЕ РЕГИСТРОМ. Капсула портала говорит
   строчными, но части сырья названы поставщиком - federalFunds у него именно
   такой, и "federalfunds" на экране это уже наша версия его ответа. */
.tfswitch.asis button{text-transform:none;letter-spacing:0}
.tfswitch button:hover{color:var(--text2)}
.tfswitch button.active{background:var(--panel-hi);color:var(--text)}
/* НЕРЕШЁННЫЕ ЗОВУТ ДЕЙСТВИЕМ, и зовут тем же жёлтым, что метка new в строке.
   Без этого "all · 16 new" стоит цветом --dim, который в тёмной теме почти
   белый, и неактивная кнопка читается как вторая выбранная (владелец,
   02.09.2026). Это не нарушение закона о цвете: жёлтым здесь говорится не
   "хорошо", а "здесь ждут решения". */
/* РЯД НЕ ПРЫГАЕТ ПРИ СМЕНЕ ПОСТАВЩИКА. Состав кнопок меняется вместе с ним
   (opus/sonnet/haiku против sol/terra/luna), и без общей ширины вся строка
   дилов ездит вбок на каждом переключении. */
.tfswitch.fixed button{min-width:78px}
.tfswitch.has-new button[data-v="all"]{color:var(--warn)}
.tfswitch.has-new button[data-v="all"].active{color:var(--warn)}
/* inside a card the surface is already --panel itself, so both steps shift.
   .table-card is named explicitly: it is the only card container without the .card
   class (Streams, "Closed minutes") */
.card .tfswitch{background:var(--panel-hi)}
.card .tfswitch button.active{background:var(--panel-top)}

/* ── the card of a collector (the pages of the contours): a grid of key facts ── */
.col-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px 24px}
@media (max-width:1020px){.col-grid{grid-template-columns:repeat(2,1fr)}}
.cstat{display:flex;flex-direction:column;gap:4px;min-width:0}
.cstat .lb{font:13px var(--ui);color:var(--dim)}
/* ОДНА ГАРНИТУРА НА ВЕСЬ ПРОЕКТ (владелец, 01.09.2026). Моноширинный берётся
   ТОЛЬКО там, где цифры сравнивают глазом в столбце, или где это код - ключ
   поля, адрес, отпечаток. Показание вроде "0 of 2" или "never answered" не
   сравнивают ни с чем, и моно делает из него телеграмму. Ровность цифр даёт
   tabular-nums, а не смена гарнитуры - так набраны часы портала. */
.cstat .v{font:600 15px var(--ui);font-variant-numeric:tabular-nums;
          white-space:nowrap}
.cstat .v.ok{color:var(--text)} .cstat .v.warn{color:var(--warn)}
.cstat .sub{font:11.5px var(--ui);color:var(--faint);
            font-variant-numeric:tabular-nums;
            white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:1000px){.col-grid{gap:14px 16px}}

/* ── the heading of a section (shared by every page): a bold white mark ── */
/* the heading does not share its width with the caption: if they do not fit side by
   side, the caption wraps UNDER it whole (rather than the two squeezing into
   columns) */
/* ONE DISTANCE FROM THE BOTTOM OF A HEAD TO ITS CARD, whatever the head carries
   and however it wrapped (owner, 13.08.2026, revised 14.08.2026). The air is
   measured from the BOTTOM EDGE OF THE HEAD - the title, the caption or the
   control, whichever ends it - and it is nineteen pixels everywhere.
   The first edition subtracted the seven pixels a capsule hangs below the
   baseline of the title, so that the air read as nineteen FROM THE TEXT. That
   holds only while the capsule stands ON THE LINE of the title: the moment it
   wraps onto its own line - every phone, and a narrow desktop with a long
   caption (measured: Streams at 1001px) - those seven pixels are taken out of
   the air under the LAST line of the head, and the card jumps up to twelve.
   Two heads side by side then read as a misprint again, this time on the phone.
   A capsule is a thing, not air: the distance is counted from what the head
   ends with, and one margin serves every layout of it. */
.sec-head{display:flex;align-items:baseline;gap:2px 12px;flex-wrap:wrap;margin:26px 0 19px}
.sec-head:first-child{margin-top:4px}
/* THE LINE OF A TITLE IS ONE HEIGHT ACROSS THE PORTAL - the height of a control
   capsule (27px), whether the head carries one or not. A capsule is taller than
   a line of 18px text, so in the heads that have one it stretched the line and
   pushed the CAPTION three pixels further down than in the heads that do not:
   `Contract` read tight, `Through time` loose, on the same screen (owner,
   14.08.2026). Reserving the height everywhere costs three pixels under a
   plain title and buys one rhythm: title, caption, card - the same in every
   section of every page. */
.sec-head h2{margin:0;font:700 18px var(--ui);line-height:30px;color:var(--head);
             white-space:nowrap}
/* the capsule sits in the MIDDLE of that line and out of the baseline sorting:
   aligned by its own baseline it hangs below the text and stretches the line */
.sec-head .tfswitch,.sec-head .hd-sw{align-self:center}
/* УПРАВЛЕНИЕ ОХВАТА СТОИТ В КОНЦЕ СТРОКИ, а не вплотную к подписи: подпись
   читают слева направо, а переключатель это ДЕЙСТВИЕ над всей секцией - его
   место у правого края, как у кнопки копии. */
.sec-head .hd-sw{margin-left:auto}
.sec-note{font:13.5px var(--ui);color:var(--dim)}
/* ДЕЙСТВИЕ ЖИВЁТ В ЗАГОЛОВКЕ СЕКЦИИ, а не в карточке под ним: копия сырья это
   действие НАД разделом, и кнопка внутри плашки спорила бы с её содержимым.
   Правила перенесены из портала как есть - кнопка одна на весь проект, и
   вторая её форма развела бы два вида одного жеста. */
.sum-actions{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}
.sum-copy{border:0;cursor:pointer;border-radius:8px;padding:0 12px;
          height:var(--ctl);
          background:var(--panel-hi);color:var(--text2);letter-spacing:.03em;
          font:600 11.5px var(--ui);transition:background .15s,color .15s;
          min-width:132px;text-align:center;font-variant-numeric:tabular-nums}
.sum-copy:hover{background:var(--hover);color:var(--text)}
.sum-copy:disabled{opacity:.45;cursor:default}
.sum-copy:disabled:hover{background:var(--panel-hi);color:var(--text2)}
@media (max-width:1000px){
  /* на телефоне действие занимает свою строку целиком: втиснутое в строку
     заголовка, оно ужимает сам заголовок до многоточия */
  .sum-actions{margin-left:0;width:100%;display:grid;
               grid-template-columns:1fr;gap:8px}
  .sum-actions .sum-copy{text-align:center;min-width:0}
}
/* A LINK IN THE QUIET LINE OF A SECTION keeps the line a caption rather than a
   call to action: the colour of the text, an underline quieter than the text.
   Left to the browser it came out in its own violet - a colour of no widget of
   this portal (owner, 13.08.2026). The rule lived on one page and moved here
   the moment a second section wanted the same link. */
.sec-note a{color:var(--text2);text-decoration:underline;
            text-decoration-color:var(--line);text-underline-offset:3px}
.sec-note a:hover{color:var(--text);text-decoration-color:var(--dim)}

/* ── the table card (.vt): the entities go as rows; on narrow screens a row turns
     into a block with a grid of captioned cells (the caption comes from data-l). The
     1020 collapse breakpoint is THE SINGLE table breakpoint of the site (as with the
     Levels matrix and Closed minutes on Streams): the wide tables go into blocks
     BEFORE a horizontal scroll would appear ── */
.tcard{padding:16px 0 8px}
/* показания НАД таблицей в одной карточке: у таблицы отступы дают ячейки, а
   строка показаний своих не имеет и без этого правила легла бы на самый край */
.raw-top{padding:6px var(--pad) 16px}
/* ── ПАНЕЛЬ НАД ТАБЛИЦЕЙ: поиск, счёт и мелкое действие ────────────────────
   Перенесено из портала (кухня новостей), где жило стилем одной страницы.
   Строка сужает набор, а не листает его: набранное слово оставляет в таблице
   только то, что ему отвечает, и счётчик рядом говорит, сколько осталось. */
.tb-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
          padding:0 var(--pad) 12px}
.tb-find{flex:0 1 210px;min-width:120px;border:0;border-radius:9px;
         background:var(--panel-hi);color:var(--text);
         font:400 12.5px var(--ui);padding:0 12px;height:var(--ctl)}
.tb-find::placeholder{color:var(--faint)}
.tb-find:focus{outline:2px solid var(--line2);outline-offset:0}
.tb-tools .sp{flex:1}
.tb-count{font:600 11px var(--ui);color:var(--faint);letter-spacing:.03em;
          font-variant-numeric:tabular-nums}
/* ТРИ ГЛАГОЛА ПЕРЕНОСЯТСЯ ВМЕСТЕ, А НЕ ПО ОДНОМУ. Они судят об одном наборе и
   читаются как один жест; поодиночке они расползались по строкам, и на телефоне
   "take all" стоял в конце одной строки, а "take none" начинал следующую. */
.tb-acts{display:inline-flex;gap:8px;flex:none}
/* ── СПИСОК ИСТОЧНИКОВ: РЕШЕНИЕ, А НЕ ПЕРЕЧЕНЬ ────────────────────────────
   Сорок имён по алфавиту - это список, который никто не читает; по ОБЪЁМУ он
   становится списком решений: первые пять несут две трети ленты, а хвост - по
   истории на брата. Доля стоит рядом со счётом по той же причине: "779" не
   значит ничего, пока не станет "31% всего, что мы показываем".
   ПОЛОСКА - ТА КОЛОНКА, КОТОРУЮ ГЛАЗ ЧИТАЕТ НА САМОМ ДЕЛЕ: проценты в столбце
   все на одно лицо, а полоска говорит "это треть твоей ленты", даже если её не
   читать. Висит под своим числом, у правого края колонки. */
.np-bar{display:block;height:3px;border-radius:2px;background:var(--text2);
        margin:4px 0 0 auto;min-width:1px}
/* ВЫКЛЮЧЕННЫЙ ИСТОЧНИК ОСТАЁТСЯ ЧИТАЕМЫМ - это решение, а не удаление, и его
   пересматривают так же часто, как принимают */
.vt tr.off .tick-name{color:var(--faint)}
.vt tr.off td{opacity:.55}
/* ГАЛОЧКА ЖИВЁТ В КЛЕТКЕ ИМЕНИ, а не в своей колонке: таблица отдаёт ПЕРВОЙ
   клетке левый край и читаемый шрифт, и столбец галочек забрал бы это себе,
   отодвинув каждое имя вправо. В подписи он к тому же делает мишенью само имя,
   что подписи и нужно, и не стоит ни строчки скрипта. */
.vt td.np-cell{display:flex;align-items:center;gap:9px}
/* НЕРЕШЁННЫЙ ИСТОЧНИК ЗОВЁТ РЕДАКТОРА: строка тихая, как у выключенного (она
   делает то же самое - ничего), а метка держит полную силу - это единственное
   в ней, что требует действия */
.np-badge{flex:none;padding:2px 6px;border-radius:5px;
          font:600 9px/1 var(--ui);letter-spacing:.07em;text-transform:uppercase;
          background:var(--hover);color:var(--faint)}
.np-badge.new{color:var(--warn);
              background:color-mix(in srgb,var(--warn) 14%,transparent)}
.vt tr.off .np-badge.new{opacity:1}
/* мелкое действие панели: тот же жест, что у кнопки копии, только без ширины */
.tb-bulk{border:0;cursor:pointer;background:var(--panel-hi);color:var(--dim);
         letter-spacing:.03em;font:600 11px var(--ui);padding:0 12px;
         height:var(--ctl);
         border-radius:9px;transition:background .15s,color .15s}
.tb-bulk:hover{background:var(--hover);color:var(--text)}
.tb-bulk[disabled]{opacity:.35;cursor:default}

/* фильтр не совпал ни с чем: одна строка там, где были бы строки */
td.tb-none{text-align:center;color:var(--faint);font:400 12.5px var(--ui);
           padding:22px 12px}
.twrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
table.vt{width:100%;min-width:760px;border-collapse:collapse;font-variant-numeric:tabular-nums}
/* the head of the columns: small caps with letter-spacing - noticeable but never
   arguing with the data */
.vt th{font:600 11px var(--ui);color:var(--text2);text-transform:uppercase;
       letter-spacing:.07em;text-align:right;padding:6px 12px;white-space:nowrap}
.vt th:first-child{text-align:left;padding-left:var(--pad)}
.vt td{font:12.5px var(--ui);text-align:right;padding:9px 12px;white-space:nowrap;
       vertical-align:top;border-top:1px solid var(--line2)}
/* the first column is the label of a row: it has a typeface of its own (ui rather
   than mono) but THE SAME SIZE as the data (12.5): a discord of 13.5 against 12.5
   read as two registers inside one table. The headings of the tables are untouched
   by this rule */
.vt td:first-child{font:500 12.5px var(--ui);color:var(--text);text-align:left;
                   padding-left:var(--pad)}
.vt td:last-child,.vt th:last-child{padding-right:var(--pad)}
.vt .prod{display:block;font:11.5px var(--ui);color:var(--faint);margin-top:2px}
.vt .d{display:block;font-size:11px;color:var(--faint);margin-top:2px}
@media (max-width:1020px){
  .twrap{overflow:visible}
  table.vt{min-width:0;display:block}
  .vt thead{display:none}
  .vt tbody{display:block}
  .vt tr{display:grid;grid-template-columns:repeat(3,1fr);gap:12px 14px;
         padding:14px 16px;border-top:1px solid var(--line2)}
  .vt tr:first-child{border-top:none}
  /* the data is noticeably larger on a phone: there is one screen, and small type
     is a barrier */
  .vt td{display:block;text-align:left;padding:0;border:0;white-space:normal;
         font-size:15px}
  .vt .d,.vt .prod{font-size:12.5px}
  .vt td::before{content:attr(data-l);display:block;font:600 11px var(--ui);
                 text-transform:uppercase;letter-spacing:.06em;
                 color:var(--faint);margin-bottom:3px}
  .vt td:first-child{grid-column:1/-1;padding:0;font-size:15.5px}
  .vt td:first-child::before{content:none}
}

/* ── Health: one zone for the problems of a page - the sources go as status
     columns (a small-caps name rhyming with the heads of the tables plus a quiet
     line of the state), and the error log is always the last block, across the full
     width behind a hairline; the norm is silence ── */
.card.health-card{padding:20px 0 14px;display:flex;flex-direction:column}
.health-card.loading{min-height:148px}
/* the blocks go as a plain list across the full width (not as columns) with a
   hairline between them; the error log is the same kind of block, uniformly */
.hblock{padding:2px var(--pad)}
.hblock + .hblock{border-top:1px solid var(--line2);margin-top:12px;padding-top:14px}
.hblock .gv{font:600 11px var(--ui);color:var(--text2);text-transform:uppercase;
            letter-spacing:.07em;margin-bottom:7px}
/* the health lines share ONE font with the whole zone: the ordinary Ubuntu (--ui)
   rather than mono; the only difference between the lines is the COLOUR (a problem
   label in --warn, the ok/warn/bad traffic light) rather than the typeface -
   otherwise the yellow labels "jump" relative to the quiet lines. tabular-nums keeps
   the columns of times and numbers even */
/* ── THE TICK: one checkbox for the whole kitchen ────────────────────────
   A control drawn by CSS alone - no image, no font, nothing to load - and it
   scales with its box. The mark is two borders of an empty box turned 45
   degrees, so it reads the same in both themes without a second rule.
   It lived inside the News page while it had one user (26.08.2026); the Notify
   page needed the same tick, and a control copied into a second page is a
   control that drifts on the first day somebody adjusts one of them. */
.tick{appearance:none;-webkit-appearance:none;position:relative;flex:none;
       width:16px;height:16px;margin:0;cursor:pointer;
       border:1.5px solid var(--line2);border-radius:5px;background:transparent;
       transition:background .12s ease,border-color .12s ease}
.tick:hover{border-color:var(--dim)}
.tick:checked{background:var(--text);border-color:var(--text)}
.tick:checked::after{content:"";position:absolute;left:4.4px;top:1.4px;
       width:3.6px;height:8px;border:solid var(--bg);
       border-width:0 1.7px 1.7px 0;transform:rotate(45deg)}
.tick:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* THE BOX AND ITS WORD ARE ONE TARGET: the label is what makes the name
   clickable, and the name is what a reader aims at - so the pair is one
   control here rather than a box in the stylesheet and a word on each page. */
/* THE PAIR BREATHES, AND ONLY JUST (the owner, 31.08.2026: "is it worth adding
   a little air between them?"). The name of a box is BOLD, and a bold word
   pulls at the box harder than an ordinary one - ten pixels beside a sixteen
   pixel box read as crowding. Twelve against the twenty-two between pairs is a
   ratio of 1.8, so the word still plainly belongs to its own box; at fourteen
   the inner gap starts competing with the outer one and a row of pairs reads as
   a row of loose words. */
.tick-row{display:inline-flex;align-items:center;gap:12px;cursor:pointer}
.tick-name{font:600 12.5px var(--ui);color:var(--text)}
.tick-row:hover .tick-name{color:var(--head)}

/* ── THE DIALS OF A KITCHEN ──────────────────────────────────────────────
   A kitchen card is rows of dials, and a row is groups of "a word and the
   thing the word names". The word stands NEXT TO its control, never in a
   column of its own: a column pushes every control to the same inner edge and
   the card reads as a form somebody centred rather than as a sentence about
   what the contour does.
   It grew on the News page and stayed there while it had one reader
   (26.08.2026); the Notify page needed the same rows, so the grammar moved
   here under a name that says what it is. The `.sc-` of mcpadmin/almadmin is a
   DIFFERENT thing (a warning card) - one of the reasons this could not simply
   keep the old prefix. */
/* THE TWO-CLASS FORM IS LOAD-BEARING (30.08.2026, the owner: "why can you not
   make the paddings inside the main card the same on a phone"). The phone rule
   `.card{padding:18px 16px}` is written far below every one of these and has
   the same weight, so a single class lost to it there and only there: the card
   took sixteen pixels of its own AND its rows took theirs, and the content of
   one card stood eight pixels further in than the content of the next. */
.card.dial-card{padding:0}          /* the rows carry the padding, not the card */
.dial-read{padding:22px var(--pad) 20px}          /* the readings above the dials */
.dials{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
       padding:15px var(--pad);border-top:1px solid var(--line2)}
/* ВТОРОЙ ЭТАЖ ТОГО ЖЕ РЯДА, а не второй ряд. Длинная группа переносится вниз,
   когда не помещается рядом, но отбивка между этажами не ставится: черта
   говорит "другая тема", а тема здесь одна. */
.dials.floor{border-top:0;padding-top:0}
/* a card whose first row IS the row: it needs the air of a card, not of a foot */
.dial-card > .dials:first-child{border-top:0;padding:20px var(--pad)}
.dials .d{font:12.5px var(--ui);color:var(--faint)}
/* THE WORDS THAT NAME THE ROWS STAND IN A COLUMN, so the controls they name
   start on one line. Measured (26.08.2026): `news` is 30px and `released` 49,
   so a row of ticks began twenty pixels left of the row above it and the card
   read as a ragged list rather than as a set of dials.
   ONLY THE FIRST WORD OF A ROW: the words INSIDE a row ("h back", "d ahead",
   "h of opinions") name what stands before them and must stay tight to it. */
.dial-card .dials > .dial > .d:first-child{min-width:70px}
.dials .sp{flex:1}
/* A LABEL AND THE DIAL IT NAMES ARE ONE BOX: the row may wrap, but never
   between a word and the thing it is a word for. `.head` is the label that
   names SEVERAL dials at once and stands over them rather than beside the
   first of them. */
.dial{display:inline-flex;align-items:center;gap:12px;flex-wrap:wrap}
.dial-div{width:1px;align-self:stretch;background:var(--line2);margin:0 8px}
/* THE SPINNERS ARE OFF in both engines: a number field of the portal is typed
   into, never nudged */
/* ВСЕ КОНТРОЛЫ ОДНОГО РЯДА - ОДНОЙ ВЫСОТЫ (владелец, 02.09.2026). Высоту
   задаёт капсула переключателя (29px), потому что их в ряду больше всего;
   поле и мелкая кнопка равняются на неё, а не каждый на свои отступы -
   иначе в одной строке стоят три разных роста, и это видно. */
.dial-n{width:58px;border:0;border-radius:9px;background:var(--panel-hi);
        color:var(--text);font:600 12.5px var(--ui);padding:0 10px;
        height:var(--ctl);
        font-variant-numeric:tabular-nums;
        text-align:center;appearance:textfield;-moz-appearance:textfield}
.dial-n::-webkit-outer-spin-button,
.dial-n::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.dial-n:focus{outline:2px solid var(--line2);outline-offset:0}

.gap-row{display:flex;gap:16px;font:12.5px var(--ui);color:var(--text2);
         font-variant-numeric:tabular-nums;padding:3px 0}
/* THE TRAFFIC LIGHT STANDS ON THE VALUE, NEVER ON THE NAME (25.08.2026). There
   used to be a fourth class here, .n, doing the same amber as .warn - and the
   pages hung it on a name unconditionally, so the colour meant "this row has a
   name" in one block and "something is wrong" in the next. Two names for one
   colour and one colour for two jobs: the page could not be learned. One class
   per state now, hung by UI.hrow on the value alone. */
/* ХОРОШЕЕ НЕ ПИШЕТСЯ ЦВЕТОМ (закон проекта, владелец 02.09.2026). Норма это
   норма: она набирается тем же цветом, что и всё остальное на странице.
   Цветом говорят только о беде - жёлтым об опоздании, красным о поломке, - и
   тогда цвет на экране означает ровно одно: посмотри сюда. Зелёный "live" в
   каждой строке съедал это значение, потому что цвет был везде. */
.gap-row .ok{color:var(--text)} .gap-row .warn{color:var(--warn)}
.gap-row .bad{color:var(--down)}
/* recent errors use the same 12.5 as the rest of the health data: a size of their
   own made the errors a separate register inside one zone */
.err-line{font:12.5px var(--ui);color:var(--dim);padding:3px 0;overflow-wrap:anywhere;
          font-variant-numeric:tabular-nums}
.err-line .et{color:var(--faint);margin-right:10px;font-variant-numeric:tabular-nums}

/* ── AN EMPTY STATE THAT STANDS IN A READING COLUMN ───────────────────────
   A plate that has nothing in it centres its message, and that is right: the
   message IS the whole plate. A feed has no plate - it is a column of text with
   a left edge the eye is already on - and a notice in the middle of eleven
   hundred pixels reads as belonging to the page rather than to the feed (the
   owner, 20.08.2026).
   So in a column it stands WHERE THE FIRST ENTRY WOULD STAND, and it is set as
   an entry: the line that says what happened takes the size of a headline, the
   line that explains takes the size of the body. One modifier, two feeds (News
   and Tape), one behaviour. */
/* ── AN EMPTY STATE THAT STANDS IN A READING COLUMN ───────────────────────
   A plate that has nothing in it centres its message, and that is right: the
   message IS the whole plate. A feed has no plate - it is a column of text with
   a left edge the eye is already on - and a notice in the middle of eleven
   hundred pixels reads as belonging to the page rather than to the feed (the
   owner, 20.08.2026).
   So in a column it stands WHERE THE FIRST ENTRY WOULD STAND, and it is set as
   an entry: the line that says what happened takes the size of a headline, the
   line that explains takes the size of the body. One modifier, two feeds (News
   and Tape), one behaviour. */
.nquiet{padding:40px 24px;text-align:center}
.nquiet .t{font:700 16px var(--ui);color:var(--text);letter-spacing:.01em}
.nquiet .n{margin-top:6px;font:12.5px var(--ui);color:var(--faint)}
/* the links in a quiet scene use the tokens of the site rather than the default
   blue and purple */
.nquiet a{color:var(--text2);text-decoration:underline;text-underline-offset:2px}
.nquiet a:hover{color:var(--text)}
.nquiet.column{padding:22px 0 0;text-align:left}
.nquiet.column .t{font:700 18px/1.4 var(--ui)}
.nquiet.column .n{margin-top:6px;font:400 16px/1.55 var(--ui);color:var(--text2)}
/* ── the centring of an empty state inside a card (shared across the whole
   project): a card holding a .nquiet becomes a flex column; the ancestor container
   carrying the .nquiet is stretched over all the free height and centred vertically
   - the headers and the counters (feed-head, sum-top ...) stay at the top, since
   they have no .nquiet. The gate by :has(.nquiet) leaves a filled state (rows or a
   grid) untouched. It covers .table-card (Closed minutes) too - the only plate that
   is not a .card ── */
.card:has(.nquiet){display:flex;flex-direction:column}
.card:has(> .nquiet){justify-content:center}
.card:has(.nquiet) > *:has(.nquiet){
  flex:1;display:flex;flex-direction:column;justify-content:center}
@media (max-width:1000px){.nquiet{padding:32px 16px}}

/* ── A PLATE OF TEXT THAT SHIPS WITH THE CODE ─────────────────────────────
   A contract the model is given, shown byte for byte with a button to take it
   away. Written for the AI opinions page and needed a second time the day the
   News contour got a rubric of its own (20.08.2026), so it moved here: the
   heading row, the body and the typography of the text are the same thing on
   both pages, and a second copy would have drifted the first time either was
   touched. What stays with a page is what is ITS own - the collapse toggle of
   the four heavy plates on AI opinions, the widths of its buttons. */
.card.pr-card{padding:0}   /* no overflow:hidden - it would clip a sheet opened over it */
.pr-top{position:relative;display:flex;align-items:baseline;gap:10px;
        padding:18px 24px 4px;flex-wrap:wrap}
.pr-top .t{font:600 14px var(--ui);color:var(--text)}
/* the version and the date are an equal part of the heading */
.pr-top .u{font:inherit;color:inherit;font-variant-numeric:tabular-nums}
.pr-top .sp{flex:1}
.pr-body{padding:6px 24px 18px}
.pr-text{font:14px/1.65 var(--ui);color:var(--text);white-space:pre-wrap;
         overflow-wrap:anywhere}
.pr-text.quiet{color:var(--faint)}
/* A HEAVY PLATE COLLAPSES to its own heading: a sheet of contract is worth
   opening, not worth scrolling past. The glyph is mono and a fixed width so the
   heading does not shift between + and −, and the heading itself is the second
   click target. */
.clp-tg{background:none;border:0;padding:0;cursor:pointer;align-self:center;
        font:600 14px/1 var(--mono);width:12px;text-align:center;
        color:var(--text2);transition:color .15s}
.clp-tg:hover{color:var(--text)}
.pr-top .t[data-clp]{cursor:pointer}
.card.clp .pr-body{display:none}
.card.clp .pr-top{padding-bottom:16px}
.card.clp.loading{min-height:0}

.sum-copy{border:0;cursor:pointer;border-radius:8px;padding:6px 12px;
          background:var(--panel-hi);color:var(--text2);letter-spacing:.03em;
          font:600 11.5px var(--ui);transition:background .15s,color .15s;
          min-width:132px;text-align:center;font-variant-numeric:tabular-nums}
.sum-copy:hover{background:var(--hover);color:var(--text)}
.sum-copy:disabled{opacity:.45;cursor:default}
.sum-copy:disabled:hover{background:var(--panel-hi);color:var(--text2)}
/* a link in the form of an action button (latest / open in snapshots); the [hidden]
   must win over our display (the UA rule is weaker) */
a.sum-copy{text-decoration:none;display:inline-block}
/* ── the loading skeleton: until the first answer of the backend the content is
     hidden (the geometry is preserved so nothing jumps) while the plate itself
     pulses quietly - a slow "breath in, breath out" instead of a shimmer. The JS
     removes the `loading` class after the first successful render of the data. ── */
.loading{position:relative;   /* it works on non-.card containers too */
  animation:skel-pulse 2.6s ease-in-out infinite}
.loading > *{visibility:hidden}
@keyframes skel-pulse{0%,100%{opacity:1}50%{opacity:.55}}
@media (prefers-reduced-motion:reduce){
  .loading{animation:none;opacity:.75}
}

/* ── the footer: a quiet typographic signature, shared by every page - a hairline,
     the mark plus the version pill, and the motto on the line below ── */
/* ГЕОМЕТРИЯ СТРАНИЦЫ ОДНА НА ВСЕХ: она стояла копией в <style> семи страниц,
   и любая правка требовала семи одинаковых. Страница, которой нужно иное,
   переопределяет это своим правилом - и тогда исключение видно как исключение. */
main{max-width:1180px;margin:0 auto;padding:22px 26px 88px}
@media (max-width:1000px){main{padding:18px 10px 56px}}
footer{max-width:1180px;margin:0 auto;padding:22px 26px 44px}
.f-inner{border-top:1px solid var(--line2);padding-top:24px;
         display:flex;flex-direction:column;align-items:center;gap:9px}
.f-brand{display:inline-flex;align-items:center;gap:10px}
/* в подвале тот же приём, что в шапке: 15 в ширину при коробке в 16 - строка с
   версией стоит на прежней высоте */
.f-logo{flex:none;width:21px;height:16px;color:var(--text2)}
/* the version is a quiet mono tag rather than a statement - a detail for those who
   look for it */
.f-ver{font:11px/1 var(--ui);color:var(--dim);background:var(--panel);
       font-variant-numeric:tabular-nums;
       border-radius:999px;padding:4px 10px}
.f-ver:empty{display:none}
/* the caption under the "logo plus version" line: the motto as a quiet line (the
   name of the brand is carried by the ring logo next to the version and does not
   appear in the text of the motto) */
.f-note{font:11.5px var(--ui);color:var(--faint);text-align:center}
/* the notice inside the signature: the same ink as the sentence it sits in,
   marked by a rule rather than by a colour - blue here would be a control in a
   line that controls nothing */
.f-note a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.f-note a:hover{color:var(--text2)}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;
         clip:rect(0 0 0 0);white-space:nowrap}
@media (max-width:1000px){
  .tabs-wrap{position:relative;display:flex;align-items:center;
             justify-content:space-between}
  .tabs{display:none}
  /* An open desktop sheet of the contours MUST disappear on a narrow screen: it
     lives in .tabs-wrap rather than in .tabs, so it survived the hiding of the pill -
     narrow the window with "Contours ▾" open and you got two menus on top of each
     other */
  .data-menu{display:none}
}
@media (max-width:1000px){
  /* the margins at the edges of the screen are narrower (12px): more room for the
     content */
  .topbar{padding:20px 12px 0}
  .tabs-wrap{padding:0 12px;margin-top:12px}
  /* ...AND THE CONTENT TAKES THE SAME TWELVE (25.08.2026, the owner: "the
     paddings on the phone came from somewhere, bring them back to the logo and
     the tabs"). The rule above promises "more room for the content" and handed
     it to the bar, the tabs and the foot - to everything except the content.
     The reason it was missed: `main` is not declared here at all, it is written
     out page by page (`main{max-width:1180px;margin:0 auto;padding:22px 26px
     88px}` in each of twenty-odd files), so a phone left the heading and the
     cards inset fourteen pixels deeper than the ring above them. The descendant
     selector is what outranks those page rules - theme.css is linked first, and
     at equal specificity the page would win. `body main` rather than
     `body > main`: on the pages that carry the curtain of the first load the
     content sits one level deeper (body > .page-clip > main), and the child
     selector quietly missed exactly them. */
  body main{padding-left:12px;padding-right:12px}   /* in tune with the margins
                                                           of the container */
  :root{--pad:16px}
  .card{padding:18px var(--pad)}   /* denser on a phone - less empty scrolling */
  /* the cards with an INTERNAL grammar of margins (the rows and the blocks carry
     their own 16px on the sides: .vt tr, .hblock, .run) get a ZERO horizontal
     padding on mobile, otherwise the margin doubles (16+16=32 - the "crooked
     margins"). The rule stands AFTER .card in order to override its mobile
     shortcut */
  .tcard{padding:16px 0 8px}
  .health-card{padding:20px 0 14px}
  /* ...and the card of a CONTRACT is the fourth of exactly the same case, missed
     when the list was written (24.08.2026, the owner: "the contract cards are
     wrong everywhere - News, AI opinions, check them all"). `.pr-card{padding:0}`
     stands ABOVE the mobile shortcut of .card and at the same specificity, so on
     a phone the shortcut won it back and the two paddings stacked: measured 40px
     of margin before the plus of a contract heading at 390. Both pages that
     carry these cards were showing it. */
  .pr-card{padding:0}
  /* ...and the card of DIALS is the fifth{padding:0}` lived in the
     page it was linked AFTER theme.css and won on its own; standing here it is
     above the mobile shortcut at equal specificity, so the shortcut won it
     back and the two paddings stacked - measured 44px before the word
     `telegram` against the 28 of a Health block in the same column (the owner:
     "the paddings do not line up anywhere"). */
  .dial-card{padding:0}
  /* ── THE DIALS STAND IN A COLUMN HERE ────────────────────────────────
     A row of groups is a row while there is a row to be had; on a phone there
     is not, and wrapping it left the groups at ragged starts with a hairline
     between two of them that no longer parted anything. One group to a line,
     all flush left - and the hairline and the spring go with the row they
     belonged to: a vertical rule between two stacked things is not a rule, and
     a spring in a column pushes nothing.
     The card is denser too: .dial-card{padding:0} keeps the shortcut of .card
     from reaching it, so the rows take the canon's number themselves. */
  .dial-read{padding:18px 16px 16px}
  .dials{padding:14px 16px;flex-direction:column;align-items:flex-start;gap:14px}
  .dial-card > .dials:first-child{padding:18px 16px}
  .dial-div,.dials .sp{display:none}
  .dial.head{flex-direction:column;align-items:flex-start;gap:12px}
  /* and its rows take the 16 of the phone, the same step .sum-top took above */
  .pr-top{padding:18px 16px 4px}
  .pr-body{padding:6px 16px 18px}
  .card.clp .pr-top{padding-bottom:16px}
  footer{padding:20px 12px 36px}
  /* the timeframe switcher is more compact: it fits one line with the heading of
     the card (the source on Order flow, the selector on Home) - with no second row of
     buttons above the chart; with five timeframes (...15m...) it is a couple of px
     narrower still */
  .tfswitch button{padding:4px 7px;font-size:11px}
  /* the capsule is shorter here, and the line of a title is its height */
  .sec-head h2{line-height:27px}
}
/* ── ONE RHYTHM INSIDE EVERY HEAD OF THE PORTAL ─────────────────────────────
   A head is a title, a caption under it and, on some sections, a control. The
   air between its lines is ONE number (the row gap above), and the air under it
   is one number (.sec-head), whatever the head carries.
   Two editions got this wrong by treating the control as a line of its own.
   Giving heads with a control a bigger row gap (10px against 2px) pushed their
   CAPTION away from the title - side by side, `Contract` read tight and
   `Through time` loose, and that is the same misprint one line up (owner,
   14.08.2026). Subtracting the height of the control from the margin under the
   head only moved the problem to the phone, where the control ends the head.
   THE CONTROL IS NOT A LINE, IT IS THE RIGHT SIDE OF THE TITLE. Where the whole
   head fits one line it already stood there; where it does not, the CAPTION is
   what goes down - it is the long part - and the control stays up beside the
   title. So every head of the portal, on any width, reads the same way: title,
   caption under it, card under that. */
@media (max-width:1200px){
  .sec-head .sec-note{flex-basis:100%;order:2}
  .sec-head .tfswitch,.sec-head .hd-sw{order:1}
}
@keyframes navpop{from{opacity:0;transform:scale(.97) translateY(-4px)}}
@media (prefers-reduced-motion:reduce){
  .tab{transition:none}
}
/* ...and the tab that leads to it disappears from the pill of the section */

/* ── the quiet sign-out icon (the closed services: on app nav.js adds it by the
     nav=app cookie, the admin has markup of its own): the grammar of theme-btn ── */
.out-btn{width:44px;height:44px;border:0;cursor:pointer;border-radius:14px;
         background:transparent;color:var(--dim);
         display:inline-flex;align-items:center;justify-content:center;
         transition:background .15s,color .15s}
.out-btn:hover{background:var(--hover);color:var(--text2)}
/* The order of the corner of a SERVICE page (the admin of the users): there the
   buttons hang straight in the topbar - the theme, then the sign-out at the
   outermost right (the DOM order differs: nav.js hangs the theme while the
   sign-out lives in the markup, and a flex order aligns them).
   The child combinator matters: inside .nav-icons the row has an order of its
   own, and a plain `.topbar .theme-btn` (equal specificity, later in the file)
   quietly overruled it - the theme kept jumping past the name */
.topbar > .theme-btn{order:7}
.topbar > .out-btn{order:8}

/* ── the curtain of the first load (.veil, the early script of the pages): the
     content does not flash through in pieces - it appears whole once every visible
     plate has dropped its skeleton (nav.js watches it; there is a timeout as
     insurance - with a dead contour we show the skeletons).
     THE CURTAIN COVERS THE CONTENT, NOT THE FRAME (the owner, 10.08.2026). It used
     to hold the WHOLE body, so the frame of the portal - the topbar, the pill and
     the menu of the sections - waited for the data of a page it does not depend on
     and flashed in half a second later. The frame is known before any request and
     STANDS STILL, so it is drawn at once.
     THE FOOTER GOES WITH THE CONTENT (the owner, the same day): it is known too,
     but it does not stand still - it rests on the bottom of main, and until the
     plates have their height it sits wherever the short page leaves it. Drawn at
     once, it would show up under the topbar and then travel down the screen.
     The <html> holds the background: a body at zero opacity must not reveal a white
     bottom. */
html{background:var(--bg)}
main,footer{transition:opacity .18s ease}
html.veil main,html.veil footer{opacity:0;transition:none}

/* ── ON A PHONE A TABLE STOPS BEING A TABLE ────────────────────────────────
   Three columns in three hundred points give a middle column six lines tall and
   two words wide - the reader spells it out instead of reading it. So below this
   width every row becomes a small block, one cell under another. The header goes
   with the columns: it named them, and there are no columns left to name. */
@media (max-width:760px){
  .doc table{margin-bottom:22px}
  .doc thead{display:none}
  .doc tbody,.doc tr,.doc td{display:block;width:auto}
  .doc tr{border-bottom:1px solid var(--line2);padding:13px 0}
  .doc tr:first-child{padding-top:0}
  .doc td{border:0;padding:0}
  .doc td:first-child{margin-bottom:3px}
}
